@secondlayer/cli 2.1.0 → 3.0.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 (3) hide show
  1. package/dist/cli.js +1213 -1354
  2. package/dist/cli.js.map +23 -18
  3. package/package.json +7 -7
package/dist/cli.js CHANGED
@@ -2140,14 +2140,109 @@ var require_commander = __commonJS((exports) => {
2140
2140
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2141
2141
  });
2142
2142
 
2143
+ // src/lib/session.ts
2144
+ import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
2145
+ import { homedir } from "node:os";
2146
+ import { dirname, join } from "node:path";
2147
+ import { z } from "zod/v4";
2148
+ async function readSession() {
2149
+ try {
2150
+ const raw = await readFile(SESSION_PATH, "utf8");
2151
+ return SessionSchema.parse(JSON.parse(raw));
2152
+ } catch (err) {
2153
+ if (err?.code === "ENOENT")
2154
+ return null;
2155
+ return null;
2156
+ }
2157
+ }
2158
+ async function writeSession(session) {
2159
+ await mkdir(dirname(SESSION_PATH), { recursive: true });
2160
+ await writeFile(SESSION_PATH, JSON.stringify(session, null, 2) + `
2161
+ `, "utf8");
2162
+ await chmod(SESSION_PATH, 384);
2163
+ }
2164
+ async function clearSession() {
2165
+ await rm(SESSION_PATH, { force: true });
2166
+ }
2167
+ var SessionSchema, SESSION_DIR, SESSION_PATH;
2168
+ var init_session = __esm(() => {
2169
+ SessionSchema = z.object({
2170
+ token: z.string().min(1),
2171
+ email: z.string().email(),
2172
+ accountId: z.string().uuid(),
2173
+ expiresAt: z.string()
2174
+ });
2175
+ SESSION_DIR = join(homedir(), ".secondlayer");
2176
+ SESSION_PATH = join(SESSION_DIR, "session.json");
2177
+ });
2178
+
2179
+ // src/lib/http.ts
2180
+ async function request(url, opts) {
2181
+ const headers = {
2182
+ "content-type": "application/json",
2183
+ ...opts.headers ?? {}
2184
+ };
2185
+ if (opts.bearer)
2186
+ headers.authorization = `Bearer ${opts.bearer}`;
2187
+ const res = await fetch(url, {
2188
+ method: opts.method ?? "GET",
2189
+ headers,
2190
+ body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined
2191
+ });
2192
+ if (!res.ok) {
2193
+ let body = {};
2194
+ try {
2195
+ body = await res.json();
2196
+ } catch {
2197
+ body = { error: await res.text().catch(() => "") };
2198
+ }
2199
+ const code = body.code ?? (res.status === 401 ? "SESSION_EXPIRED" : res.status === 404 ? "NOT_FOUND" : `HTTP_${res.status}`);
2200
+ const message = body.message ?? body.error ?? `HTTP ${res.status}`;
2201
+ throw new CliHttpError(res.status, code, body, message);
2202
+ }
2203
+ if (res.status === 204)
2204
+ return;
2205
+ return await res.json();
2206
+ }
2207
+ async function httpPlatform(path, opts = {}) {
2208
+ const session = await readSession();
2209
+ if (!session) {
2210
+ throw new CliHttpError(401, "SESSION_EXPIRED", { error: "Not logged in" }, "Not logged in — run `sl login`");
2211
+ }
2212
+ return request(`${PLATFORM_API_URL}${path}`, {
2213
+ ...opts,
2214
+ bearer: session.token
2215
+ });
2216
+ }
2217
+ async function httpPlatformAnon(path, opts = {}) {
2218
+ return request(`${PLATFORM_API_URL}${path}`, opts);
2219
+ }
2220
+ var CliHttpError, PLATFORM_API_URL;
2221
+ var init_http = __esm(() => {
2222
+ init_session();
2223
+ CliHttpError = class CliHttpError extends Error {
2224
+ status;
2225
+ code;
2226
+ body;
2227
+ name = "CliHttpError";
2228
+ constructor(status, code, body, message) {
2229
+ super(message);
2230
+ this.status = status;
2231
+ this.code = code;
2232
+ this.body = body;
2233
+ }
2234
+ };
2235
+ PLATFORM_API_URL = process.env.SL_PLATFORM_API_URL ?? "https://api.secondlayer.tools";
2236
+ });
2237
+
2143
2238
  // src/lib/fs.ts
2144
- import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
2239
+ import { mkdir as mkdir2, readFile as readFile2, stat, unlink, writeFile as writeFile2 } from "node:fs/promises";
2145
2240
  async function readJsonFile(path) {
2146
- const text = await readFile(path, "utf-8");
2241
+ const text = await readFile2(path, "utf-8");
2147
2242
  return JSON.parse(text);
2148
2243
  }
2149
2244
  async function writeTextFile(path, content) {
2150
- await writeFile(path, content, "utf-8");
2245
+ await writeFile2(path, content, "utf-8");
2151
2246
  }
2152
2247
  async function fileExists(path) {
2153
2248
  try {
@@ -2158,7 +2253,7 @@ async function fileExists(path) {
2158
2253
  }
2159
2254
  }
2160
2255
  async function ensureDir(path) {
2161
- await mkdir(path, { recursive: true });
2256
+ await mkdir2(path, { recursive: true });
2162
2257
  }
2163
2258
  async function removeFile(path) {
2164
2259
  await unlink(path);
@@ -2171,7 +2266,6 @@ __export(exports_config, {
2171
2266
  setConfigValue: () => setConfigValue,
2172
2267
  saveConfig: () => saveConfig,
2173
2268
  resolvePath: () => resolvePath,
2174
- resolveApiUrl: () => resolveApiUrl,
2175
2269
  resetConfig: () => resetConfig,
2176
2270
  requireLocalNetwork: () => requireLocalNetwork,
2177
2271
  loadConfig: () => loadConfig,
@@ -2185,20 +2279,15 @@ __export(exports_config, {
2185
2279
  NetworkSchema: () => NetworkSchema,
2186
2280
  ConfigSchema: () => ConfigSchema
2187
2281
  });
2188
- import { homedir } from "node:os";
2189
- import { join } from "node:path";
2190
- import { z } from "zod/v4";
2191
- function resolveApiUrl(config) {
2192
- if (config.apiUrl)
2193
- return config.apiUrl;
2194
- return API_URLS[config.network] || API_URLS.local;
2195
- }
2282
+ import { homedir as homedir2 } from "node:os";
2283
+ import { join as join2 } from "node:path";
2284
+ import { z as z2 } from "zod/v4";
2196
2285
  async function ensureConfigDir() {
2197
2286
  await ensureDir(CONFIG_DIR);
2198
2287
  }
2199
2288
  function resolvePath(path) {
2200
2289
  if (path.startsWith("~/")) {
2201
- return join(homedir(), path.slice(2));
2290
+ return join2(homedir2(), path.slice(2));
2202
2291
  }
2203
2292
  return path;
2204
2293
  }
@@ -2214,21 +2303,13 @@ function migrateConfig(raw) {
2214
2303
  const migrated = { ...DEFAULT_CONFIG };
2215
2304
  if (typeof old.network === "string" && ["local", "testnet", "mainnet"].includes(old.network)) {
2216
2305
  migrated.network = old.network;
2217
- } else if (typeof old.apiUrl === "string" && old.apiUrl !== "http://localhost:3800") {
2218
- migrated.network = "local";
2219
- }
2220
- if (typeof old.apiKey === "string") {
2221
- migrated.apiKey = old.apiKey;
2222
- }
2223
- if (typeof old.sessionToken === "string" && !migrated.apiKey) {
2224
- console.warn("Warning: config contains sessionToken but no apiKey. Run `sl auth login` to re-authenticate.");
2225
- }
2226
- if (typeof old.apiUrl === "string" && old.apiUrl !== "http://localhost:3800") {
2227
- migrated.apiUrl = old.apiUrl;
2228
2306
  }
2229
2307
  if (typeof old.dataDir === "string") {
2230
2308
  migrated.dataDir = old.dataDir;
2231
2309
  }
2310
+ if (typeof old.defaultProject === "string") {
2311
+ migrated.defaultProject = old.defaultProject;
2312
+ }
2232
2313
  if (typeof old.nodeInstallPath === "string" || typeof old.nodeNetwork === "string") {
2233
2314
  migrated.node = {
2234
2315
  installPath: old.nodeInstallPath || "",
@@ -2280,9 +2361,6 @@ function applyEnvOverrides(config) {
2280
2361
  result.network = net;
2281
2362
  }
2282
2363
  }
2283
- if (process.env.SECONDLAYER_API_KEY) {
2284
- result.apiKey = process.env.SECONDLAYER_API_KEY;
2285
- }
2286
2364
  if (process.env.SL_DATA_DIR) {
2287
2365
  result.dataDir = process.env.SL_DATA_DIR;
2288
2366
  }
@@ -2388,39 +2466,33 @@ function isDefaultValue(config, key) {
2388
2466
  const defaultValue = getConfigValue(DEFAULT_CONFIG, key);
2389
2467
  return JSON.stringify(currentValue) === JSON.stringify(defaultValue);
2390
2468
  }
2391
- var PortsSchema, NodeSchema, DatabaseSchema, NetworkSchema, API_URLS, ConfigSchema, CONFIG_DIR, CONFIG_PATH, DEFAULT_CONFIG;
2469
+ var PortsSchema, NodeSchema, DatabaseSchema, NetworkSchema, ConfigSchema, CONFIG_DIR, CONFIG_PATH, DEFAULT_CONFIG;
2392
2470
  var init_config = __esm(() => {
2393
2471
  init_fs();
2394
- PortsSchema = z.object({
2395
- api: z.number().int().min(1).max(65535).default(3800),
2396
- indexer: z.number().int().min(1).max(65535).default(3700)
2472
+ PortsSchema = z2.object({
2473
+ api: z2.number().int().min(1).max(65535).default(3800),
2474
+ indexer: z2.number().int().min(1).max(65535).default(3700)
2397
2475
  });
2398
- NodeSchema = z.object({
2399
- installPath: z.string().min(1),
2400
- network: z.enum(["mainnet", "testnet"]).default("mainnet")
2476
+ NodeSchema = z2.object({
2477
+ installPath: z2.string().min(1),
2478
+ network: z2.enum(["mainnet", "testnet"]).default("mainnet")
2401
2479
  });
2402
- DatabaseSchema = z.object({
2403
- type: z.enum(["docker", "external"]).default("docker"),
2404
- url: z.string().url().optional()
2480
+ DatabaseSchema = z2.object({
2481
+ type: z2.enum(["docker", "external"]).default("docker"),
2482
+ url: z2.string().url().optional()
2405
2483
  });
2406
- NetworkSchema = z.enum(["local", "testnet", "mainnet"]);
2407
- API_URLS = {
2408
- local: "http://localhost:3800",
2409
- testnet: "https://api.secondlayer.tools",
2410
- mainnet: "https://api.secondlayer.tools"
2411
- };
2412
- ConfigSchema = z.object({
2484
+ NetworkSchema = z2.enum(["local", "testnet", "mainnet"]);
2485
+ ConfigSchema = z2.object({
2413
2486
  network: NetworkSchema.default("mainnet"),
2414
- apiUrl: z.string().url().optional(),
2415
- apiKey: z.string().optional(),
2416
- nodeRpcUrl: z.string().url().optional(),
2417
- dataDir: z.string().default("~/.secondlayer/data"),
2487
+ nodeRpcUrl: z2.string().url().optional(),
2488
+ dataDir: z2.string().default("~/.secondlayer/data"),
2418
2489
  node: NodeSchema.optional(),
2419
2490
  ports: PortsSchema.default({ api: 3800, indexer: 3700 }),
2420
- database: DatabaseSchema.default({ type: "docker" })
2491
+ database: DatabaseSchema.default({ type: "docker" }),
2492
+ defaultProject: z2.string().optional()
2421
2493
  });
2422
- CONFIG_DIR = join(homedir(), ".secondlayer");
2423
- CONFIG_PATH = join(CONFIG_DIR, "config.json");
2494
+ CONFIG_DIR = join2(homedir2(), ".secondlayer");
2495
+ CONFIG_PATH = join2(CONFIG_DIR, "config.json");
2424
2496
  DEFAULT_CONFIG = {
2425
2497
  network: "mainnet",
2426
2498
  dataDir: "~/.secondlayer/data",
@@ -2429,135 +2501,91 @@ var init_config = __esm(() => {
2429
2501
  };
2430
2502
  });
2431
2503
 
2432
- // src/lib/api-client.ts
2433
- import { SecondLayer } from "@secondlayer/sdk";
2434
- import { ApiError } from "@secondlayer/sdk";
2435
- async function assertOk(res) {
2436
- if (res.ok)
2437
- return;
2438
- const body = await res.text();
2439
- try {
2440
- const parsed = JSON.parse(body);
2441
- if (typeof parsed.error === "string" && parsed.error)
2442
- throw new Error(parsed.error);
2443
- } catch (e) {
2444
- if (e instanceof Error && e.message !== body)
2445
- throw e;
2504
+ // src/lib/project-file.ts
2505
+ import { existsSync } from "node:fs";
2506
+ import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
2507
+ import { homedir as homedir3 } from "node:os";
2508
+ import { dirname as dirname2, join as join3, parse as parsePath, resolve } from "node:path";
2509
+ import { z as z3 } from "zod/v4";
2510
+ async function readActiveProject(cwd, globalDefault) {
2511
+ let dir = resolve(cwd);
2512
+ const home = resolve(homedir3());
2513
+ const fsRoot = parsePath(dir).root;
2514
+ while (true) {
2515
+ const candidate = join3(dir, DIRNAME, FILENAME);
2516
+ if (existsSync(candidate)) {
2517
+ try {
2518
+ const raw = await readFile3(candidate, "utf8");
2519
+ const parsed = ProjectFileSchema.parse(JSON.parse(raw));
2520
+ return { slug: parsed.slug, resolvedFrom: candidate };
2521
+ } catch {}
2522
+ }
2523
+ if (existsSync(join3(dir, ".git")))
2524
+ break;
2525
+ if (dir === home || dir === fsRoot)
2526
+ break;
2527
+ const parent = dirname2(dir);
2528
+ if (parent === dir)
2529
+ break;
2530
+ dir = parent;
2446
2531
  }
2447
- throw new Error(`HTTP ${res.status}`);
2448
- }
2449
- function handleApiError(err, action) {
2450
- if (err instanceof ApiError && err.status === 401) {
2451
- console.error("Error: Authentication required. Run: sl auth login");
2452
- process.exit(1);
2532
+ if (globalDefault) {
2533
+ return {
2534
+ slug: globalDefault,
2535
+ resolvedFrom: join3(homedir3(), ".secondlayer", "config.json")
2536
+ };
2453
2537
  }
2454
- console.error(`Error: Failed to ${action}: ${err}`);
2455
- process.exit(1);
2538
+ return null;
2456
2539
  }
2457
- function withErrorHandling(fn, options) {
2458
- return async (...args) => {
2459
- try {
2460
- await fn(...args);
2461
- } catch (err) {
2462
- if (options?.onError) {
2463
- options.onError(err);
2464
- } else {
2465
- handleApiError(err, options?.action ?? "execute command");
2540
+ async function writeActiveProject(slug, cwd) {
2541
+ const dir = join3(resolve(cwd), DIRNAME);
2542
+ await mkdir3(dir, { recursive: true });
2543
+ const file = join3(dir, FILENAME);
2544
+ await writeFile3(file, JSON.stringify({ slug }, null, 2) + `
2545
+ `, "utf8");
2546
+ return file;
2547
+ }
2548
+ var ProjectFileSchema, FILENAME = "project", DIRNAME = ".secondlayer";
2549
+ var init_project_file = __esm(() => {
2550
+ ProjectFileSchema = z3.object({
2551
+ slug: z3.string().min(1)
2552
+ });
2553
+ });
2554
+
2555
+ // src/lib/resolve-tenant.ts
2556
+ async function resolveActiveTenant(opts = {}) {
2557
+ const envUrl = process.env.SL_API_URL;
2558
+ const envKey = process.env.SL_SERVICE_KEY;
2559
+ if (envUrl && envKey) {
2560
+ return { apiUrl: envUrl, ephemeralKey: envKey, fromEnv: true };
2561
+ }
2562
+ opts.tenant;
2563
+ try {
2564
+ const res = await httpPlatform("/api/tenants/me/keys/mint-ephemeral", { method: "POST" });
2565
+ return {
2566
+ apiUrl: res.apiUrl,
2567
+ ephemeralKey: res.serviceKey,
2568
+ fromEnv: false
2569
+ };
2570
+ } catch (err) {
2571
+ if (err instanceof CliHttpError) {
2572
+ if (err.status === 404) {
2573
+ const config = await loadConfig();
2574
+ const active = await readActiveProject(process.cwd(), config.defaultProject);
2575
+ const hint = active ? `Run 'sl instance create --plan launch' to provision for project ${active.slug}` : "Run 'sl project create <name>' then 'sl instance create --plan launch'";
2576
+ throw new CliHttpError(404, "NO_TENANT_FOR_PROJECT", { error: hint }, hint);
2466
2577
  }
2467
2578
  }
2468
- };
2469
- }
2470
- async function getClient() {
2471
- const config = await loadConfig();
2472
- const baseUrl = resolveApiUrl(config);
2473
- return new SecondLayer({ baseUrl, apiKey: config.apiKey });
2474
- }
2475
- function authHeaders(config) {
2476
- return SecondLayer.authHeaders(config.apiKey);
2477
- }
2478
- async function listSubgraphsApi() {
2479
- return (await getClient()).subgraphs.list();
2480
- }
2481
- async function getSubgraphApi(name) {
2482
- return (await getClient()).subgraphs.get(name);
2483
- }
2484
- async function reindexSubgraphApi(name, options) {
2485
- return (await getClient()).subgraphs.reindex(name, options);
2486
- }
2487
- async function backfillSubgraphApi(name, options) {
2488
- return (await getClient()).subgraphs.backfill(name, options);
2489
- }
2490
- async function stopSubgraphApi(name) {
2491
- return (await getClient()).subgraphs.stop(name);
2492
- }
2493
- async function deleteSubgraphApi(name) {
2494
- return (await getClient()).subgraphs.delete(name);
2495
- }
2496
- async function deploySubgraphApi(data) {
2497
- return (await getClient()).subgraphs.deploy(data);
2498
- }
2499
- async function querySubgraphTable(name, table, params = {}) {
2500
- return (await getClient()).subgraphs.queryTable(name, table, params);
2501
- }
2502
- async function querySubgraphTableCount(name, table, params = {}) {
2503
- return (await getClient()).subgraphs.queryTableCount(name, table, params);
2504
- }
2505
- async function getSubgraphGaps(name, opts) {
2506
- return (await getClient()).subgraphs.gaps(name, opts);
2507
- }
2508
- async function getAccountProfile() {
2509
- const config = await loadConfig();
2510
- const baseUrl = resolveApiUrl(config);
2511
- const res = await fetch(`${baseUrl}/api/accounts/me`, {
2512
- headers: authHeaders(config)
2513
- });
2514
- await assertOk(res);
2515
- return res.json();
2516
- }
2517
- async function updateAccountProfile(data) {
2518
- const config = await loadConfig();
2519
- const baseUrl = resolveApiUrl(config);
2520
- const res = await fetch(`${baseUrl}/api/accounts/me`, {
2521
- method: "PATCH",
2522
- headers: authHeaders(config),
2523
- body: JSON.stringify(data)
2524
- });
2525
- await assertOk(res);
2526
- return res.json();
2527
- }
2528
- async function browseMarketplace(opts = {}) {
2529
- return (await getClient()).marketplace.browse(opts);
2530
- }
2531
- async function getMarketplaceSubgraph(name) {
2532
- return (await getClient()).marketplace.get(name);
2533
- }
2534
- async function forkMarketplaceSubgraph(name, newName) {
2535
- return (await getClient()).marketplace.fork(name, newName);
2536
- }
2537
- async function publishSubgraphApi(name, opts) {
2538
- const config = await loadConfig();
2539
- const baseUrl = resolveApiUrl(config);
2540
- const res = await fetch(`${baseUrl}/api/subgraphs/${name}/publish`, {
2541
- method: "POST",
2542
- headers: authHeaders(config),
2543
- body: JSON.stringify(opts ?? {})
2544
- });
2545
- await assertOk(res);
2546
- return res.json();
2579
+ throw err;
2580
+ }
2547
2581
  }
2548
- async function unpublishSubgraphApi(name) {
2549
- const config = await loadConfig();
2550
- const baseUrl = resolveApiUrl(config);
2551
- const res = await fetch(`${baseUrl}/api/subgraphs/${name}/unpublish`, {
2552
- method: "POST",
2553
- headers: authHeaders(config),
2554
- body: JSON.stringify({})
2555
- });
2556
- await assertOk(res);
2557
- return res.json();
2582
+ function isOssMode() {
2583
+ return !!process.env.SL_API_URL && !process.env.SL_SERVICE_KEY;
2558
2584
  }
2559
- var init_api_client = __esm(() => {
2585
+ var init_resolve_tenant = __esm(() => {
2586
+ init_http();
2560
2587
  init_config();
2588
+ init_project_file();
2561
2589
  });
2562
2590
 
2563
2591
  // src/lib/output.ts
@@ -2690,9 +2718,9 @@ var init_query = __esm(() => {
2690
2718
  CLOSE = {};
2691
2719
  Query = class Query extends Promise {
2692
2720
  constructor(strings, args, handler, canceller, options = {}) {
2693
- let resolve, reject;
2721
+ let resolve2, reject;
2694
2722
  super((a, b) => {
2695
- resolve = a;
2723
+ resolve2 = a;
2696
2724
  reject = b;
2697
2725
  });
2698
2726
  this.tagged = Array.isArray(strings.raw);
@@ -2703,7 +2731,7 @@ var init_query = __esm(() => {
2703
2731
  this.options = options;
2704
2732
  this.state = null;
2705
2733
  this.statement = null;
2706
- this.resolve = (x) => (this.active = false, resolve(x));
2734
+ this.resolve = (x) => (this.active = false, resolve2(x));
2707
2735
  this.reject = (x) => (this.active = false, reject(x));
2708
2736
  this.active = false;
2709
2737
  this.cancelled = null;
@@ -2751,12 +2779,12 @@ var init_query = __esm(() => {
2751
2779
  if (this.executed && !this.active)
2752
2780
  return { done: true };
2753
2781
  prev && prev();
2754
- const promise = new Promise((resolve, reject) => {
2782
+ const promise = new Promise((resolve2, reject) => {
2755
2783
  this.cursorFn = (value) => {
2756
- resolve({ value, done: false });
2784
+ resolve2({ value, done: false });
2757
2785
  return new Promise((r) => prev = r);
2758
2786
  };
2759
- this.resolve = () => (this.active = false, resolve({ done: true }));
2787
+ this.resolve = () => (this.active = false, resolve2({ done: true }));
2760
2788
  this.reject = (x) => (this.active = false, reject(x));
2761
2789
  });
2762
2790
  this.execute();
@@ -3310,12 +3338,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
3310
3338
  x.on("drain", drain);
3311
3339
  return x;
3312
3340
  }
3313
- async function cancel({ pid, secret }, resolve, reject) {
3341
+ async function cancel({ pid, secret }, resolve2, reject) {
3314
3342
  try {
3315
3343
  cancelMessage = bytes_default().i32(16).i32(80877102).i32(pid).i32(secret).end(16);
3316
3344
  await connect();
3317
3345
  socket.once("error", reject);
3318
- socket.once("close", resolve);
3346
+ socket.once("close", resolve2);
3319
3347
  } catch (error3) {
3320
3348
  reject(error3);
3321
3349
  }
@@ -4188,7 +4216,7 @@ var noop2 = () => {};
4188
4216
  // ../../node_modules/postgres/src/large.js
4189
4217
  import Stream2 from "stream";
4190
4218
  function largeObject(sql, oid, mode = 131072 | 262144) {
4191
- return new Promise(async (resolve, reject) => {
4219
+ return new Promise(async (resolve2, reject) => {
4192
4220
  await sql.begin(async (sql2) => {
4193
4221
  let finish;
4194
4222
  !oid && ([{ oid }] = await sql2`select lo_creat(-1) as oid`);
@@ -4214,7 +4242,7 @@ function largeObject(sql, oid, mode = 131072 | 262144) {
4214
4242
  ) seek
4215
4243
  `
4216
4244
  };
4217
- resolve(lo);
4245
+ resolve2(lo);
4218
4246
  return new Promise(async (r) => finish = r);
4219
4247
  async function readable({
4220
4248
  highWaterMark = 2048 * 8,
@@ -4374,8 +4402,8 @@ function Postgres(a, b2) {
4374
4402
  }
4375
4403
  async function reserve() {
4376
4404
  const queue = queue_default();
4377
- const c = open.length ? open.shift() : await new Promise((resolve, reject) => {
4378
- const query = { reserve: resolve, reject };
4405
+ const c = open.length ? open.shift() : await new Promise((resolve2, reject) => {
4406
+ const query = { reserve: resolve2, reject };
4379
4407
  queries.push(query);
4380
4408
  closed.length && connect(closed.shift(), query);
4381
4409
  });
@@ -4412,9 +4440,9 @@ function Postgres(a, b2) {
4412
4440
  let uncaughtError, result;
4413
4441
  name && await sql2`savepoint ${sql2(name)}`;
4414
4442
  try {
4415
- result = await new Promise((resolve, reject) => {
4443
+ result = await new Promise((resolve2, reject) => {
4416
4444
  const x = fn2(sql2);
4417
- Promise.resolve(Array.isArray(x) ? Promise.all(x) : x).then(resolve, reject);
4445
+ Promise.resolve(Array.isArray(x) ? Promise.all(x) : x).then(resolve2, reject);
4418
4446
  });
4419
4447
  if (uncaughtError)
4420
4448
  throw uncaughtError;
@@ -4471,8 +4499,8 @@ function Postgres(a, b2) {
4471
4499
  return c.execute(query) ? move(c, busy) : move(c, full);
4472
4500
  }
4473
4501
  function cancel(query) {
4474
- return new Promise((resolve, reject) => {
4475
- query.state ? query.active ? connection_default(options).cancel(query.state, resolve, reject) : query.cancelled = { resolve, reject } : (queries.remove(query), query.cancelled = true, query.reject(Errors.generic("57014", "canceling statement due to user request")), resolve());
4502
+ return new Promise((resolve2, reject) => {
4503
+ query.state ? query.active ? connection_default(options).cancel(query.state, resolve2, reject) : query.cancelled = { resolve: resolve2, reject } : (queries.remove(query), query.cancelled = true, query.reject(Errors.generic("57014", "canceling statement due to user request")), resolve2());
4476
4504
  });
4477
4505
  }
4478
4506
  async function end({ timeout = null } = {}) {
@@ -4488,11 +4516,11 @@ function Postgres(a, b2) {
4488
4516
  async function close() {
4489
4517
  await Promise.all(connections.map((c) => c.end()));
4490
4518
  }
4491
- async function destroy(resolve) {
4519
+ async function destroy(resolve2) {
4492
4520
  await Promise.all(connections.map((c) => c.terminate()));
4493
4521
  while (queries.length)
4494
4522
  queries.shift().reject(Errors.connection("CONNECTION_DESTROYED", options));
4495
- resolve();
4523
+ resolve2();
4496
4524
  }
4497
4525
  function connect(c, query) {
4498
4526
  move(c, connecting);
@@ -4676,13 +4704,13 @@ __export(exports_dev_state, {
4676
4704
  clearLogs: () => clearLogs,
4677
4705
  clearDevState: () => clearDevState
4678
4706
  });
4679
- import { homedir as homedir3 } from "node:os";
4680
- import { join as join3 } from "node:path";
4707
+ import { homedir as homedir5 } from "node:os";
4708
+ import { join as join5 } from "node:path";
4681
4709
  function getLogsDir() {
4682
4710
  return LOGS_DIR;
4683
4711
  }
4684
4712
  function getLogFile(service) {
4685
- return join3(LOGS_DIR, `${service}.log`);
4713
+ return join5(LOGS_DIR, `${service}.log`);
4686
4714
  }
4687
4715
  async function ensureDirs() {
4688
4716
  await Bun.$`mkdir -p ${STATE_DIR}`.quiet();
@@ -4739,9 +4767,9 @@ async function isDevRunning() {
4739
4767
  }
4740
4768
  var STATE_DIR, DEV_STATE_PATH, LOGS_DIR;
4741
4769
  var init_dev_state = __esm(() => {
4742
- STATE_DIR = join3(homedir3(), ".secondlayer");
4743
- DEV_STATE_PATH = join3(STATE_DIR, "dev.json");
4744
- LOGS_DIR = join3(STATE_DIR, "logs");
4770
+ STATE_DIR = join5(homedir5(), ".secondlayer");
4771
+ DEV_STATE_PATH = join5(STATE_DIR, "dev.json");
4772
+ LOGS_DIR = join5(STATE_DIR, "logs");
4745
4773
  });
4746
4774
 
4747
4775
  // src/utils/format.ts
@@ -5460,9 +5488,9 @@ var init_dist = __esm(() => {
5460
5488
  class PCancelable {
5461
5489
  static fn(userFunction) {
5462
5490
  return (...arguments_) => {
5463
- return new PCancelable((resolve, reject, onCancel) => {
5491
+ return new PCancelable((resolve2, reject, onCancel) => {
5464
5492
  arguments_.push(onCancel);
5465
- userFunction(...arguments_).then(resolve, reject);
5493
+ userFunction(...arguments_).then(resolve2, reject);
5466
5494
  });
5467
5495
  };
5468
5496
  }
@@ -5471,12 +5499,12 @@ class PCancelable {
5471
5499
  this._isPending = true;
5472
5500
  this._isCanceled = false;
5473
5501
  this._rejectOnCancel = true;
5474
- this._promise = new Promise((resolve, reject) => {
5502
+ this._promise = new Promise((resolve2, reject) => {
5475
5503
  this._reject = reject;
5476
5504
  const onResolve = (value) => {
5477
5505
  if (!this._isCanceled || !onCancel.shouldReject) {
5478
5506
  this._isPending = false;
5479
- resolve(value);
5507
+ resolve2(value);
5480
5508
  }
5481
5509
  };
5482
5510
  const onReject = (error2) => {
@@ -5626,8 +5654,8 @@ var init_errors2 = __esm(() => {
5626
5654
  }
5627
5655
  };
5628
5656
  MaxRedirectsError = class MaxRedirectsError extends RequestError {
5629
- constructor(request) {
5630
- super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
5657
+ constructor(request2) {
5658
+ super(`Redirected ${request2.options.maxRedirects} times. Aborting.`, {}, request2);
5631
5659
  this.name = "MaxRedirectsError";
5632
5660
  this.code = "ERR_TOO_MANY_REDIRECTS";
5633
5661
  }
@@ -5640,22 +5668,22 @@ var init_errors2 = __esm(() => {
5640
5668
  }
5641
5669
  };
5642
5670
  CacheError = class CacheError extends RequestError {
5643
- constructor(error2, request) {
5644
- super(error2.message, error2, request);
5671
+ constructor(error2, request2) {
5672
+ super(error2.message, error2, request2);
5645
5673
  this.name = "CacheError";
5646
5674
  this.code = this.code === "ERR_GOT_REQUEST_ERROR" ? "ERR_CACHE_ACCESS" : this.code;
5647
5675
  }
5648
5676
  };
5649
5677
  UploadError = class UploadError extends RequestError {
5650
- constructor(error2, request) {
5651
- super(error2.message, error2, request);
5678
+ constructor(error2, request2) {
5679
+ super(error2.message, error2, request2);
5652
5680
  this.name = "UploadError";
5653
5681
  this.code = this.code === "ERR_GOT_REQUEST_ERROR" ? "ERR_UPLOAD" : this.code;
5654
5682
  }
5655
5683
  };
5656
5684
  TimeoutError = class TimeoutError extends RequestError {
5657
- constructor(error2, timings, request) {
5658
- super(error2.message, error2, request);
5685
+ constructor(error2, timings, request2) {
5686
+ super(error2.message, error2, request2);
5659
5687
  Object.defineProperty(this, "timings", {
5660
5688
  enumerable: true,
5661
5689
  configurable: true,
@@ -5674,22 +5702,22 @@ var init_errors2 = __esm(() => {
5674
5702
  }
5675
5703
  };
5676
5704
  ReadError = class ReadError extends RequestError {
5677
- constructor(error2, request) {
5678
- super(error2.message, error2, request);
5705
+ constructor(error2, request2) {
5706
+ super(error2.message, error2, request2);
5679
5707
  this.name = "ReadError";
5680
5708
  this.code = this.code === "ERR_GOT_REQUEST_ERROR" ? "ERR_READING_RESPONSE_STREAM" : this.code;
5681
5709
  }
5682
5710
  };
5683
5711
  RetryError = class RetryError extends RequestError {
5684
- constructor(request) {
5685
- super("Retrying", {}, request);
5712
+ constructor(request2) {
5713
+ super("Retrying", {}, request2);
5686
5714
  this.name = "RetryError";
5687
5715
  this.code = "ERR_RETRYING";
5688
5716
  }
5689
5717
  };
5690
5718
  AbortError = class AbortError extends RequestError {
5691
- constructor(request) {
5692
- super("This operation was aborted.", {}, request);
5719
+ constructor(request2) {
5720
+ super("This operation was aborted.", {}, request2);
5693
5721
  this.code = "ERR_ABORTED";
5694
5722
  this.name = "AbortError";
5695
5723
  }
@@ -5744,9 +5772,9 @@ var require_source = __commonJS((exports, module) => {
5744
5772
  // ../../node_modules/@szmarczak/http-timer/dist/source/index.js
5745
5773
  import { errorMonitor } from "events";
5746
5774
  import { types as types2 } from "util";
5747
- var import_defer_to_connect, timer2 = (request) => {
5748
- if (request.timings) {
5749
- return request.timings;
5775
+ var import_defer_to_connect, timer2 = (request2) => {
5776
+ if (request2.timings) {
5777
+ return request2.timings;
5750
5778
  }
5751
5779
  const timings = {
5752
5780
  start: Date.now(),
@@ -5770,19 +5798,19 @@ var import_defer_to_connect, timer2 = (request) => {
5770
5798
  total: undefined
5771
5799
  }
5772
5800
  };
5773
- request.timings = timings;
5801
+ request2.timings = timings;
5774
5802
  const handleError = (origin) => {
5775
5803
  origin.once(errorMonitor, () => {
5776
5804
  timings.error = Date.now();
5777
5805
  timings.phases.total = timings.error - timings.start;
5778
5806
  });
5779
5807
  };
5780
- handleError(request);
5808
+ handleError(request2);
5781
5809
  const onAbort = () => {
5782
5810
  timings.abort = Date.now();
5783
5811
  timings.phases.total = timings.abort - timings.start;
5784
5812
  };
5785
- request.prependOnceListener("abort", onAbort);
5813
+ request2.prependOnceListener("abort", onAbort);
5786
5814
  const onSocket = (socket) => {
5787
5815
  timings.socket = Date.now();
5788
5816
  timings.phases.wait = timings.socket - timings.start;
@@ -5810,27 +5838,27 @@ var import_defer_to_connect, timer2 = (request) => {
5810
5838
  }
5811
5839
  });
5812
5840
  };
5813
- if (request.socket) {
5814
- onSocket(request.socket);
5841
+ if (request2.socket) {
5842
+ onSocket(request2.socket);
5815
5843
  } else {
5816
- request.prependOnceListener("socket", onSocket);
5844
+ request2.prependOnceListener("socket", onSocket);
5817
5845
  }
5818
5846
  const onUpload = () => {
5819
5847
  timings.upload = Date.now();
5820
5848
  timings.phases.request = timings.upload - (timings.secureConnect ?? timings.connect);
5821
5849
  };
5822
- if (request.writableFinished) {
5850
+ if (request2.writableFinished) {
5823
5851
  onUpload();
5824
5852
  } else {
5825
- request.prependOnceListener("finish", onUpload);
5853
+ request2.prependOnceListener("finish", onUpload);
5826
5854
  }
5827
- request.prependOnceListener("response", (response) => {
5855
+ request2.prependOnceListener("response", (response) => {
5828
5856
  timings.response = Date.now();
5829
5857
  timings.phases.firstByte = timings.response - timings.upload;
5830
5858
  response.timings = timings;
5831
5859
  handleError(response);
5832
5860
  response.prependOnceListener("end", () => {
5833
- request.off("abort", onAbort);
5861
+ request2.off("abort", onAbort);
5834
5862
  response.off("aborted", onAbort);
5835
5863
  if (timings.phases.total) {
5836
5864
  return;
@@ -6120,7 +6148,7 @@ var require_get_stream = __commonJS((exports, module) => {
6120
6148
  };
6121
6149
  const { maxBuffer } = options;
6122
6150
  const stream2 = bufferStream(options);
6123
- await new Promise((resolve, reject) => {
6151
+ await new Promise((resolve2, reject) => {
6124
6152
  const rejectPromise = (error2) => {
6125
6153
  if (error2 && stream2.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
6126
6154
  error2.bufferedData = stream2.getBufferedValue();
@@ -6130,7 +6158,7 @@ var require_get_stream = __commonJS((exports, module) => {
6130
6158
  (async () => {
6131
6159
  try {
6132
6160
  await streamPipelinePromisified(inputStream, stream2);
6133
- resolve();
6161
+ resolve2();
6134
6162
  } catch (error2) {
6135
6163
  rejectPromise(error2);
6136
6164
  }
@@ -6308,16 +6336,16 @@ var require_http_cache_semantics = __commonJS((exports, module) => {
6308
6336
  revalidation
6309
6337
  };
6310
6338
  }
6311
- _evaluateRequestRevalidation(request, synchronous) {
6339
+ _evaluateRequestRevalidation(request2, synchronous) {
6312
6340
  return {
6313
6341
  synchronous,
6314
- headers: this.revalidationHeaders(request)
6342
+ headers: this.revalidationHeaders(request2)
6315
6343
  };
6316
6344
  }
6317
- _evaluateRequestMissResult(request) {
6345
+ _evaluateRequestMissResult(request2) {
6318
6346
  return {
6319
6347
  response: undefined,
6320
- revalidation: this._evaluateRequestRevalidation(request, true)
6348
+ revalidation: this._evaluateRequestRevalidation(request2, true)
6321
6349
  };
6322
6350
  }
6323
6351
  evaluateRequest(req) {
@@ -6546,8 +6574,8 @@ var require_http_cache_semantics = __commonJS((exports, module) => {
6546
6574
  }
6547
6575
  return headers;
6548
6576
  }
6549
- revalidatedPolicy(request, response) {
6550
- this._assertRequestHasHeaders(request);
6577
+ revalidatedPolicy(request2, response) {
6578
+ this._assertRequestHasHeaders(request2);
6551
6579
  if (this._useStaleIfError() && isErrorResponse(response)) {
6552
6580
  return {
6553
6581
  policy: this,
@@ -6580,7 +6608,7 @@ var require_http_cache_semantics = __commonJS((exports, module) => {
6580
6608
  };
6581
6609
  if (!matches) {
6582
6610
  return {
6583
- policy: new this.constructor(request, response, optionsCopy),
6611
+ policy: new this.constructor(request2, response, optionsCopy),
6584
6612
  modified: response.status != 304,
6585
6613
  matches: false
6586
6614
  };
@@ -6595,7 +6623,7 @@ var require_http_cache_semantics = __commonJS((exports, module) => {
6595
6623
  headers
6596
6624
  });
6597
6625
  return {
6598
- policy: new this.constructor(request, newResponse, optionsCopy),
6626
+ policy: new this.constructor(request2, newResponse, optionsCopy),
6599
6627
  modified: false,
6600
6628
  matches: true
6601
6629
  };
@@ -7032,11 +7060,11 @@ class CacheableRequest {
7032
7060
  madeRequest = true;
7033
7061
  let requestErrored = false;
7034
7062
  let requestErrorCallback = () => {};
7035
- const requestErrorPromise = new Promise((resolve) => {
7063
+ const requestErrorPromise = new Promise((resolve2) => {
7036
7064
  requestErrorCallback = () => {
7037
7065
  if (!requestErrored) {
7038
7066
  requestErrored = true;
7039
- resolve();
7067
+ resolve2();
7040
7068
  }
7041
7069
  };
7042
7070
  });
@@ -7046,8 +7074,8 @@ class CacheableRequest {
7046
7074
  const revalidatedPolicy = import_http_cache_semantics.default.fromObject(revalidate.cachePolicy).revalidatedPolicy(options_, response);
7047
7075
  if (!revalidatedPolicy.modified) {
7048
7076
  response.resume();
7049
- await new Promise((resolve) => {
7050
- response.once("end", resolve);
7077
+ await new Promise((resolve2) => {
7078
+ response.once("end", resolve2);
7051
7079
  });
7052
7080
  const headers = convertHeaders(revalidatedPolicy.policy.responseHeaders());
7053
7081
  response = new Response({ statusCode: revalidate.statusCode, headers, body: revalidate.body, url: revalidate.url });
@@ -7067,8 +7095,8 @@ class CacheableRequest {
7067
7095
  const bodyPromise = import_get_stream.default.buffer(response);
7068
7096
  await Promise.race([
7069
7097
  requestErrorPromise,
7070
- new Promise((resolve) => response.once("end", resolve)),
7071
- new Promise((resolve) => response.once("close", resolve))
7098
+ new Promise((resolve2) => response.once("end", resolve2)),
7099
+ new Promise((resolve2) => response.once("close", resolve2))
7072
7100
  ]);
7073
7101
  const body = await bodyPromise;
7074
7102
  let value = {
@@ -7399,7 +7427,7 @@ var require_get_stream2 = __commonJS((exports, module) => {
7399
7427
  };
7400
7428
  const { maxBuffer } = options;
7401
7429
  const stream3 = bufferStream(options);
7402
- await new Promise((resolve, reject) => {
7430
+ await new Promise((resolve2, reject) => {
7403
7431
  const rejectPromise = (error2) => {
7404
7432
  if (error2 && stream3.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
7405
7433
  error2.bufferedData = stream3.getBufferedValue();
@@ -7409,7 +7437,7 @@ var require_get_stream2 = __commonJS((exports, module) => {
7409
7437
  (async () => {
7410
7438
  try {
7411
7439
  await streamPipelinePromisified(inputStream, stream3);
7412
- resolve();
7440
+ resolve2();
7413
7441
  } catch (error2) {
7414
7442
  rejectPromise(error2);
7415
7443
  }
@@ -7735,11 +7763,11 @@ function unhandle() {
7735
7763
 
7736
7764
  // ../../node_modules/got/dist/source/core/timed-out.js
7737
7765
  import net2 from "node:net";
7738
- function timedOut(request, delays, options) {
7739
- if (reentry in request) {
7766
+ function timedOut(request2, delays, options) {
7767
+ if (reentry in request2) {
7740
7768
  return noop3;
7741
7769
  }
7742
- request[reentry] = true;
7770
+ request2[reentry] = true;
7743
7771
  const cancelers = [];
7744
7772
  const { once, unhandleAll } = unhandle();
7745
7773
  const addTimeout = (delay, callback, event) => {
@@ -7753,7 +7781,7 @@ function timedOut(request, delays, options) {
7753
7781
  };
7754
7782
  const { host, hostname } = options;
7755
7783
  const timeoutHandler = (delay, event) => {
7756
- request.destroy(new TimeoutError2(delay, event));
7784
+ request2.destroy(new TimeoutError2(delay, event));
7757
7785
  };
7758
7786
  const cancelTimeouts = () => {
7759
7787
  for (const cancel of cancelers) {
@@ -7761,15 +7789,15 @@ function timedOut(request, delays, options) {
7761
7789
  }
7762
7790
  unhandleAll();
7763
7791
  };
7764
- request.once("error", (error2) => {
7792
+ request2.once("error", (error2) => {
7765
7793
  cancelTimeouts();
7766
- if (request.listenerCount("error") === 0) {
7794
+ if (request2.listenerCount("error") === 0) {
7767
7795
  throw error2;
7768
7796
  }
7769
7797
  });
7770
7798
  if (delays.request !== undefined) {
7771
7799
  const cancelTimeout = addTimeout(delays.request, timeoutHandler, "request");
7772
- once(request, "response", (response) => {
7800
+ once(request2, "response", (response) => {
7773
7801
  once(response, "end", cancelTimeout);
7774
7802
  });
7775
7803
  }
@@ -7778,9 +7806,9 @@ function timedOut(request, delays, options) {
7778
7806
  const socketTimeoutHandler = () => {
7779
7807
  timeoutHandler(socket, "socket");
7780
7808
  };
7781
- request.setTimeout(socket, socketTimeoutHandler);
7809
+ request2.setTimeout(socket, socketTimeoutHandler);
7782
7810
  cancelers.push(() => {
7783
- request.removeListener("timeout", socketTimeoutHandler);
7811
+ request2.removeListener("timeout", socketTimeoutHandler);
7784
7812
  });
7785
7813
  }
7786
7814
  const hasLookup = delays.lookup !== undefined;
@@ -7788,8 +7816,8 @@ function timedOut(request, delays, options) {
7788
7816
  const hasSecureConnect = delays.secureConnect !== undefined;
7789
7817
  const hasSend = delays.send !== undefined;
7790
7818
  if (hasLookup || hasConnect || hasSecureConnect || hasSend) {
7791
- once(request, "socket", (socket) => {
7792
- const { socketPath } = request;
7819
+ once(request2, "socket", (socket) => {
7820
+ const { socketPath } = request2;
7793
7821
  if (socket.connecting) {
7794
7822
  const hasPath = Boolean(socketPath ?? net2.isIP(hostname ?? host ?? "") !== 0);
7795
7823
  if (hasLookup && !hasPath && socket.address().address === undefined) {
@@ -7819,22 +7847,22 @@ function timedOut(request, delays, options) {
7819
7847
  const timeRequest = () => addTimeout(delays.send, timeoutHandler, "send");
7820
7848
  if (socket.connecting) {
7821
7849
  once(socket, "connect", () => {
7822
- once(request, "upload-complete", timeRequest());
7850
+ once(request2, "upload-complete", timeRequest());
7823
7851
  });
7824
7852
  } else {
7825
- once(request, "upload-complete", timeRequest());
7853
+ once(request2, "upload-complete", timeRequest());
7826
7854
  }
7827
7855
  }
7828
7856
  });
7829
7857
  }
7830
7858
  if (delays.response !== undefined) {
7831
- once(request, "upload-complete", () => {
7859
+ once(request2, "upload-complete", () => {
7832
7860
  const cancelTimeout = addTimeout(delays.response, timeoutHandler, "response");
7833
- once(request, "response", cancelTimeout);
7861
+ once(request2, "response", cancelTimeout);
7834
7862
  });
7835
7863
  }
7836
7864
  if (delays.read !== undefined) {
7837
- once(request, "response", (response) => {
7865
+ once(request2, "response", (response) => {
7838
7866
  const cancelTimeout = addTimeout(delays.read, timeoutHandler, "read");
7839
7867
  once(response, "end", cancelTimeout);
7840
7868
  });
@@ -8595,12 +8623,12 @@ var require_agent = __commonJS((exports, module) => {
8595
8623
  }
8596
8624
  }
8597
8625
  getSession(origin, options, listeners) {
8598
- return new Promise((resolve, reject) => {
8626
+ return new Promise((resolve2, reject) => {
8599
8627
  if (Array.isArray(listeners) && listeners.length > 0) {
8600
8628
  listeners = [...listeners];
8601
- resolve();
8629
+ resolve2();
8602
8630
  } else {
8603
- listeners = [{ resolve, reject }];
8631
+ listeners = [{ resolve: resolve2, reject }];
8604
8632
  }
8605
8633
  try {
8606
8634
  if (typeof origin === "string") {
@@ -8879,14 +8907,14 @@ var require_agent = __commonJS((exports, module) => {
8879
8907
  });
8880
8908
  }
8881
8909
  request(origin, options, headers, streamOptions) {
8882
- return new Promise((resolve, reject) => {
8910
+ return new Promise((resolve2, reject) => {
8883
8911
  this.getSession(origin, options, [{
8884
8912
  reject,
8885
8913
  resolve: (session) => {
8886
8914
  try {
8887
8915
  const stream2 = session.request(headers, streamOptions);
8888
8916
  delayAsyncDestroy(stream2);
8889
- resolve(stream2);
8917
+ resolve2(stream2);
8890
8918
  } catch (error2) {
8891
8919
  reject(error2);
8892
8920
  }
@@ -9607,7 +9635,7 @@ var require_client_request = __commonJS((exports, module) => {
9607
9635
  // ../../node_modules/resolve-alpn/index.js
9608
9636
  var require_resolve_alpn = __commonJS((exports, module) => {
9609
9637
  var tls2 = __require("tls");
9610
- module.exports = (options = {}, connect = tls2.connect) => new Promise((resolve, reject) => {
9638
+ module.exports = (options = {}, connect = tls2.connect) => new Promise((resolve2, reject) => {
9611
9639
  let timeout = false;
9612
9640
  let socket;
9613
9641
  const callback = async () => {
@@ -9615,14 +9643,14 @@ var require_resolve_alpn = __commonJS((exports, module) => {
9615
9643
  socket.off("timeout", onTimeout);
9616
9644
  socket.off("error", reject);
9617
9645
  if (options.resolveSocket) {
9618
- resolve({ alpnProtocol: socket.alpnProtocol, socket, timeout });
9646
+ resolve2({ alpnProtocol: socket.alpnProtocol, socket, timeout });
9619
9647
  if (timeout) {
9620
9648
  await Promise.resolve();
9621
9649
  socket.emit("timeout");
9622
9650
  }
9623
9651
  } else {
9624
9652
  socket.destroy();
9625
- resolve({ alpnProtocol: socket.alpnProtocol, timeout });
9653
+ resolve2({ alpnProtocol: socket.alpnProtocol, timeout });
9626
9654
  }
9627
9655
  };
9628
9656
  const onTimeout = async () => {
@@ -10025,11 +10053,11 @@ var require_h2_over_h2 = __commonJS((exports, module) => {
10025
10053
  var { globalAgent } = require_agent();
10026
10054
  var Http2OverHttpX = require_h2_over_hx();
10027
10055
  var getAuthorizationHeaders = require_get_auth_headers();
10028
- var getStatusCode = (stream2) => new Promise((resolve, reject) => {
10056
+ var getStatusCode = (stream2) => new Promise((resolve2, reject) => {
10029
10057
  stream2.once("error", reject);
10030
10058
  stream2.once("response", (headers) => {
10031
10059
  stream2.off("error", reject);
10032
- resolve(headers[":status"]);
10060
+ resolve2(headers[":status"]);
10033
10061
  });
10034
10062
  });
10035
10063
 
@@ -10056,14 +10084,14 @@ var require_h2_over_h1 = __commonJS((exports, module) => {
10056
10084
  var https = __require("https");
10057
10085
  var Http2OverHttpX = require_h2_over_hx();
10058
10086
  var getAuthorizationHeaders = require_get_auth_headers();
10059
- var getStream2 = (request) => new Promise((resolve, reject) => {
10087
+ var getStream2 = (request2) => new Promise((resolve2, reject) => {
10060
10088
  const onConnect = (response, socket, head) => {
10061
10089
  socket.unshift(head);
10062
- request.off("error", reject);
10063
- resolve([socket, response.statusCode, response.statusMessage]);
10090
+ request2.off("error", reject);
10091
+ resolve2([socket, response.statusCode, response.statusMessage]);
10064
10092
  };
10065
- request.once("error", reject);
10066
- request.once("connect", onConnect);
10093
+ request2.once("error", reject);
10094
+ request2.once("connect", onConnect);
10067
10095
  });
10068
10096
 
10069
10097
  class Http2OverHttp extends Http2OverHttpX {
@@ -10071,7 +10099,7 @@ var require_h2_over_h1 = __commonJS((exports, module) => {
10071
10099
  const { proxyOptions } = this;
10072
10100
  const { url, headers } = this.proxyOptions;
10073
10101
  const network = url.protocol === "https:" ? https : http;
10074
- const request = network.request({
10102
+ const request2 = network.request({
10075
10103
  ...proxyOptions,
10076
10104
  hostname: url.hostname,
10077
10105
  port: url.port,
@@ -10083,7 +10111,7 @@ var require_h2_over_h1 = __commonJS((exports, module) => {
10083
10111
  },
10084
10112
  method: "CONNECT"
10085
10113
  }).end();
10086
- return getStream2(request);
10114
+ return getStream2(request2);
10087
10115
  }
10088
10116
  }
10089
10117
  module.exports = {
@@ -10113,7 +10141,7 @@ var require_source2 = __commonJS((exports, module) => {
10113
10141
  } = require_h2_over_h1();
10114
10142
  var validateHeaderName = require_validate_header_name();
10115
10143
  var validateHeaderValue = require_validate_header_value();
10116
- var request = (url, options, callback) => new ClientRequest(url, options, callback);
10144
+ var request2 = (url, options, callback) => new ClientRequest(url, options, callback);
10117
10145
  var get = (url, options, callback) => {
10118
10146
  const req = new ClientRequest(url, options, callback);
10119
10147
  req.end();
@@ -10125,7 +10153,7 @@ var require_source2 = __commonJS((exports, module) => {
10125
10153
  IncomingMessage,
10126
10154
  Agent,
10127
10155
  globalAgent,
10128
- request,
10156
+ request: request2,
10129
10157
  get,
10130
10158
  auto,
10131
10159
  proxies: {
@@ -11247,11 +11275,11 @@ var init_options = __esm(() => {
11247
11275
  }
11248
11276
  getRequestFunction() {
11249
11277
  const url = this._internals.url;
11250
- const { request } = this._internals;
11251
- if (!request && url) {
11278
+ const { request: request2 } = this._internals;
11279
+ if (!request2 && url) {
11252
11280
  return this.getFallbackRequestFunction();
11253
11281
  }
11254
- return request;
11282
+ return request2;
11255
11283
  }
11256
11284
  getFallbackRequestFunction() {
11257
11285
  const url = this._internals.url;
@@ -11685,11 +11713,11 @@ var init_core = __esm(() => {
11685
11713
  return;
11686
11714
  }
11687
11715
  if (backoff2) {
11688
- await new Promise((resolve) => {
11689
- const timeout = setTimeout(resolve, backoff2);
11716
+ await new Promise((resolve2) => {
11717
+ const timeout = setTimeout(resolve2, backoff2);
11690
11718
  this._stopRetry = () => {
11691
11719
  clearTimeout(timeout);
11692
- resolve();
11720
+ resolve2();
11693
11721
  };
11694
11722
  });
11695
11723
  if (this.destroyed) {
@@ -11708,12 +11736,12 @@ var init_core = __esm(() => {
11708
11736
  }
11709
11737
  this.destroy();
11710
11738
  this.emit("retry", this.retryCount + 1, error2, (updatedOptions) => {
11711
- const request = new Request(options.url, updatedOptions, options);
11712
- request.retryCount = this.retryCount + 1;
11739
+ const request2 = new Request(options.url, updatedOptions, options);
11740
+ request2.retryCount = this.retryCount + 1;
11713
11741
  process3.nextTick(() => {
11714
- request.flush();
11742
+ request2.flush();
11715
11743
  });
11716
- return request;
11744
+ return request2;
11717
11745
  });
11718
11746
  return;
11719
11747
  }
@@ -12040,38 +12068,38 @@ var init_core = __esm(() => {
12040
12068
  this._beforeError(error2);
12041
12069
  }
12042
12070
  }
12043
- _onRequest(request) {
12071
+ _onRequest(request2) {
12044
12072
  const { options } = this;
12045
12073
  const { timeout, url } = options;
12046
- source_default(request);
12074
+ source_default(request2);
12047
12075
  if (this.options.http2) {
12048
- request.setTimeout(0);
12076
+ request2.setTimeout(0);
12049
12077
  }
12050
- this._cancelTimeouts = timedOut(request, timeout, url);
12078
+ this._cancelTimeouts = timedOut(request2, timeout, url);
12051
12079
  const responseEventName = options.cache ? "cacheableResponse" : "response";
12052
- request.once(responseEventName, (response) => {
12080
+ request2.once(responseEventName, (response) => {
12053
12081
  this._onResponse(response);
12054
12082
  });
12055
- request.once("error", (error2) => {
12083
+ request2.once("error", (error2) => {
12056
12084
  this._aborted = true;
12057
- request.destroy();
12085
+ request2.destroy();
12058
12086
  error2 = error2 instanceof TimeoutError2 ? new TimeoutError(error2, this.timings, this) : new RequestError(error2.message, error2, this);
12059
12087
  this._beforeError(error2);
12060
12088
  });
12061
- this._unproxyEvents = proxyEvents(request, this, proxiedRequestEvents);
12062
- this._request = request;
12089
+ this._unproxyEvents = proxyEvents(request2, this, proxiedRequestEvents);
12090
+ this._request = request2;
12063
12091
  this.emit("uploadProgress", this.uploadProgress);
12064
12092
  this._sendBody();
12065
- this.emit("request", request);
12093
+ this.emit("request", request2);
12066
12094
  }
12067
12095
  async _asyncWrite(chunk) {
12068
- return new Promise((resolve, reject) => {
12096
+ return new Promise((resolve2, reject) => {
12069
12097
  super.write(chunk, (error2) => {
12070
12098
  if (error2) {
12071
12099
  reject(error2);
12072
12100
  return;
12073
12101
  }
12074
- resolve();
12102
+ resolve2();
12075
12103
  });
12076
12104
  });
12077
12105
  }
@@ -12115,8 +12143,8 @@ var init_core = __esm(() => {
12115
12143
  } else if (event === "abort") {
12116
12144
  (async () => {
12117
12145
  try {
12118
- const request = await result;
12119
- request.once("abort", handler2);
12146
+ const request2 = await result;
12147
+ request2.once("abort", handler2);
12120
12148
  } catch {}
12121
12149
  })();
12122
12150
  } else {
@@ -12131,12 +12159,12 @@ var init_core = __esm(() => {
12131
12159
  }
12132
12160
  }
12133
12161
  async _createCacheableRequest(url, options) {
12134
- return new Promise((resolve, reject) => {
12162
+ return new Promise((resolve2, reject) => {
12135
12163
  Object.assign(options, urlToOptions(url));
12136
- let request;
12164
+ let request2;
12137
12165
  const cacheRequest = cacheableStore.get(options.cache)(options, async (response) => {
12138
12166
  response._readableState.autoDestroy = false;
12139
- if (request) {
12167
+ if (request2) {
12140
12168
  const fix = () => {
12141
12169
  if (response.req) {
12142
12170
  response.complete = response.req.res.complete;
@@ -12144,14 +12172,14 @@ var init_core = __esm(() => {
12144
12172
  };
12145
12173
  response.prependOnceListener("end", fix);
12146
12174
  fix();
12147
- (await request).emit("cacheableResponse", response);
12175
+ (await request2).emit("cacheableResponse", response);
12148
12176
  }
12149
- resolve(response);
12177
+ resolve2(response);
12150
12178
  });
12151
12179
  cacheRequest.once("error", reject);
12152
12180
  cacheRequest.once("request", async (requestOrPromise) => {
12153
- request = requestOrPromise;
12154
- resolve(request);
12181
+ request2 = requestOrPromise;
12182
+ resolve2(request2);
12155
12183
  });
12156
12184
  });
12157
12185
  }
@@ -12180,26 +12208,26 @@ var init_core = __esm(() => {
12180
12208
  }
12181
12209
  }
12182
12210
  options.prefixUrl = "";
12183
- let request;
12211
+ let request2;
12184
12212
  for (const hook of options.hooks.beforeRequest) {
12185
12213
  const result = await hook(options);
12186
12214
  if (!dist_default.undefined(result)) {
12187
- request = () => result;
12215
+ request2 = () => result;
12188
12216
  break;
12189
12217
  }
12190
12218
  }
12191
- if (!request) {
12192
- request = options.getRequestFunction();
12219
+ if (!request2) {
12220
+ request2 = options.getRequestFunction();
12193
12221
  }
12194
12222
  const url = options.url;
12195
12223
  this._requestOptions = options.createNativeRequestOptions();
12196
12224
  if (options.cache) {
12197
- this._requestOptions._request = request;
12225
+ this._requestOptions._request = request2;
12198
12226
  this._requestOptions.cache = options.cache;
12199
12227
  this._requestOptions.body = options.body;
12200
12228
  this._prepareCache(options.cache);
12201
12229
  }
12202
- const fn = options.cache ? this._createCacheableRequest : request;
12230
+ const fn = options.cache ? this._createCacheableRequest : request2;
12203
12231
  try {
12204
12232
  let requestOrResponse = fn(url, this._requestOptions);
12205
12233
  if (dist_default.promise(requestOrResponse)) {
@@ -12311,8 +12339,8 @@ var CancelError2;
12311
12339
  var init_types3 = __esm(() => {
12312
12340
  init_errors2();
12313
12341
  CancelError2 = class CancelError2 extends RequestError {
12314
- constructor(request) {
12315
- super("Promise was canceled", {}, request);
12342
+ constructor(request2) {
12343
+ super("Promise was canceled", {}, request2);
12316
12344
  this.name = "CancelError";
12317
12345
  this.code = "ERR_CANCELED";
12318
12346
  }
@@ -12329,7 +12357,7 @@ function asPromise(firstRequest) {
12329
12357
  let globalResponse;
12330
12358
  let normalizedOptions;
12331
12359
  const emitter = new EventEmitter2;
12332
- const promise = new PCancelable((resolve, reject, onCancel) => {
12360
+ const promise = new PCancelable((resolve2, reject, onCancel) => {
12333
12361
  onCancel(() => {
12334
12362
  globalRequest.destroy();
12335
12363
  });
@@ -12339,14 +12367,14 @@ function asPromise(firstRequest) {
12339
12367
  });
12340
12368
  const makeRequest = (retryCount) => {
12341
12369
  onCancel(() => {});
12342
- const request = firstRequest ?? new Request(undefined, undefined, normalizedOptions);
12343
- request.retryCount = retryCount;
12344
- request._noPipe = true;
12345
- globalRequest = request;
12346
- request.once("response", async (response) => {
12370
+ const request2 = firstRequest ?? new Request(undefined, undefined, normalizedOptions);
12371
+ request2.retryCount = retryCount;
12372
+ request2._noPipe = true;
12373
+ globalRequest = request2;
12374
+ request2.once("response", async (response) => {
12347
12375
  const contentEncoding = (response.headers["content-encoding"] ?? "").toLowerCase();
12348
12376
  const isCompressed = contentEncoding === "gzip" || contentEncoding === "deflate" || contentEncoding === "br";
12349
- const { options } = request;
12377
+ const { options } = request2;
12350
12378
  if (isCompressed && !options.decompress) {
12351
12379
  response.body = response.rawBody;
12352
12380
  } else {
@@ -12355,7 +12383,7 @@ function asPromise(firstRequest) {
12355
12383
  } catch (error2) {
12356
12384
  response.body = response.rawBody.toString();
12357
12385
  if (isResponseOk(response)) {
12358
- request._beforeError(error2);
12386
+ request2._beforeError(error2);
12359
12387
  return;
12360
12388
  }
12361
12389
  }
@@ -12370,53 +12398,53 @@ function asPromise(firstRequest) {
12370
12398
  options.url = updatedOptions.url;
12371
12399
  }
12372
12400
  options.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
12373
- throw new RetryError(request);
12401
+ throw new RetryError(request2);
12374
12402
  });
12375
12403
  if (!(dist_default.object(response) && dist_default.number(response.statusCode) && !dist_default.nullOrUndefined(response.body))) {
12376
12404
  throw new TypeError("The `afterResponse` hook returned an invalid value");
12377
12405
  }
12378
12406
  }
12379
12407
  } catch (error2) {
12380
- request._beforeError(error2);
12408
+ request2._beforeError(error2);
12381
12409
  return;
12382
12410
  }
12383
12411
  globalResponse = response;
12384
12412
  if (!isResponseOk(response)) {
12385
- request._beforeError(new HTTPError(response));
12413
+ request2._beforeError(new HTTPError(response));
12386
12414
  return;
12387
12415
  }
12388
- request.destroy();
12389
- resolve(request.options.resolveBodyOnly ? response.body : response);
12416
+ request2.destroy();
12417
+ resolve2(request2.options.resolveBodyOnly ? response.body : response);
12390
12418
  });
12391
12419
  const onError = (error2) => {
12392
12420
  if (promise.isCanceled) {
12393
12421
  return;
12394
12422
  }
12395
- const { options } = request;
12423
+ const { options } = request2;
12396
12424
  if (error2 instanceof HTTPError && !options.throwHttpErrors) {
12397
12425
  const { response } = error2;
12398
- request.destroy();
12399
- resolve(request.options.resolveBodyOnly ? response.body : response);
12426
+ request2.destroy();
12427
+ resolve2(request2.options.resolveBodyOnly ? response.body : response);
12400
12428
  return;
12401
12429
  }
12402
12430
  reject(error2);
12403
12431
  };
12404
- request.once("error", onError);
12405
- const previousBody = request.options?.body;
12406
- request.once("retry", (newRetryCount, error2) => {
12432
+ request2.once("error", onError);
12433
+ const previousBody = request2.options?.body;
12434
+ request2.once("retry", (newRetryCount, error2) => {
12407
12435
  firstRequest = undefined;
12408
- const newBody = request.options.body;
12436
+ const newBody = request2.options.body;
12409
12437
  if (previousBody === newBody && dist_default.nodeStream(newBody)) {
12410
12438
  error2.message = "Cannot retry with consumed body stream";
12411
12439
  onError(error2);
12412
12440
  return;
12413
12441
  }
12414
- normalizedOptions = request.options;
12442
+ normalizedOptions = request2.options;
12415
12443
  makeRequest(newRetryCount);
12416
12444
  });
12417
- proxyEvents(request, emitter, proxiedRequestEvents2);
12445
+ proxyEvents(request2, emitter, proxiedRequestEvents2);
12418
12446
  if (dist_default.undefined(firstRequest)) {
12419
- request.flush();
12447
+ request2.flush();
12420
12448
  }
12421
12449
  };
12422
12450
  makeRequest(0);
@@ -12469,8 +12497,8 @@ var init_as_promise = __esm(() => {
12469
12497
  });
12470
12498
 
12471
12499
  // ../../node_modules/got/dist/source/create.js
12472
- var delay = async (ms) => new Promise((resolve) => {
12473
- setTimeout(resolve, ms);
12500
+ var delay = async (ms) => new Promise((resolve2) => {
12501
+ setTimeout(resolve2, ms);
12474
12502
  }), isGotInstance = (value) => dist_default.function_(value), aliases, create = (defaults) => {
12475
12503
  defaults = {
12476
12504
  options: new Options(undefined, undefined, defaults.options),
@@ -12483,17 +12511,17 @@ var delay = async (ms) => new Promise((resolve) => {
12483
12511
  writable: false
12484
12512
  });
12485
12513
  const got = (url, options, defaultOptions2 = defaults.options) => {
12486
- const request = new Request(url, options, defaultOptions2);
12514
+ const request2 = new Request(url, options, defaultOptions2);
12487
12515
  let promise;
12488
12516
  const lastHandler = (normalized) => {
12489
- request.options = normalized;
12490
- request._noPipe = !normalized.isStream;
12491
- request.flush();
12517
+ request2.options = normalized;
12518
+ request2._noPipe = !normalized.isStream;
12519
+ request2.flush();
12492
12520
  if (normalized.isStream) {
12493
- return request;
12521
+ return request2;
12494
12522
  }
12495
12523
  if (!promise) {
12496
- promise = asPromise(request);
12524
+ promise = asPromise(request2);
12497
12525
  }
12498
12526
  return promise;
12499
12527
  };
@@ -12501,9 +12529,9 @@ var delay = async (ms) => new Promise((resolve) => {
12501
12529
  const iterateHandlers = (newOptions) => {
12502
12530
  const handler = defaults.handlers[iteration++] ?? lastHandler;
12503
12531
  const result = handler(newOptions, iterateHandlers);
12504
- if (dist_default.promise(result) && !request.options.isStream) {
12532
+ if (dist_default.promise(result) && !request2.options.isStream) {
12505
12533
  if (!promise) {
12506
- promise = asPromise(request);
12534
+ promise = asPromise(request2);
12507
12535
  }
12508
12536
  if (result !== promise) {
12509
12537
  const descriptors = Object.getOwnPropertyDescriptors(promise);
@@ -12518,7 +12546,7 @@ var delay = async (ms) => new Promise((resolve) => {
12518
12546
  }
12519
12547
  return result;
12520
12548
  };
12521
- return iterateHandlers(request.options);
12549
+ return iterateHandlers(request2.options);
12522
12550
  };
12523
12551
  got.extend = (...instancesOrOptions) => {
12524
12552
  const options = new Options(undefined, undefined, defaults.options);
@@ -12699,9 +12727,9 @@ class StacksApiClient {
12699
12727
  async ensureProxy() {
12700
12728
  if (!this.useProxy || this.baseUrl)
12701
12729
  return;
12702
- const config = await loadConfig();
12703
- this.baseUrl = resolveApiUrl(config);
12704
- this.headers = authHeaders(config);
12730
+ const { apiUrl, ephemeralKey } = await resolveActiveTenant();
12731
+ this.baseUrl = apiUrl;
12732
+ this.headers = { authorization: `Bearer ${ephemeralKey}` };
12705
12733
  }
12706
12734
  async fetchWithErrorHandling(url, resourceType, resourceId) {
12707
12735
  try {
@@ -12741,8 +12769,7 @@ class StacksApiClient {
12741
12769
  var gotWithRetry;
12742
12770
  var init_api = __esm(() => {
12743
12771
  init_source3();
12744
- init_api_client();
12745
- init_config();
12772
+ init_resolve_tenant();
12746
12773
  gotWithRetry = source_default2.extend({
12747
12774
  timeout: { request: 30000 },
12748
12775
  retry: {
@@ -13151,11 +13178,11 @@ var init_manager = __esm(() => {
13151
13178
  });
13152
13179
 
13153
13180
  // src/services/indexer.ts
13154
- import { dirname, resolve as resolve2 } from "node:path";
13181
+ import { dirname as dirname3, resolve as resolve3 } from "node:path";
13155
13182
  async function startIndexer(options2) {
13156
13183
  const port = options2.port ?? 3700;
13157
- const rootDir = dirname(dirname(dirname(dirname(import.meta.dir))));
13158
- const indexerPath = resolve2(rootDir, "packages/indexer/src/index.ts");
13184
+ const rootDir = dirname3(dirname3(dirname3(dirname3(import.meta.dir))));
13185
+ const indexerPath = resolve3(rootDir, "packages/indexer/src/index.ts");
13159
13186
  await serviceManager.start(SERVICE_NAME, ["bun", "run", "--watch", indexerPath], {
13160
13187
  port,
13161
13188
  env: {
@@ -13171,10 +13198,10 @@ var init_indexer = __esm(() => {
13171
13198
  });
13172
13199
 
13173
13200
  // src/services/worker.ts
13174
- import { dirname as dirname2, resolve as resolve3 } from "node:path";
13201
+ import { dirname as dirname4, resolve as resolve4 } from "node:path";
13175
13202
  async function startWorker(options2) {
13176
- const rootDir = dirname2(dirname2(dirname2(dirname2(import.meta.dir))));
13177
- const workerPath = resolve3(rootDir, "packages/worker/src/index.ts");
13203
+ const rootDir = dirname4(dirname4(dirname4(dirname4(import.meta.dir))));
13204
+ const workerPath = resolve4(rootDir, "packages/worker/src/index.ts");
13178
13205
  await serviceManager.start(SERVICE_NAME2, ["bun", "run", "--watch", workerPath], {
13179
13206
  onStdout: options2.onLog,
13180
13207
  onStderr: options2.onLog
@@ -13186,11 +13213,11 @@ var init_worker = __esm(() => {
13186
13213
  });
13187
13214
 
13188
13215
  // src/services/api.ts
13189
- import { dirname as dirname3, resolve as resolve4 } from "node:path";
13216
+ import { dirname as dirname5, resolve as resolve5 } from "node:path";
13190
13217
  async function startApi(options2) {
13191
13218
  const port = options2.port ?? 3800;
13192
- const rootDir = dirname3(dirname3(dirname3(dirname3(import.meta.dir))));
13193
- const apiPath = resolve4(rootDir, "packages/api/src/index.ts");
13219
+ const rootDir = dirname5(dirname5(dirname5(dirname5(import.meta.dir))));
13220
+ const apiPath = resolve5(rootDir, "packages/api/src/index.ts");
13194
13221
  await serviceManager.start(SERVICE_NAME3, ["bun", "run", "--watch", apiPath], {
13195
13222
  port,
13196
13223
  env: {
@@ -13206,10 +13233,10 @@ var init_api2 = __esm(() => {
13206
13233
  });
13207
13234
 
13208
13235
  // src/services/subgraph-processor.ts
13209
- import { dirname as dirname4, resolve as resolve5 } from "node:path";
13236
+ import { dirname as dirname6, resolve as resolve6 } from "node:path";
13210
13237
  async function startSubgraphProcessor(options2) {
13211
- const rootDir = dirname4(dirname4(dirname4(dirname4(import.meta.dir))));
13212
- const servicePath = resolve5(rootDir, "packages/subgraphs/src/service.ts");
13238
+ const rootDir = dirname6(dirname6(dirname6(dirname6(import.meta.dir))));
13239
+ const servicePath = resolve6(rootDir, "packages/subgraphs/src/service.ts");
13213
13240
  await serviceManager.start(SERVICE_NAME4, ["bun", "run", "--watch", servicePath], {
13214
13241
  env: {
13215
13242
  SUBGRAPH_CONCURRENCY: String(options2.concurrency ?? 5)
@@ -13244,7 +13271,7 @@ __export(exports_dev_impl, {
13244
13271
  isDevAlreadyRunning: () => isDevAlreadyRunning
13245
13272
  });
13246
13273
  import { mkdirSync as mkdirSync2 } from "node:fs";
13247
- import { dirname as dirname5, join as join4, resolve as resolve6 } from "node:path";
13274
+ import { dirname as dirname7, join as join6, resolve as resolve7 } from "node:path";
13248
13275
  async function isDevAlreadyRunning() {
13249
13276
  if (await isDevRunning()) {
13250
13277
  const running = await getRunningServices();
@@ -13308,7 +13335,7 @@ async function runBackground(options2) {
13308
13335
  if (!databaseUrl) {
13309
13336
  info("Starting PostgreSQL container...");
13310
13337
  startedPostgres = await ensureDevPostgres(dataDir);
13311
- databaseUrl = DEV_DATABASE_URL3;
13338
+ databaseUrl = DEV_DATABASE_URL2;
13312
13339
  console.log(green(" ✓ PostgreSQL"), dim(`localhost:5432 (data: ${dataDir}/postgres)`));
13313
13340
  info("Running migrations...");
13314
13341
  await runMigrations(databaseUrl);
@@ -13322,10 +13349,10 @@ async function runBackground(options2) {
13322
13349
  startedAt: new Date().toISOString()
13323
13350
  };
13324
13351
  try {
13325
- const packagesDir = dirname5(dirname5(dirname5(dirname5(import.meta.dir))));
13352
+ const packagesDir = dirname7(dirname7(dirname7(dirname7(import.meta.dir))));
13326
13353
  const env = { DATABASE_URL: databaseUrl, DEV_MODE: "true" };
13327
13354
  const apiLogFile = getLogFile("api");
13328
- const apiProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/api/src/index.ts")], {
13355
+ const apiProc = Bun.spawn(["bun", "run", resolve7(packagesDir, "packages/api/src/index.ts")], {
13329
13356
  env: { ...process.env, ...env, PORT: String(apiPort) },
13330
13357
  stdout: Bun.file(apiLogFile),
13331
13358
  stderr: Bun.file(apiLogFile)
@@ -13338,7 +13365,7 @@ async function runBackground(options2) {
13338
13365
  };
13339
13366
  console.log(green(" ✓ API"), dim(`http://localhost:${apiPort}`));
13340
13367
  const indexerLogFile = getLogFile("indexer");
13341
- const indexerProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/indexer/src/index.ts")], {
13368
+ const indexerProc = Bun.spawn(["bun", "run", resolve7(packagesDir, "packages/indexer/src/index.ts")], {
13342
13369
  env: { ...process.env, ...env, PORT: String(indexerPort) },
13343
13370
  stdout: Bun.file(indexerLogFile),
13344
13371
  stderr: Bun.file(indexerLogFile)
@@ -13352,7 +13379,7 @@ async function runBackground(options2) {
13352
13379
  console.log(green(" ✓ Indexer"), dim(`http://localhost:${indexerPort}`));
13353
13380
  if (options2.worker) {
13354
13381
  const workerLogFile = getLogFile("worker");
13355
- const workerProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/worker/src/index.ts")], {
13382
+ const workerProc = Bun.spawn(["bun", "run", resolve7(packagesDir, "packages/worker/src/index.ts")], {
13356
13383
  env: { ...process.env, ...env },
13357
13384
  stdout: Bun.file(workerLogFile),
13358
13385
  stderr: Bun.file(workerLogFile)
@@ -13370,7 +13397,7 @@ async function runBackground(options2) {
13370
13397
  const subgraphsProc = Bun.spawn([
13371
13398
  "bun",
13372
13399
  "run",
13373
- resolve6(packagesDir, "packages/subgraphs/src/service.ts")
13400
+ resolve7(packagesDir, "packages/subgraphs/src/service.ts")
13374
13401
  ], {
13375
13402
  env: { ...process.env, ...env },
13376
13403
  stdout: Bun.file(subgraphsLogFile),
@@ -13470,7 +13497,7 @@ async function runForeground(options2) {
13470
13497
  if (!databaseUrl) {
13471
13498
  info("Starting PostgreSQL container...");
13472
13499
  devPostgresStarted = await ensureDevPostgres(dataDir);
13473
- databaseUrl = DEV_DATABASE_URL3;
13500
+ databaseUrl = DEV_DATABASE_URL2;
13474
13501
  process.env.DATABASE_URL = databaseUrl;
13475
13502
  console.log(green(" ✓ PostgreSQL"), dim(`localhost:5432 (data: ${dataDir}/postgres)`));
13476
13503
  info("Running migrations...");
@@ -13669,7 +13696,7 @@ async function restartDev() {
13669
13696
  await clearDevState();
13670
13697
  await clearLogs();
13671
13698
  const config = await loadConfig();
13672
- const packagesDir = dirname5(dirname5(dirname5(dirname5(import.meta.dir))));
13699
+ const packagesDir = dirname7(dirname7(dirname7(dirname7(import.meta.dir))));
13673
13700
  const env = state.env;
13674
13701
  const newState = {
13675
13702
  services: {},
@@ -13679,7 +13706,7 @@ async function restartDev() {
13679
13706
  };
13680
13707
  const apiPort = config.ports.api;
13681
13708
  const apiLogFile = getLogFile("api");
13682
- const apiProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/api/src/index.ts")], {
13709
+ const apiProc = Bun.spawn(["bun", "run", resolve7(packagesDir, "packages/api/src/index.ts")], {
13683
13710
  env: { ...process.env, ...env, PORT: String(apiPort) },
13684
13711
  stdout: Bun.file(apiLogFile),
13685
13712
  stderr: Bun.file(apiLogFile)
@@ -13693,7 +13720,7 @@ async function restartDev() {
13693
13720
  console.log(green(" ✓ API"), dim(`http://localhost:${apiPort}`));
13694
13721
  const indexerPort = config.ports.indexer;
13695
13722
  const indexerLogFile = getLogFile("indexer");
13696
- const indexerProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/indexer/src/index.ts")], {
13723
+ const indexerProc = Bun.spawn(["bun", "run", resolve7(packagesDir, "packages/indexer/src/index.ts")], {
13697
13724
  env: { ...process.env, ...env, PORT: String(indexerPort) },
13698
13725
  stdout: Bun.file(indexerLogFile),
13699
13726
  stderr: Bun.file(indexerLogFile)
@@ -13707,7 +13734,7 @@ async function restartDev() {
13707
13734
  console.log(green(" ✓ Indexer"), dim(`http://localhost:${indexerPort}`));
13708
13735
  if (state.services.worker) {
13709
13736
  const workerLogFile = getLogFile("worker");
13710
- const workerProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/worker/src/index.ts")], {
13737
+ const workerProc = Bun.spawn(["bun", "run", resolve7(packagesDir, "packages/worker/src/index.ts")], {
13711
13738
  env: { ...process.env, ...env },
13712
13739
  stdout: Bun.file(workerLogFile),
13713
13740
  stderr: Bun.file(workerLogFile)
@@ -13722,7 +13749,7 @@ async function restartDev() {
13722
13749
  }
13723
13750
  if (state.services.subgraphs) {
13724
13751
  const subgraphsLogFile = getLogFile("subgraphs");
13725
- const subgraphsProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/subgraphs/src/service.ts")], {
13752
+ const subgraphsProc = Bun.spawn(["bun", "run", resolve7(packagesDir, "packages/subgraphs/src/service.ts")], {
13726
13753
  env: { ...process.env, ...env },
13727
13754
  stdout: Bun.file(subgraphsLogFile),
13728
13755
  stderr: Bun.file(subgraphsLogFile)
@@ -13850,7 +13877,7 @@ async function ensureDevPostgres(dataDir) {
13850
13877
  if (check.stdout.toString().trim()) {
13851
13878
  return false;
13852
13879
  }
13853
- const pgDataDir = join4(dataDir, "postgres");
13880
+ const pgDataDir = join6(dataDir, "postgres");
13854
13881
  mkdirSync2(pgDataDir, { recursive: true });
13855
13882
  const stopped = await Bun.$`docker ps -aq -f name=secondlayer-dev-postgres`.quiet().nothrow();
13856
13883
  if (stopped.stdout.toString().trim()) {
@@ -13866,14 +13893,14 @@ async function ensureDevPostgres(dataDir) {
13866
13893
  throw new Error("PostgreSQL failed to start");
13867
13894
  }
13868
13895
  async function runMigrations(databaseUrl) {
13869
- const packagesDir = dirname5(dirname5(dirname5(dirname5(import.meta.dir))));
13870
- const migrateScript = resolve6(packagesDir, "packages/shared/src/db/migrate.ts");
13896
+ const packagesDir = dirname7(dirname7(dirname7(dirname7(import.meta.dir))));
13897
+ const migrateScript = resolve7(packagesDir, "packages/shared/src/db/migrate.ts");
13871
13898
  const result = await Bun.$`DATABASE_URL=${databaseUrl} bun run ${migrateScript}`.quiet().nothrow();
13872
13899
  if (result.exitCode !== 0) {
13873
13900
  throw new Error(`Migration failed: ${result.stderr.toString()}`);
13874
13901
  }
13875
13902
  }
13876
- var DEV_DATABASE_URL3 = "postgres://postgres:postgres@localhost:5432/secondlayer_dev", serviceColors;
13903
+ var DEV_DATABASE_URL2 = "postgres://postgres:postgres@localhost:5432/secondlayer_dev", serviceColors;
13877
13904
  var init_dev_impl = __esm(() => {
13878
13905
  init_config();
13879
13906
  init_dev_state();
@@ -13900,7 +13927,7 @@ __export(exports_node_impl, {
13900
13927
  runSetupWizard: () => runSetupWizard,
13901
13928
  restartNode: () => restartNode
13902
13929
  });
13903
- import { confirm as confirm4, input as input2, select as select2 } from "@inquirer/prompts";
13930
+ import { confirm as confirm3, input, select as select2 } from "@inquirer/prompts";
13904
13931
  async function runSetupWizard() {
13905
13932
  console.log("");
13906
13933
  console.log(blue("Stacks Node Setup Wizard"));
@@ -13918,7 +13945,7 @@ async function runSetupWizard() {
13918
13945
  }
13919
13946
  success("Docker is running");
13920
13947
  console.log("");
13921
- const installPath = await input2({
13948
+ const installPath = await input({
13922
13949
  message: "Where is stacks-blockchain-docker installed?",
13923
13950
  validate: async (value) => {
13924
13951
  if (!value.trim())
@@ -13937,18 +13964,18 @@ async function runSetupWizard() {
13937
13964
  ],
13938
13965
  default: "mainnet"
13939
13966
  });
13940
- const autoStartIndexer = await confirm4({
13967
+ const autoStartIndexer = await confirm3({
13941
13968
  message: "Auto-start indexer when node starts?",
13942
13969
  default: true
13943
13970
  });
13944
13971
  let indexerPort = 3700;
13945
13972
  if (autoStartIndexer) {
13946
- const customPort = await confirm4({
13973
+ const customPort = await confirm3({
13947
13974
  message: "Use default indexer port (3700)?",
13948
13975
  default: true
13949
13976
  });
13950
13977
  if (!customPort) {
13951
- const portInput = await input2({
13978
+ const portInput = await input({
13952
13979
  message: "Enter custom indexer port:",
13953
13980
  default: "3700",
13954
13981
  validate: (value) => {
@@ -14049,7 +14076,7 @@ async function stopNode(_pathOverride, force, _wait) {
14049
14076
  return;
14050
14077
  }
14051
14078
  if (!force) {
14052
- const proceed = await confirm4({
14079
+ const proceed = await confirm3({
14053
14080
  message: "Stop the Stacks node?",
14054
14081
  default: false
14055
14082
  });
@@ -14079,7 +14106,7 @@ async function restartNode(pathOverride, force, _wait) {
14079
14106
  const wasRunning = await isNodeRunning();
14080
14107
  if (wasRunning) {
14081
14108
  if (!force) {
14082
- const proceed = await confirm4({
14109
+ const proceed = await confirm3({
14083
14110
  message: "Restart the Stacks node?",
14084
14111
  default: false
14085
14112
  });
@@ -15429,8 +15456,8 @@ var require_fill_range = __commonJS((exports, module) => {
15429
15456
  return typeof value === "number" || typeof value === "string" && value !== "";
15430
15457
  };
15431
15458
  var isNumber = (num) => Number.isInteger(+num);
15432
- var zeros = (input3) => {
15433
- let value = `${input3}`;
15459
+ var zeros = (input5) => {
15460
+ let value = `${input5}`;
15434
15461
  let index = -1;
15435
15462
  if (value[0] === "-")
15436
15463
  value = value.slice(1);
@@ -15446,27 +15473,27 @@ var require_fill_range = __commonJS((exports, module) => {
15446
15473
  }
15447
15474
  return options2.stringify === true;
15448
15475
  };
15449
- var pad = (input3, maxLength, toNumber) => {
15476
+ var pad = (input5, maxLength, toNumber) => {
15450
15477
  if (maxLength > 0) {
15451
- let dash = input3[0] === "-" ? "-" : "";
15478
+ let dash = input5[0] === "-" ? "-" : "";
15452
15479
  if (dash)
15453
- input3 = input3.slice(1);
15454
- input3 = dash + input3.padStart(dash ? maxLength - 1 : maxLength, "0");
15480
+ input5 = input5.slice(1);
15481
+ input5 = dash + input5.padStart(dash ? maxLength - 1 : maxLength, "0");
15455
15482
  }
15456
15483
  if (toNumber === false) {
15457
- return String(input3);
15484
+ return String(input5);
15458
15485
  }
15459
- return input3;
15486
+ return input5;
15460
15487
  };
15461
- var toMaxLen = (input3, maxLength) => {
15462
- let negative = input3[0] === "-" ? "-" : "";
15488
+ var toMaxLen = (input5, maxLength) => {
15489
+ let negative = input5[0] === "-" ? "-" : "";
15463
15490
  if (negative) {
15464
- input3 = input3.slice(1);
15491
+ input5 = input5.slice(1);
15465
15492
  maxLength--;
15466
15493
  }
15467
- while (input3.length < maxLength)
15468
- input3 = "0" + input3;
15469
- return negative ? "-" + input3 : input3;
15494
+ while (input5.length < maxLength)
15495
+ input5 = "0" + input5;
15496
+ return negative ? "-" + input5 : input5;
15470
15497
  };
15471
15498
  var toSequence = (parts, options2, maxLen) => {
15472
15499
  parts.negatives.sort((a, b2) => a < b2 ? -1 : a > b2 ? 1 : 0);
@@ -15835,25 +15862,25 @@ var require_parse = __commonJS((exports, module) => {
15835
15862
  CHAR_NO_BREAK_SPACE,
15836
15863
  CHAR_ZERO_WIDTH_NOBREAK_SPACE
15837
15864
  } = require_constants();
15838
- var parse2 = (input3, options2 = {}) => {
15839
- if (typeof input3 !== "string") {
15865
+ var parse2 = (input5, options2 = {}) => {
15866
+ if (typeof input5 !== "string") {
15840
15867
  throw new TypeError("Expected a string");
15841
15868
  }
15842
15869
  const opts = options2 || {};
15843
15870
  const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
15844
- if (input3.length > max) {
15845
- throw new SyntaxError(`Input length (${input3.length}), exceeds max characters (${max})`);
15871
+ if (input5.length > max) {
15872
+ throw new SyntaxError(`Input length (${input5.length}), exceeds max characters (${max})`);
15846
15873
  }
15847
- const ast = { type: "root", input: input3, nodes: [] };
15874
+ const ast = { type: "root", input: input5, nodes: [] };
15848
15875
  const stack = [ast];
15849
15876
  let block = ast;
15850
15877
  let prev = ast;
15851
15878
  let brackets = 0;
15852
- const length = input3.length;
15879
+ const length = input5.length;
15853
15880
  let index = 0;
15854
15881
  let depth = 0;
15855
15882
  let value;
15856
- const advance = () => input3[index++];
15883
+ const advance = () => input5[index++];
15857
15884
  const push = (node) => {
15858
15885
  if (node.type === "text" && prev.type === "dot") {
15859
15886
  prev.type = "text";
@@ -16048,10 +16075,10 @@ var require_braces = __commonJS((exports, module) => {
16048
16075
  var compile = require_compile();
16049
16076
  var expand = require_expand();
16050
16077
  var parse2 = require_parse();
16051
- var braces = (input3, options2 = {}) => {
16078
+ var braces = (input5, options2 = {}) => {
16052
16079
  let output = [];
16053
- if (Array.isArray(input3)) {
16054
- for (const pattern of input3) {
16080
+ if (Array.isArray(input5)) {
16081
+ for (const pattern of input5) {
16055
16082
  const result = braces.create(pattern, options2);
16056
16083
  if (Array.isArray(result)) {
16057
16084
  output.push(...result);
@@ -16060,31 +16087,31 @@ var require_braces = __commonJS((exports, module) => {
16060
16087
  }
16061
16088
  }
16062
16089
  } else {
16063
- output = [].concat(braces.create(input3, options2));
16090
+ output = [].concat(braces.create(input5, options2));
16064
16091
  }
16065
16092
  if (options2 && options2.expand === true && options2.nodupes === true) {
16066
16093
  output = [...new Set(output)];
16067
16094
  }
16068
16095
  return output;
16069
16096
  };
16070
- braces.parse = (input3, options2 = {}) => parse2(input3, options2);
16071
- braces.stringify = (input3, options2 = {}) => {
16072
- if (typeof input3 === "string") {
16073
- return stringify2(braces.parse(input3, options2), options2);
16097
+ braces.parse = (input5, options2 = {}) => parse2(input5, options2);
16098
+ braces.stringify = (input5, options2 = {}) => {
16099
+ if (typeof input5 === "string") {
16100
+ return stringify2(braces.parse(input5, options2), options2);
16074
16101
  }
16075
- return stringify2(input3, options2);
16102
+ return stringify2(input5, options2);
16076
16103
  };
16077
- braces.compile = (input3, options2 = {}) => {
16078
- if (typeof input3 === "string") {
16079
- input3 = braces.parse(input3, options2);
16104
+ braces.compile = (input5, options2 = {}) => {
16105
+ if (typeof input5 === "string") {
16106
+ input5 = braces.parse(input5, options2);
16080
16107
  }
16081
- return compile(input3, options2);
16108
+ return compile(input5, options2);
16082
16109
  };
16083
- braces.expand = (input3, options2 = {}) => {
16084
- if (typeof input3 === "string") {
16085
- input3 = braces.parse(input3, options2);
16110
+ braces.expand = (input5, options2 = {}) => {
16111
+ if (typeof input5 === "string") {
16112
+ input5 = braces.parse(input5, options2);
16086
16113
  }
16087
- let result = expand(input3, options2);
16114
+ let result = expand(input5, options2);
16088
16115
  if (options2.noempty === true) {
16089
16116
  result = result.filter(Boolean);
16090
16117
  }
@@ -16093,11 +16120,11 @@ var require_braces = __commonJS((exports, module) => {
16093
16120
  }
16094
16121
  return result;
16095
16122
  };
16096
- braces.create = (input3, options2 = {}) => {
16097
- if (input3 === "" || input3.length < 3) {
16098
- return [input3];
16123
+ braces.create = (input5, options2 = {}) => {
16124
+ if (input5 === "" || input5.length < 3) {
16125
+ return [input5];
16099
16126
  }
16100
- return options2.expand !== true ? braces.compile(input3, options2) : braces.expand(input3, options2);
16127
+ return options2.expand !== true ? braces.compile(input5, options2) : braces.expand(input5, options2);
16101
16128
  };
16102
16129
  module.exports = braces;
16103
16130
  });
@@ -16275,26 +16302,26 @@ var require_utils2 = __commonJS((exports) => {
16275
16302
  }
16276
16303
  return win32 === true || path.sep === "\\";
16277
16304
  };
16278
- exports.escapeLast = (input3, char, lastIdx) => {
16279
- const idx = input3.lastIndexOf(char, lastIdx);
16305
+ exports.escapeLast = (input5, char, lastIdx) => {
16306
+ const idx = input5.lastIndexOf(char, lastIdx);
16280
16307
  if (idx === -1)
16281
- return input3;
16282
- if (input3[idx - 1] === "\\")
16283
- return exports.escapeLast(input3, char, idx - 1);
16284
- return `${input3.slice(0, idx)}\\${input3.slice(idx)}`;
16308
+ return input5;
16309
+ if (input5[idx - 1] === "\\")
16310
+ return exports.escapeLast(input5, char, idx - 1);
16311
+ return `${input5.slice(0, idx)}\\${input5.slice(idx)}`;
16285
16312
  };
16286
- exports.removePrefix = (input3, state = {}) => {
16287
- let output = input3;
16313
+ exports.removePrefix = (input5, state = {}) => {
16314
+ let output = input5;
16288
16315
  if (output.startsWith("./")) {
16289
16316
  output = output.slice(2);
16290
16317
  state.prefix = "./";
16291
16318
  }
16292
16319
  return output;
16293
16320
  };
16294
- exports.wrapOutput = (input3, state = {}, options2 = {}) => {
16321
+ exports.wrapOutput = (input5, state = {}, options2 = {}) => {
16295
16322
  const prepend = options2.contains ? "" : "^";
16296
16323
  const append = options2.contains ? "" : "$";
16297
- let output = `${prepend}(?:${input3})${append}`;
16324
+ let output = `${prepend}(?:${input5})${append}`;
16298
16325
  if (state.negated === true) {
16299
16326
  output = `(?:^(?!${output}).*$)`;
16300
16327
  }
@@ -16330,14 +16357,14 @@ var require_scan = __commonJS((exports, module) => {
16330
16357
  token.depth = token.isGlobstar ? Infinity : 1;
16331
16358
  }
16332
16359
  };
16333
- var scan = (input3, options2) => {
16360
+ var scan = (input5, options2) => {
16334
16361
  const opts = options2 || {};
16335
- const length = input3.length - 1;
16362
+ const length = input5.length - 1;
16336
16363
  const scanToEnd = opts.parts === true || opts.scanToEnd === true;
16337
16364
  const slashes = [];
16338
16365
  const tokens = [];
16339
16366
  const parts = [];
16340
- let str = input3;
16367
+ let str = input5;
16341
16368
  let index = -1;
16342
16369
  let start = 0;
16343
16370
  let lastIndex = 0;
@@ -16560,7 +16587,7 @@ var require_scan = __commonJS((exports, module) => {
16560
16587
  }
16561
16588
  const state = {
16562
16589
  prefix,
16563
- input: input3,
16590
+ input: input5,
16564
16591
  start,
16565
16592
  base,
16566
16593
  glob,
@@ -16584,7 +16611,7 @@ var require_scan = __commonJS((exports, module) => {
16584
16611
  for (let idx = 0;idx < slashes.length; idx++) {
16585
16612
  const n = prevIndex ? prevIndex + 1 : start;
16586
16613
  const i = slashes[idx];
16587
- const value = input3.slice(n, i);
16614
+ const value = input5.slice(n, i);
16588
16615
  if (opts.tokens) {
16589
16616
  if (idx === 0 && start !== 0) {
16590
16617
  tokens[idx].isPrefix = true;
@@ -16600,8 +16627,8 @@ var require_scan = __commonJS((exports, module) => {
16600
16627
  }
16601
16628
  prevIndex = i;
16602
16629
  }
16603
- if (prevIndex && prevIndex + 1 < input3.length) {
16604
- const value = input3.slice(prevIndex + 1);
16630
+ if (prevIndex && prevIndex + 1 < input5.length) {
16631
+ const value = input5.slice(prevIndex + 1);
16605
16632
  parts.push(value);
16606
16633
  if (opts.tokens) {
16607
16634
  tokens[tokens.length - 1].value = value;
@@ -16644,14 +16671,14 @@ var require_parse2 = __commonJS((exports, module) => {
16644
16671
  var syntaxError = (type, char) => {
16645
16672
  return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
16646
16673
  };
16647
- var parse2 = (input3, options2) => {
16648
- if (typeof input3 !== "string") {
16674
+ var parse2 = (input5, options2) => {
16675
+ if (typeof input5 !== "string") {
16649
16676
  throw new TypeError("Expected a string");
16650
16677
  }
16651
- input3 = REPLACEMENTS[input3] || input3;
16678
+ input5 = REPLACEMENTS[input5] || input5;
16652
16679
  const opts = { ...options2 };
16653
16680
  const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
16654
- let len = input3.length;
16681
+ let len = input5.length;
16655
16682
  if (len > max) {
16656
16683
  throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
16657
16684
  }
@@ -16688,7 +16715,7 @@ var require_parse2 = __commonJS((exports, module) => {
16688
16715
  opts.noextglob = opts.noext;
16689
16716
  }
16690
16717
  const state = {
16691
- input: input3,
16718
+ input: input5,
16692
16719
  index: -1,
16693
16720
  start: 0,
16694
16721
  dot: opts.dot === true,
@@ -16704,17 +16731,17 @@ var require_parse2 = __commonJS((exports, module) => {
16704
16731
  globstar: false,
16705
16732
  tokens
16706
16733
  };
16707
- input3 = utils.removePrefix(input3, state);
16708
- len = input3.length;
16734
+ input5 = utils.removePrefix(input5, state);
16735
+ len = input5.length;
16709
16736
  const extglobs = [];
16710
16737
  const braces = [];
16711
16738
  const stack = [];
16712
16739
  let prev = bos;
16713
16740
  let value;
16714
16741
  const eos = () => state.index === len - 1;
16715
- const peek = state.peek = (n = 1) => input3[state.index + n];
16716
- const advance = state.advance = () => input3[++state.index] || "";
16717
- const remaining = () => input3.slice(state.index + 1);
16742
+ const peek = state.peek = (n = 1) => input5[state.index + n];
16743
+ const advance = state.advance = () => input5[++state.index] || "";
16744
+ const remaining = () => input5.slice(state.index + 1);
16718
16745
  const consume = (value2 = "", num = 0) => {
16719
16746
  state.consumed += value2;
16720
16747
  state.index += num;
@@ -16804,9 +16831,9 @@ var require_parse2 = __commonJS((exports, module) => {
16804
16831
  push({ type: "paren", extglob: true, value, output });
16805
16832
  decrement("parens");
16806
16833
  };
16807
- if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input3)) {
16834
+ if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input5)) {
16808
16835
  let backslashes = false;
16809
- let output = input3.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
16836
+ let output = input5.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
16810
16837
  if (first === "\\") {
16811
16838
  backslashes = true;
16812
16839
  return m;
@@ -16840,8 +16867,8 @@ var require_parse2 = __commonJS((exports, module) => {
16840
16867
  });
16841
16868
  }
16842
16869
  }
16843
- if (output === input3 && opts.contains === true) {
16844
- state.output = input3;
16870
+ if (output === input5 && opts.contains === true) {
16871
+ state.output = input5;
16845
16872
  return state;
16846
16873
  }
16847
16874
  state.output = utils.wrapOutput(output, state, options2);
@@ -17200,7 +17227,7 @@ var require_parse2 = __commonJS((exports, module) => {
17200
17227
  continue;
17201
17228
  }
17202
17229
  while (rest.slice(0, 3) === "/**") {
17203
- const after = input3[state.index + 4];
17230
+ const after = input5[state.index + 4];
17204
17231
  if (after && after !== "/") {
17205
17232
  break;
17206
17233
  }
@@ -17323,14 +17350,14 @@ var require_parse2 = __commonJS((exports, module) => {
17323
17350
  }
17324
17351
  return state;
17325
17352
  };
17326
- parse2.fastpaths = (input3, options2) => {
17353
+ parse2.fastpaths = (input5, options2) => {
17327
17354
  const opts = { ...options2 };
17328
17355
  const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
17329
- const len = input3.length;
17356
+ const len = input5.length;
17330
17357
  if (len > max) {
17331
17358
  throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
17332
17359
  }
17333
- input3 = REPLACEMENTS[input3] || input3;
17360
+ input5 = REPLACEMENTS[input5] || input5;
17334
17361
  const win32 = utils.isWindows(options2);
17335
17362
  const {
17336
17363
  DOT_LITERAL,
@@ -17385,7 +17412,7 @@ var require_parse2 = __commonJS((exports, module) => {
17385
17412
  }
17386
17413
  }
17387
17414
  };
17388
- const output = utils.removePrefix(input3, state);
17415
+ const output = utils.removePrefix(input5, state);
17389
17416
  let source = create2(output);
17390
17417
  if (source && opts.strictSlashes !== true) {
17391
17418
  source += `${SLASH_LITERAL}?`;
@@ -17405,7 +17432,7 @@ var require_picomatch = __commonJS((exports, module) => {
17405
17432
  var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
17406
17433
  var picomatch = (glob, options2, returnState = false) => {
17407
17434
  if (Array.isArray(glob)) {
17408
- const fns = glob.map((input3) => picomatch(input3, options2, returnState));
17435
+ const fns = glob.map((input5) => picomatch(input5, options2, returnState));
17409
17436
  const arrayMatcher = (str) => {
17410
17437
  for (const isMatch of fns) {
17411
17438
  const state2 = isMatch(str);
@@ -17430,9 +17457,9 @@ var require_picomatch = __commonJS((exports, module) => {
17430
17457
  const ignoreOpts = { ...options2, ignore: null, onMatch: null, onResult: null };
17431
17458
  isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
17432
17459
  }
17433
- const matcher = (input3, returnObject = false) => {
17434
- const { isMatch, match, output } = picomatch.test(input3, regex, options2, { glob, posix });
17435
- const result = { glob, state, regex, posix, input: input3, output, match, isMatch };
17460
+ const matcher = (input5, returnObject = false) => {
17461
+ const { isMatch, match, output } = picomatch.test(input5, regex, options2, { glob, posix });
17462
+ const result = { glob, state, regex, posix, input: input5, output, match, isMatch };
17436
17463
  if (typeof opts.onResult === "function") {
17437
17464
  opts.onResult(result);
17438
17465
  }
@@ -17440,7 +17467,7 @@ var require_picomatch = __commonJS((exports, module) => {
17440
17467
  result.isMatch = false;
17441
17468
  return returnObject ? result : false;
17442
17469
  }
17443
- if (isIgnored(input3)) {
17470
+ if (isIgnored(input5)) {
17444
17471
  if (typeof opts.onIgnore === "function") {
17445
17472
  opts.onIgnore(result);
17446
17473
  }
@@ -17457,33 +17484,33 @@ var require_picomatch = __commonJS((exports, module) => {
17457
17484
  }
17458
17485
  return matcher;
17459
17486
  };
17460
- picomatch.test = (input3, regex, options2, { glob, posix } = {}) => {
17461
- if (typeof input3 !== "string") {
17487
+ picomatch.test = (input5, regex, options2, { glob, posix } = {}) => {
17488
+ if (typeof input5 !== "string") {
17462
17489
  throw new TypeError("Expected input to be a string");
17463
17490
  }
17464
- if (input3 === "") {
17491
+ if (input5 === "") {
17465
17492
  return { isMatch: false, output: "" };
17466
17493
  }
17467
17494
  const opts = options2 || {};
17468
17495
  const format = opts.format || (posix ? utils.toPosixSlashes : null);
17469
- let match = input3 === glob;
17470
- let output = match && format ? format(input3) : input3;
17496
+ let match = input5 === glob;
17497
+ let output = match && format ? format(input5) : input5;
17471
17498
  if (match === false) {
17472
- output = format ? format(input3) : input3;
17499
+ output = format ? format(input5) : input5;
17473
17500
  match = output === glob;
17474
17501
  }
17475
17502
  if (match === false || opts.capture === true) {
17476
17503
  if (opts.matchBase === true || opts.basename === true) {
17477
- match = picomatch.matchBase(input3, regex, options2, posix);
17504
+ match = picomatch.matchBase(input5, regex, options2, posix);
17478
17505
  } else {
17479
17506
  match = regex.exec(output);
17480
17507
  }
17481
17508
  }
17482
17509
  return { isMatch: Boolean(match), match, output };
17483
17510
  };
17484
- picomatch.matchBase = (input3, glob, options2, posix = utils.isWindows(options2)) => {
17511
+ picomatch.matchBase = (input5, glob, options2, posix = utils.isWindows(options2)) => {
17485
17512
  const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options2);
17486
- return regex.test(path.basename(input3));
17513
+ return regex.test(path.basename(input5));
17487
17514
  };
17488
17515
  picomatch.isMatch = (str, patterns, options2) => picomatch(patterns, options2)(str);
17489
17516
  picomatch.parse = (pattern, options2) => {
@@ -17491,7 +17518,7 @@ var require_picomatch = __commonJS((exports, module) => {
17491
17518
  return pattern.map((p) => picomatch.parse(p, options2));
17492
17519
  return parse2(pattern, { ...options2, fastpaths: false });
17493
17520
  };
17494
- picomatch.scan = (input3, options2) => scan(input3, options2);
17521
+ picomatch.scan = (input5, options2) => scan(input5, options2);
17495
17522
  picomatch.compileRe = (state, options2, returnOutput = false, returnState = false) => {
17496
17523
  if (returnOutput === true) {
17497
17524
  return state.output;
@@ -17509,16 +17536,16 @@ var require_picomatch = __commonJS((exports, module) => {
17509
17536
  }
17510
17537
  return regex;
17511
17538
  };
17512
- picomatch.makeRe = (input3, options2 = {}, returnOutput = false, returnState = false) => {
17513
- if (!input3 || typeof input3 !== "string") {
17539
+ picomatch.makeRe = (input5, options2 = {}, returnOutput = false, returnState = false) => {
17540
+ if (!input5 || typeof input5 !== "string") {
17514
17541
  throw new TypeError("Expected a non-empty string");
17515
17542
  }
17516
17543
  let parsed = { negated: false, fastpaths: true };
17517
- if (options2.fastpaths !== false && (input3[0] === "." || input3[0] === "*")) {
17518
- parsed.output = parse2.fastpaths(input3, options2);
17544
+ if (options2.fastpaths !== false && (input5[0] === "." || input5[0] === "*")) {
17545
+ parsed.output = parse2.fastpaths(input5, options2);
17519
17546
  }
17520
17547
  if (!parsed.output) {
17521
- parsed = parse2(input3, options2);
17548
+ parsed = parse2(input5, options2);
17522
17549
  }
17523
17550
  return picomatch.compileRe(parsed, options2, returnOutput, returnState);
17524
17551
  };
@@ -17664,10 +17691,10 @@ var require_micromatch = __commonJS((exports, module) => {
17664
17691
  }
17665
17692
  return [].concat(patterns).every((p) => picomatch(p, options2)(str));
17666
17693
  };
17667
- micromatch.capture = (glob, input3, options2) => {
17694
+ micromatch.capture = (glob, input5, options2) => {
17668
17695
  let posix = utils.isWindows(options2);
17669
17696
  let regex = picomatch.makeRe(String(glob), { ...options2, capture: true });
17670
- let match = regex.exec(posix ? utils.toPosixSlashes(input3) : input3);
17697
+ let match = regex.exec(posix ? utils.toPosixSlashes(input5) : input5);
17671
17698
  if (match) {
17672
17699
  return match.slice(1).map((v) => v === undefined ? "" : v);
17673
17700
  }
@@ -18002,12 +18029,12 @@ var require_stream = __commonJS((exports) => {
18002
18029
  var require_string = __commonJS((exports) => {
18003
18030
  Object.defineProperty(exports, "__esModule", { value: true });
18004
18031
  exports.isEmpty = exports.isString = undefined;
18005
- function isString(input3) {
18006
- return typeof input3 === "string";
18032
+ function isString(input5) {
18033
+ return typeof input5 === "string";
18007
18034
  }
18008
18035
  exports.isString = isString;
18009
- function isEmpty(input3) {
18010
- return input3 === "";
18036
+ function isEmpty(input5) {
18037
+ return input5 === "";
18011
18038
  }
18012
18039
  exports.isEmpty = isEmpty;
18013
18040
  });
@@ -18037,8 +18064,8 @@ var require_tasks = __commonJS((exports) => {
18037
18064
  Object.defineProperty(exports, "__esModule", { value: true });
18038
18065
  exports.convertPatternGroupToTask = exports.convertPatternGroupsToTasks = exports.groupPatternsByBaseDirectory = exports.getNegativePatternsAsPositive = exports.getPositivePatterns = exports.convertPatternsToTasks = exports.generate = undefined;
18039
18066
  var utils = require_utils3();
18040
- function generate(input3, settings) {
18041
- const patterns = processPatterns(input3, settings);
18067
+ function generate(input5, settings) {
18068
+ const patterns = processPatterns(input5, settings);
18042
18069
  const ignore = processPatterns(settings.ignore, settings);
18043
18070
  const positivePatterns = getPositivePatterns(patterns);
18044
18071
  const negativePatterns = getNegativePatternsAsPositive(patterns, ignore);
@@ -18049,8 +18076,8 @@ var require_tasks = __commonJS((exports) => {
18049
18076
  return staticTasks.concat(dynamicTasks);
18050
18077
  }
18051
18078
  exports.generate = generate;
18052
- function processPatterns(input3, settings) {
18053
- let patterns = input3;
18079
+ function processPatterns(input5, settings) {
18080
+ let patterns = input5;
18054
18081
  if (settings.braceExpansion) {
18055
18082
  patterns = utils.pattern.expandPatternsWithBraceExpansion(patterns);
18056
18083
  }
@@ -20006,8 +20033,8 @@ var require_out4 = __commonJS((exports, module) => {
20006
20033
  const provider = new _Provider(settings);
20007
20034
  return tasks.map(provider.read, provider);
20008
20035
  }
20009
- function assertPatternsInput(input3) {
20010
- const source = [].concat(input3);
20036
+ function assertPatternsInput(input5) {
20037
+ const source = [].concat(input5);
20011
20038
  const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item));
20012
20039
  if (!isValidSource) {
20013
20040
  throw new TypeError("Patterns must be a string (non empty) or an array of strings");
@@ -21126,7 +21153,7 @@ var l, u, d, f, p, m, h = (e2, t2) => () => (t2 || e2((t2 = { exports: {} }).exp
21126
21153
  t3.on("end", r2);
21127
21154
  }
21128
21155
  return n2;
21129
- }, T, E, D, O, k, A, j, M, N, P, F, I, L, R, z2, B, V, G, K = (e2, t2, n2) => {
21156
+ }, T, E, D, O, k, A, j, M, N, P, F, I, L, R, z4, B, V, G, K = (e2, t2, n2) => {
21130
21157
  const r2 = new G(e2, t2, n2);
21131
21158
  r2.spawn();
21132
21159
  return r2;
@@ -21555,7 +21582,7 @@ var init_main = __esm(() => {
21555
21582
  t2.exports._enoent = i2;
21556
21583
  });
21557
21584
  R = _(L(), 1);
21558
- z2 = class extends Error {
21585
+ z4 = class extends Error {
21559
21586
  result;
21560
21587
  output;
21561
21588
  get exitCode() {
@@ -21638,7 +21665,7 @@ var init_main = __esm(() => {
21638
21665
  if (this._thrownError)
21639
21666
  throw this._thrownError;
21640
21667
  if (this._options?.throwOnError && this.exitCode !== 0 && this.exitCode !== undefined)
21641
- throw new z2(this);
21668
+ throw new z4(this);
21642
21669
  }
21643
21670
  async _waitForOutput() {
21644
21671
  const e2 = this._process;
@@ -21657,7 +21684,7 @@ var init_main = __esm(() => {
21657
21684
  exitCode: this.exitCode
21658
21685
  };
21659
21686
  if (this._options.throwOnError && this.exitCode !== 0 && this.exitCode !== undefined)
21660
- throw new z2(this, r2);
21687
+ throw new z4(this, r2);
21661
21688
  return r2;
21662
21689
  }
21663
21690
  then(e2, t2) {
@@ -21853,7 +21880,7 @@ var init_commands = __esm(() => {
21853
21880
  });
21854
21881
 
21855
21882
  // ../../node_modules/@antfu/ni/dist/shared/ni.B5qNAuoI.mjs
21856
- import path3, { join as join5, dirname as dirname6, resolve as resolve8 } from "node:path";
21883
+ import path3, { join as join7, dirname as dirname8, resolve as resolve8 } from "node:path";
21857
21884
  import process$1 from "node:process";
21858
21885
  import require$$0 from "readline";
21859
21886
  import require$$2 from "events";
@@ -22375,10 +22402,10 @@ function requireStyle() {
22375
22402
  const c2 = requireKleur();
22376
22403
  const figures = requireFigures();
22377
22404
  const styles3 = Object.freeze({
22378
- password: { scale: 1, render: (input3) => "*".repeat(input3.length) },
22379
- emoji: { scale: 2, render: (input3) => "\uD83D\uDE03".repeat(input3.length) },
22380
- invisible: { scale: 0, render: (input3) => "" },
22381
- default: { scale: 1, render: (input3) => `${input3}` }
22405
+ password: { scale: 1, render: (input5) => "*".repeat(input5.length) },
22406
+ emoji: { scale: 2, render: (input5) => "\uD83D\uDE03".repeat(input5.length) },
22407
+ invisible: { scale: 0, render: (input5) => "" },
22408
+ default: { scale: 1, render: (input5) => `${input5}` }
22382
22409
  });
22383
22410
  const render = (type) => styles3[type] || styles3.default;
22384
22411
  const symbols = Object.freeze({
@@ -22718,7 +22745,7 @@ ${i2 ? " " : figures.pointerSmall} ${color.red().italic(l2)}`, ``);
22718
22745
  }
22719
22746
  function requireSelect() {
22720
22747
  if (hasRequiredSelect)
22721
- return select3;
22748
+ return select4;
22722
22749
  hasRequiredSelect = 1;
22723
22750
  const color = requireKleur();
22724
22751
  const Prompt = requirePrompt();
@@ -22864,8 +22891,8 @@ function requireSelect() {
22864
22891
  this.out.write(this.outputText);
22865
22892
  }
22866
22893
  }
22867
- select3 = SelectPrompt;
22868
- return select3;
22894
+ select4 = SelectPrompt;
22895
+ return select4;
22869
22896
  }
22870
22897
  function requireToggle() {
22871
22898
  if (hasRequiredToggle)
@@ -24386,7 +24413,7 @@ function requirePrompts$1() {
24386
24413
  onSubmit: toSelected
24387
24414
  });
24388
24415
  };
24389
- const byTitle = (input3, choices) => Promise.resolve(choices.filter((item) => item.title.slice(0, input3.length).toLowerCase() === input3.toLowerCase()));
24416
+ const byTitle = (input5, choices) => Promise.resolve(choices.filter((item) => item.title.slice(0, input5.length).toLowerCase() === input5.toLowerCase()));
24390
24417
  $.autocomplete = (args) => {
24391
24418
  args.suggest = args.suggest || byTitle;
24392
24419
  args.choices = [].concat(args.choices || []);
@@ -24868,7 +24895,7 @@ function requireLib() {
24868
24895
  return lib;
24869
24896
  hasRequiredLib = 1;
24870
24897
  const { isexe, sync: isexeSync } = requireCjs();
24871
- const { join: join6, delimiter, sep, posix: posix2 } = require$$1$2;
24898
+ const { join: join8, delimiter, sep, posix: posix2 } = require$$1$2;
24872
24899
  const isWindows = process.platform === "win32";
24873
24900
  const rSlash = new RegExp(`[${posix2.sep}${sep === posix2.sep ? "" : sep}]`.replace(/(\\)/g, "\\$1"));
24874
24901
  const rRel = new RegExp(`^\\.${rSlash.source}`);
@@ -24895,7 +24922,7 @@ function requireLib() {
24895
24922
  const getPathPart = (raw, cmd) => {
24896
24923
  const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
24897
24924
  const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
24898
- return prefix + join6(pathPart, cmd);
24925
+ return prefix + join8(pathPart, cmd);
24899
24926
  };
24900
24927
  const which = async (cmd, opt = {}) => {
24901
24928
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
@@ -24991,7 +25018,7 @@ async function detect2({ autoInstall, programmatic, cwd } = {}) {
24991
25018
  }
24992
25019
  return agent;
24993
25020
  }
24994
- var ini$1, hasRequiredIni, iniExports, prompts$2, kleur, hasRequiredKleur, action, hasRequiredAction, strip, hasRequiredStrip, src, hasRequiredSrc, clear, hasRequiredClear, figures_1, hasRequiredFigures, style, hasRequiredStyle, lines, hasRequiredLines, wrap, hasRequiredWrap, entriesToDisplay, hasRequiredEntriesToDisplay, util, hasRequiredUtil, prompt, hasRequiredPrompt, text, hasRequiredText, select3, hasRequiredSelect, toggle, hasRequiredToggle, datepart, hasRequiredDatepart, meridiem, hasRequiredMeridiem, day, hasRequiredDay, hours, hasRequiredHours, milliseconds, hasRequiredMilliseconds, minutes, hasRequiredMinutes, month, hasRequiredMonth, seconds, hasRequiredSeconds, year, hasRequiredYear, dateparts, hasRequiredDateparts, date, hasRequiredDate, number, hasRequiredNumber, multiselect, hasRequiredMultiselect, autocomplete, hasRequiredAutocomplete, autocompleteMultiselect, hasRequiredAutocompleteMultiselect, confirm5, hasRequiredConfirm, elements, hasRequiredElements, hasRequiredPrompts$1, lib$1, hasRequiredLib$1, prompts$1, hasRequiredPrompts, promptsExports, prompts, isBrowser, platform, OSC = "\x1B]", BEL = "\x07", SEP = ";", link = (text2, url) => [
25021
+ var ini$1, hasRequiredIni, iniExports, prompts$2, kleur, hasRequiredKleur, action, hasRequiredAction, strip, hasRequiredStrip, src, hasRequiredSrc, clear, hasRequiredClear, figures_1, hasRequiredFigures, style, hasRequiredStyle, lines, hasRequiredLines, wrap, hasRequiredWrap, entriesToDisplay, hasRequiredEntriesToDisplay, util, hasRequiredUtil, prompt, hasRequiredPrompt, text, hasRequiredText, select4, hasRequiredSelect, toggle, hasRequiredToggle, datepart, hasRequiredDatepart, meridiem, hasRequiredMeridiem, day, hasRequiredDay, hours, hasRequiredHours, milliseconds, hasRequiredMilliseconds, minutes, hasRequiredMinutes, month, hasRequiredMonth, seconds, hasRequiredSeconds, year, hasRequiredYear, dateparts, hasRequiredDateparts, date, hasRequiredDate, number, hasRequiredNumber, multiselect, hasRequiredMultiselect, autocomplete, hasRequiredAutocomplete, autocompleteMultiselect, hasRequiredAutocompleteMultiselect, confirm5, hasRequiredConfirm, elements, hasRequiredElements, hasRequiredPrompts$1, lib$1, hasRequiredLib$1, prompts$1, hasRequiredPrompts, promptsExports, prompts, isBrowser, platform, OSC = "\x1B]", BEL = "\x07", SEP = ";", link = (text2, url) => [
24995
25022
  OSC,
24996
25023
  "8",
24997
25024
  SEP,
@@ -25044,7 +25071,7 @@ var init_ni_B5qNAuoI = __esm(() => {
25044
25071
  options2 = {};
25045
25072
  libExports = requireLib();
25046
25073
  which = /* @__PURE__ */ getDefaultExportFromCjs(libExports);
25047
- CLI_TEMP_DIR = join5(os4.tmpdir(), "antfu-ni");
25074
+ CLI_TEMP_DIR = join7(os4.tmpdir(), "antfu-ni");
25048
25075
  customRcPath = process$1.env.NI_CONFIG_FILE;
25049
25076
  home = process$1.platform === "win32" ? process$1.env.USERPROFILE : process$1.env.HOME;
25050
25077
  defaultRcPath = path3.join(home || "~/", ".nirc");
@@ -25675,12 +25702,12 @@ var init_figures = __esm(() => {
25675
25702
  import tty2 from "node:tty";
25676
25703
  var hasColors, format = (open, close) => {
25677
25704
  if (!hasColors) {
25678
- return (input3) => input3;
25705
+ return (input5) => input5;
25679
25706
  }
25680
25707
  const openCode = `\x1B[${open}m`;
25681
25708
  const closeCode = `\x1B[${close}m`;
25682
- return (input3) => {
25683
- const string = input3 + "";
25709
+ return (input5) => {
25710
+ const string = input5 + "";
25684
25711
  let index = string.indexOf(closeCode);
25685
25712
  if (index === -1) {
25686
25713
  return openCode + string + closeCode;
@@ -27789,16 +27816,16 @@ var init_options2 = __esm(() => {
27789
27816
  var concatenateShell = (file, commandArguments, options3) => options3.shell && commandArguments.length > 0 ? [[file, ...commandArguments].join(" "), [], options3] : [file, commandArguments, options3];
27790
27817
 
27791
27818
  // ../../node_modules/strip-final-newline/index.js
27792
- function stripFinalNewline(input3) {
27793
- if (typeof input3 === "string") {
27794
- return stripFinalNewlineString(input3);
27819
+ function stripFinalNewline(input5) {
27820
+ if (typeof input5 === "string") {
27821
+ return stripFinalNewlineString(input5);
27795
27822
  }
27796
- if (!(ArrayBuffer.isView(input3) && input3.BYTES_PER_ELEMENT === 1)) {
27823
+ if (!(ArrayBuffer.isView(input5) && input5.BYTES_PER_ELEMENT === 1)) {
27797
27824
  throw new Error("Input must be a string or a Uint8Array");
27798
27825
  }
27799
- return stripFinalNewlineBinary(input3);
27826
+ return stripFinalNewlineBinary(input5);
27800
27827
  }
27801
- var stripFinalNewlineString = (input3) => input3.at(-1) === LF ? input3.slice(0, input3.at(-2) === CR ? -2 : -1) : input3, stripFinalNewlineBinary = (input3) => input3.at(-1) === LF_BINARY ? input3.subarray(0, input3.at(-2) === CR_BINARY ? -2 : -1) : input3, LF = `
27828
+ var stripFinalNewlineString = (input5) => input5.at(-1) === LF ? input5.slice(0, input5.at(-2) === CR ? -2 : -1) : input5, stripFinalNewlineBinary = (input5) => input5.at(-1) === LF_BINARY ? input5.subarray(0, input5.at(-2) === CR_BINARY ? -2 : -1) : input5, LF = `
27802
27829
  `, LF_BINARY, CR = "\r", CR_BINARY;
27803
27830
  var init_strip_final_newline = __esm(() => {
27804
27831
  LF_BINARY = LF.codePointAt(0);
@@ -28837,21 +28864,21 @@ var init_native = __esm(() => {
28837
28864
  });
28838
28865
 
28839
28866
  // ../../node_modules/execa/lib/stdio/input-option.js
28840
- var handleInputOptions = ({ input: input3, inputFile }, fdNumber) => fdNumber === 0 ? [
28841
- ...handleInputOption(input3),
28867
+ var handleInputOptions = ({ input: input5, inputFile }, fdNumber) => fdNumber === 0 ? [
28868
+ ...handleInputOption(input5),
28842
28869
  ...handleInputFileOption(inputFile)
28843
- ] : [], handleInputOption = (input3) => input3 === undefined ? [] : [{
28844
- type: getInputType(input3),
28845
- value: input3,
28870
+ ] : [], handleInputOption = (input5) => input5 === undefined ? [] : [{
28871
+ type: getInputType(input5),
28872
+ value: input5,
28846
28873
  optionName: "input"
28847
- }], getInputType = (input3) => {
28848
- if (isReadableStream(input3, { checkOpen: false })) {
28874
+ }], getInputType = (input5) => {
28875
+ if (isReadableStream(input5, { checkOpen: false })) {
28849
28876
  return "nodeStream";
28850
28877
  }
28851
- if (typeof input3 === "string") {
28878
+ if (typeof input5 === "string") {
28852
28879
  return "string";
28853
28880
  }
28854
- if (isUint8Array(input3)) {
28881
+ if (isUint8Array(input5)) {
28855
28882
  return "uint8Array";
28856
28883
  }
28857
28884
  throw new Error("The `input` option must be a string, a Uint8Array or a Node.js Readable stream.");
@@ -31967,7 +31994,7 @@ var init_command2 = __esm(() => {
31967
31994
  var setScriptSync = (boundExeca, createNested, boundOptions) => {
31968
31995
  boundExeca.sync = createNested(mapScriptSync, boundOptions);
31969
31996
  boundExeca.s = boundExeca.sync;
31970
- }, mapScriptAsync = ({ options: options3 }) => getScriptOptions(options3), mapScriptSync = ({ options: options3 }) => ({ ...getScriptOptions(options3), isSync: true }), getScriptOptions = (options3) => ({ options: { ...getScriptStdinOption(options3), ...options3 } }), getScriptStdinOption = ({ input: input3, inputFile, stdio }) => input3 === undefined && inputFile === undefined && stdio === undefined ? { stdin: "inherit" } : {}, deepScriptOptions;
31997
+ }, mapScriptAsync = ({ options: options3 }) => getScriptOptions(options3), mapScriptSync = ({ options: options3 }) => ({ ...getScriptOptions(options3), isSync: true }), getScriptOptions = (options3) => ({ options: { ...getScriptStdinOption(options3), ...options3 } }), getScriptStdinOption = ({ input: input5, inputFile, stdio }) => input5 === undefined && inputFile === undefined && stdio === undefined ? { stdin: "inherit" } : {}, deepScriptOptions;
31971
31998
  var init_script = __esm(() => {
31972
31999
  deepScriptOptions = { preferLocal: true };
31973
32000
  });
@@ -32078,20 +32105,20 @@ __export(exports_generate, {
32078
32105
  import path10 from "path";
32079
32106
  import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
32080
32107
  import { toCamelCase as toCamelCase8 } from "@secondlayer/stacks/clarity";
32081
- function isContractAddress(input3) {
32108
+ function isContractAddress(input5) {
32082
32109
  const contractIdPattern = /^(SP|ST|SM|SN)[A-Z0-9]{38,}\.[a-zA-Z][a-zA-Z0-9-]*$/;
32083
- return contractIdPattern.test(input3);
32110
+ return contractIdPattern.test(input5);
32084
32111
  }
32085
32112
  async function parseInputs(inputs) {
32086
32113
  const files = [];
32087
32114
  const contractIds = [];
32088
- for (const input3 of inputs) {
32089
- if (isContractAddress(input3)) {
32090
- contractIds.push(input3);
32115
+ for (const input5 of inputs) {
32116
+ if (isContractAddress(input5)) {
32117
+ contractIds.push(input5);
32091
32118
  continue;
32092
32119
  }
32093
- if (input3.includes("*") || input3.includes("?")) {
32094
- const matches = await import_fast_glob.default(input3, { cwd: process.cwd(), absolute: true });
32120
+ if (input5.includes("*") || input5.includes("?")) {
32121
+ const matches = await import_fast_glob.default(input5, { cwd: process.cwd(), absolute: true });
32095
32122
  for (const file of matches) {
32096
32123
  if (file.endsWith(".clar")) {
32097
32124
  files.push(file);
@@ -32099,8 +32126,8 @@ async function parseInputs(inputs) {
32099
32126
  }
32100
32127
  continue;
32101
32128
  }
32102
- if (input3.endsWith(".clar")) {
32103
- const absolutePath = path10.resolve(process.cwd(), input3);
32129
+ if (input5.endsWith(".clar")) {
32130
+ const absolutePath = path10.resolve(process.cwd(), input5);
32104
32131
  files.push(absolutePath);
32105
32132
  }
32106
32133
  }
@@ -32383,7 +32410,7 @@ var {
32383
32410
  // package.json
32384
32411
  var package_default = {
32385
32412
  name: "@secondlayer/cli",
32386
- version: "2.1.0",
32413
+ version: "3.0.0",
32387
32414
  description: "CLI for subgraphs and blockchain indexing on Stacks",
32388
32415
  type: "module",
32389
32416
  bin: {
@@ -32424,12 +32451,12 @@ var package_default = {
32424
32451
  license: "MIT",
32425
32452
  dependencies: {
32426
32453
  "@inquirer/prompts": "^8.2.0",
32427
- "@secondlayer/bundler": "^0.2.0",
32428
- "@secondlayer/sdk": "^1.0.0",
32429
- "@secondlayer/shared": "^1.0.0",
32430
- "@secondlayer/stacks": "^0.2.2",
32431
- "@secondlayer/subgraphs": "^0.11.6",
32432
- "@secondlayer/workflows": "^1.0.1",
32454
+ "@secondlayer/bundler": "^0.3.0",
32455
+ "@secondlayer/sdk": "^1.0.1",
32456
+ "@secondlayer/shared": "^2.0.0",
32457
+ "@secondlayer/stacks": "^0.3.0",
32458
+ "@secondlayer/subgraphs": "^0.11.8",
32459
+ "@secondlayer/workflows": "^1.1.0",
32433
32460
  "@biomejs/js-api": "^0.7.0",
32434
32461
  "@biomejs/wasm-nodejs": "^1.9.0",
32435
32462
  esbuild: "^0.19.0",
@@ -32450,8 +32477,145 @@ var package_default = {
32450
32477
  }
32451
32478
  };
32452
32479
 
32480
+ // src/lib/api-client.ts
32481
+ init_http();
32482
+ init_resolve_tenant();
32483
+ import { ApiError, SecondLayer } from "@secondlayer/sdk";
32484
+ function handleApiError(err, action) {
32485
+ if (err instanceof CliHttpError) {
32486
+ if (err.code === "SESSION_EXPIRED") {
32487
+ console.error("Session expired. Run: sl login");
32488
+ process.exit(1);
32489
+ }
32490
+ if (err.code === "TRIAL_EXPIRED") {
32491
+ console.error(err.message);
32492
+ console.error("Run: sl instance resize --plan <...> and add payment");
32493
+ process.exit(1);
32494
+ }
32495
+ if (err.code === "TENANT_SUSPENDED") {
32496
+ console.error("Tenant is suspended. Run: sl instance resume");
32497
+ process.exit(1);
32498
+ }
32499
+ if (err.code === "NO_TENANT_FOR_PROJECT") {
32500
+ console.error(err.message);
32501
+ process.exit(1);
32502
+ }
32503
+ }
32504
+ if (err instanceof ApiError && err.status === 401) {
32505
+ console.error("Authentication required. Run: sl login");
32506
+ process.exit(1);
32507
+ }
32508
+ console.error(`Error: Failed to ${action}: ${err}`);
32509
+ process.exit(1);
32510
+ }
32511
+ function withErrorHandling(fn, options) {
32512
+ return async (...args) => {
32513
+ try {
32514
+ await fn(...args);
32515
+ } catch (err) {
32516
+ if (options?.onError) {
32517
+ options.onError(err);
32518
+ } else {
32519
+ handleApiError(err, options?.action ?? "execute command");
32520
+ }
32521
+ }
32522
+ };
32523
+ }
32524
+ async function assertOk(res) {
32525
+ if (res.ok)
32526
+ return;
32527
+ const body = await res.text();
32528
+ try {
32529
+ const parsed = JSON.parse(body);
32530
+ if (typeof parsed.error === "string" && parsed.error)
32531
+ throw new Error(parsed.error);
32532
+ } catch (e) {
32533
+ if (e instanceof Error && e.message !== body)
32534
+ throw e;
32535
+ }
32536
+ throw new Error(`HTTP ${res.status}`);
32537
+ }
32538
+ async function getTenantClient() {
32539
+ const { apiUrl, ephemeralKey } = await resolveActiveTenant();
32540
+ return new SecondLayer({ baseUrl: apiUrl, apiKey: ephemeralKey });
32541
+ }
32542
+ async function listSubgraphsApi() {
32543
+ return (await getTenantClient()).subgraphs.list();
32544
+ }
32545
+ async function getSubgraphApi(name) {
32546
+ return (await getTenantClient()).subgraphs.get(name);
32547
+ }
32548
+ async function reindexSubgraphApi(name, options) {
32549
+ return (await getTenantClient()).subgraphs.reindex(name, options);
32550
+ }
32551
+ async function backfillSubgraphApi(name, options) {
32552
+ return (await getTenantClient()).subgraphs.backfill(name, options);
32553
+ }
32554
+ async function stopSubgraphApi(name) {
32555
+ return (await getTenantClient()).subgraphs.stop(name);
32556
+ }
32557
+ async function deleteSubgraphApi(name) {
32558
+ return (await getTenantClient()).subgraphs.delete(name);
32559
+ }
32560
+ async function deploySubgraphApi(data) {
32561
+ return (await getTenantClient()).subgraphs.deploy(data);
32562
+ }
32563
+ async function querySubgraphTable(name, table, params = {}) {
32564
+ return (await getTenantClient()).subgraphs.queryTable(name, table, params);
32565
+ }
32566
+ async function querySubgraphTableCount(name, table, params = {}) {
32567
+ return (await getTenantClient()).subgraphs.queryTableCount(name, table, params);
32568
+ }
32569
+ async function getSubgraphGaps(name, opts) {
32570
+ return (await getTenantClient()).subgraphs.gaps(name, opts);
32571
+ }
32572
+ async function publishSubgraphApi(name, opts) {
32573
+ const { apiUrl, ephemeralKey } = await resolveActiveTenant();
32574
+ const res = await fetch(`${apiUrl}/api/subgraphs/${name}/publish`, {
32575
+ method: "POST",
32576
+ headers: {
32577
+ "content-type": "application/json",
32578
+ authorization: `Bearer ${ephemeralKey}`
32579
+ },
32580
+ body: JSON.stringify(opts ?? {})
32581
+ });
32582
+ await assertOk(res);
32583
+ return res.json();
32584
+ }
32585
+ async function unpublishSubgraphApi(name) {
32586
+ const { apiUrl, ephemeralKey } = await resolveActiveTenant();
32587
+ const res = await fetch(`${apiUrl}/api/subgraphs/${name}/unpublish`, {
32588
+ method: "POST",
32589
+ headers: {
32590
+ "content-type": "application/json",
32591
+ authorization: `Bearer ${ephemeralKey}`
32592
+ },
32593
+ body: JSON.stringify({})
32594
+ });
32595
+ await assertOk(res);
32596
+ return res.json();
32597
+ }
32598
+ async function getAccountProfile() {
32599
+ return httpPlatform("/api/accounts/me");
32600
+ }
32601
+ async function updateAccountProfile(data) {
32602
+ return httpPlatform("/api/accounts/me", { method: "PATCH", body: data });
32603
+ }
32604
+ async function getPlatformClient() {
32605
+ const base = process.env.SL_PLATFORM_API_URL ?? "https://api.secondlayer.tools";
32606
+ return new SecondLayer({ baseUrl: base });
32607
+ }
32608
+ async function browseMarketplace(opts = {}) {
32609
+ return (await getPlatformClient()).marketplace.browse(opts);
32610
+ }
32611
+ async function getMarketplaceSubgraph(name) {
32612
+ return (await getPlatformClient()).marketplace.get(name);
32613
+ }
32614
+ async function forkMarketplaceSubgraph(name, newName) {
32615
+ return (await getPlatformClient()).marketplace.fork(name, newName);
32616
+ }
32617
+
32453
32618
  // src/commands/account.ts
32454
- init_api_client();
32455
32619
  init_output();
32456
32620
  function registerAccountCommand(program2) {
32457
32621
  const account = program2.command("account").description("Manage your account profile");
@@ -32497,8 +32661,8 @@ init_config();
32497
32661
 
32498
32662
  // src/lib/detect.ts
32499
32663
  init_docker();
32500
- import { homedir as homedir2 } from "node:os";
32501
- import { join as join2 } from "node:path";
32664
+ import { homedir as homedir4 } from "node:os";
32665
+ import { join as join4 } from "node:path";
32502
32666
  var STACKS_CONTAINER_PATTERNS = [
32503
32667
  "stacks-blockchain",
32504
32668
  "stacks-node",
@@ -32566,8 +32730,8 @@ async function findDockerComposeRoot(startPath) {
32566
32730
  let current = startPath;
32567
32731
  while (current && current !== "/") {
32568
32732
  try {
32569
- const composeYml = Bun.file(join2(current, "docker-compose.yml"));
32570
- const composeYaml = Bun.file(join2(current, "docker-compose.yaml"));
32733
+ const composeYml = Bun.file(join4(current, "docker-compose.yml"));
32734
+ const composeYaml = Bun.file(join4(current, "docker-compose.yaml"));
32571
32735
  if (await composeYml.exists() || await composeYaml.exists()) {
32572
32736
  return current;
32573
32737
  }
@@ -32614,9 +32778,9 @@ var SEARCH_PATTERNS = [
32614
32778
  "/Volumes/stacks-node",
32615
32779
  "/Volumes/*/stacks-blockchain-docker",
32616
32780
  "/Volumes/*/stacks-node",
32617
- `${homedir2()}/stacks-blockchain-docker`,
32618
- `${homedir2()}/stacks-node`,
32619
- `${homedir2()}/stacks-*`,
32781
+ `${homedir4()}/stacks-blockchain-docker`,
32782
+ `${homedir4()}/stacks-node`,
32783
+ `${homedir4()}/stacks-*`,
32620
32784
  "/opt/stacks-blockchain-docker",
32621
32785
  "/opt/stacks-node",
32622
32786
  "/opt/stacks-*"
@@ -32663,8 +32827,8 @@ async function isValidStacksNodeDir(path) {
32663
32827
  return true;
32664
32828
  }
32665
32829
  try {
32666
- const composeYml = Bun.file(join2(path, "docker-compose.yml"));
32667
- const composeYaml = Bun.file(join2(path, "docker-compose.yaml"));
32830
+ const composeYml = Bun.file(join4(path, "docker-compose.yml"));
32831
+ const composeYaml = Bun.file(join4(path, "docker-compose.yaml"));
32668
32832
  const hasCompose = await composeYml.exists() || await composeYaml.exists();
32669
32833
  if (!hasCompose) {
32670
32834
  return false;
@@ -32677,7 +32841,7 @@ async function isValidStacksNodeDir(path) {
32677
32841
  }
32678
32842
  }
32679
32843
  async function detectNetworkFromFilesystem(path) {
32680
- const envFile = Bun.file(join2(path, ".env"));
32844
+ const envFile = Bun.file(join4(path, ".env"));
32681
32845
  if (await envFile.exists()) {
32682
32846
  try {
32683
32847
  const content = await envFile.text();
@@ -32689,12 +32853,12 @@ async function detectNetworkFromFilesystem(path) {
32689
32853
  }
32690
32854
  } catch {}
32691
32855
  }
32692
- const testnetConfig = Bun.file(join2(path, "configurations/testnet"));
32693
- const mainnetConfig = Bun.file(join2(path, "configurations/mainnet"));
32694
- const activeConfig = Bun.file(join2(path, "configurations/active"));
32856
+ const testnetConfig = Bun.file(join4(path, "configurations/testnet"));
32857
+ const mainnetConfig = Bun.file(join4(path, "configurations/mainnet"));
32858
+ const activeConfig = Bun.file(join4(path, "configurations/active"));
32695
32859
  if (await activeConfig.exists()) {
32696
32860
  try {
32697
- const result = await Bun.$`readlink ${join2(path, "configurations/active")}`.quiet().nothrow();
32861
+ const result = await Bun.$`readlink ${join4(path, "configurations/active")}`.quiet().nothrow();
32698
32862
  const link = result.stdout.toString().trim();
32699
32863
  if (link.includes("testnet"))
32700
32864
  return "testnet";
@@ -32707,7 +32871,7 @@ async function detectNetworkFromFilesystem(path) {
32707
32871
  }
32708
32872
  async function isComposeProjectRunning(path) {
32709
32873
  try {
32710
- const result = await Bun.$`docker compose -f ${join2(path, "docker-compose.yml")} ps -q`.quiet().nothrow();
32874
+ const result = await Bun.$`docker compose -f ${join4(path, "docker-compose.yml")} ps -q`.quiet().nothrow();
32711
32875
  return result.exitCode === 0 && result.stdout.toString().trim().length > 0;
32712
32876
  } catch {
32713
32877
  return false;
@@ -32787,9 +32951,8 @@ function registerConfigCommand(program2) {
32787
32951
  async function printConfigTree(cfg) {
32788
32952
  const defaults = getDefaultConfig();
32789
32953
  printValue("network", cfg.network, isDefaultValue(cfg, "network"));
32790
- printValue("apiUrl", resolveApiUrl(cfg), cfg.apiUrl === undefined);
32791
- if (cfg.apiKey) {
32792
- printValue("apiKey", cfg.apiKey.slice(0, 14) + "...", false);
32954
+ if (cfg.defaultProject) {
32955
+ printValue("defaultProject", cfg.defaultProject, false);
32793
32956
  }
32794
32957
  const resolvedDataDir = getDataDir(cfg);
32795
32958
  const dataDirDisplay = cfg.dataDir === resolvedDataDir ? cfg.dataDir : `${cfg.dataDir} ${dim(`→ ${resolvedDataDir}`)}`;
@@ -32858,31 +33021,25 @@ async function validateDatabaseConnection(url) {
32858
33021
  }
32859
33022
  }
32860
33023
  // src/commands/status.ts
32861
- init_api_client();
32862
33024
  init_config();
33025
+ init_http();
32863
33026
  init_output();
32864
33027
  function registerStatusCommand(program2) {
32865
33028
  program2.command("status").description("Show system status").option("--json", "Output as JSON").action(async (options) => {
32866
33029
  const config = await loadConfig();
32867
33030
  try {
32868
- const response = await fetch(`${resolveApiUrl(config)}/status`, {
32869
- headers: authHeaders(config)
32870
- });
32871
- if (!response.ok) {
32872
- if (response.status === 401) {
32873
- console.error("Error: Authentication required. Run: sl auth login");
32874
- process.exit(1);
32875
- }
32876
- throw new Error(`HTTP ${response.status}`);
32877
- }
32878
- const status = await response.json();
33031
+ const status = await httpPlatform("/status");
32879
33032
  if (options.json) {
32880
33033
  console.log(JSON.stringify(status, null, 2));
32881
33034
  return;
32882
33035
  }
32883
33036
  printStatus(status);
32884
- } catch {
32885
- console.log("");
33037
+ } catch (err) {
33038
+ if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED") {
33039
+ console.error("Not logged in. Run: sl login");
33040
+ process.exit(1);
33041
+ }
33042
+ console.log("");
32886
33043
  console.log(blue("System Status"));
32887
33044
  console.log(` ${red("NOT RUNNING")}`);
32888
33045
  console.log("");
@@ -32890,7 +33047,7 @@ function registerStatusCommand(program2) {
32890
33047
  console.log(dim(" API service is not running."));
32891
33048
  console.log(dim(" Start with: sl local start"));
32892
33049
  } else {
32893
- console.log(dim(` Can't reach ${config.network} API at ${resolveApiUrl(config)}`));
33050
+ console.log(dim(" Can't reach the platform API."));
32894
33051
  console.log(dim(" Check your connection or try again."));
32895
33052
  }
32896
33053
  console.log("");
@@ -32952,234 +33109,18 @@ function printStatus(status) {
32952
33109
  }
32953
33110
  console.log(dim(`Last updated: ${status.timestamp}`));
32954
33111
  }
32955
- // src/commands/sync.ts
33112
+ // src/commands/db.ts
32956
33113
  init_config();
33114
+ init_dev_state();
32957
33115
  init_output();
32958
33116
  import { confirm } from "@inquirer/prompts";
32959
- import { getDb } from "@secondlayer/shared/db";
33117
+ import { getDb, sql } from "@secondlayer/shared/db";
32960
33118
  import {
32961
33119
  countMissingBlocks,
32962
33120
  findGaps
32963
33121
  } from "@secondlayer/shared/db/queries/integrity";
32964
33122
  import { StacksNodeClient } from "@secondlayer/shared/node";
32965
- import { HiroClient } from "@secondlayer/shared/node/hiro-client";
32966
- import { LocalClient } from "@secondlayer/shared/node/local-client";
32967
33123
  var DEV_DATABASE_URL = "postgres://postgres:postgres@localhost:5432/secondlayer_dev";
32968
- function registerSyncCommand(program2) {
32969
- program2.command("sync").description("Fetch missing blocks and index them").option("--from <block>", "Start block height").option("--to <block>", "End block height").option("--gaps", "Auto-detect and fill all gaps").option("--concurrency <n>", "Parallel fetch limit (default: 1 for hiro, 5 for node)").option("--delay <ms>", "Delay between batches in ms (default: 500 for hiro, 0 for node)").option("--source <source>", "Data source: auto, local, hiro, node", "auto").option("-y, --yes", "Skip confirmation prompt").action(async function() {
32970
- const opts = this.opts();
32971
- const config = await loadConfig();
32972
- const indexerUrl = process.env.INDEXER_URL || `http://localhost:${config.ports.indexer}`;
32973
- let concurrency = opts.concurrency ? Number.parseInt(opts.concurrency) : 0;
32974
- try {
32975
- const nodeClient = new StacksNodeClient;
32976
- const hiroClient = new HiroClient;
32977
- const localClient = new LocalClient;
32978
- let useHiro = opts.source === "hiro";
32979
- let useNode = opts.source === "node";
32980
- let useLocal = opts.source === "local";
32981
- if (opts.source === "auto" || !opts.source) {
32982
- if (!process.env.DATABASE_URL) {
32983
- process.env.DATABASE_URL = DEV_DATABASE_URL;
32984
- }
32985
- const db = getDb();
32986
- const localTip = await localClient.getChainTip(db);
32987
- if (localTip > 0) {
32988
- useLocal = true;
32989
- info(`Using local DB for backfill (tip: block ${localTip})`);
32990
- } else {
32991
- const nodeHealthy = await nodeClient.isHealthy();
32992
- if (nodeHealthy) {
32993
- const testBlock = await nodeClient.getBlock(1).catch(() => null);
32994
- if (testBlock) {
32995
- useNode = true;
32996
- info("Using local Stacks node for backfill");
32997
- } else {
32998
- useHiro = true;
32999
- info("Node can't serve block data, using Hiro public API");
33000
- }
33001
- } else {
33002
- useHiro = true;
33003
- info("Node not reachable, using Hiro public API");
33004
- }
33005
- }
33006
- }
33007
- if (concurrency === 0) {
33008
- concurrency = useLocal ? 10 : useHiro ? 1 : 5;
33009
- }
33010
- if (useLocal) {
33011
- if (!process.env.DATABASE_URL) {
33012
- process.env.DATABASE_URL = DEV_DATABASE_URL;
33013
- }
33014
- info("Source: local DB");
33015
- } else if (useHiro) {
33016
- const hiroHealthy = await hiroClient.isHealthy();
33017
- if (!hiroHealthy) {
33018
- error(`Cannot reach Hiro API at ${hiroClient.getApiUrl()}`);
33019
- console.log(dim(`
33020
- Set HIRO_API_URL or check your internet connection.`));
33021
- process.exit(1);
33022
- }
33023
- info(`Source: Hiro API (${hiroClient.getApiUrl()})`);
33024
- } else if (useNode) {
33025
- const nodeInfo = await nodeClient.getInfo();
33026
- info(`Source: local node (tip: block ${nodeInfo.stacks_tip_height})`);
33027
- }
33028
- let ranges = [];
33029
- if (opts.gaps) {
33030
- if (!process.env.DATABASE_URL) {
33031
- process.env.DATABASE_URL = DEV_DATABASE_URL;
33032
- }
33033
- const db = getDb();
33034
- const gaps = await findGaps(db);
33035
- const missing = await countMissingBlocks(db);
33036
- if (gaps.length === 0) {
33037
- success("No gaps detected — block data is contiguous");
33038
- process.exit(0);
33039
- }
33040
- info(`Found ${gaps.length} gaps, ${missing} missing blocks`);
33041
- ranges = gaps.map((g) => ({
33042
- start: g.gapStart,
33043
- end: g.gapEnd
33044
- }));
33045
- } else if (opts.from && opts.to) {
33046
- const from = Number.parseInt(opts.from);
33047
- const to = Number.parseInt(opts.to);
33048
- if (isNaN(from) || from < 0) {
33049
- error("--from must be a non-negative number");
33050
- process.exit(1);
33051
- }
33052
- if (isNaN(to) || to < 0) {
33053
- error("--to must be a non-negative number");
33054
- process.exit(1);
33055
- }
33056
- if (from > to) {
33057
- error("--from must be <= --to");
33058
- process.exit(1);
33059
- }
33060
- ranges = [{ start: from, end: to }];
33061
- } else {
33062
- error("Must specify --from and --to, or --gaps");
33063
- console.log(dim(`
33064
- Examples:`));
33065
- console.log(dim(" sl sync --from 1000 --to 2000"));
33066
- console.log(dim(" sl sync --gaps"));
33067
- console.log(dim(" sl sync --gaps --source hiro"));
33068
- process.exit(1);
33069
- }
33070
- const totalBlocks = ranges.reduce((sum, r) => sum + (r.end - r.start + 1), 0);
33071
- if (!opts.yes) {
33072
- console.log("");
33073
- const sourceLabel = useLocal ? "local DB" : useHiro ? "Hiro API" : "local node";
33074
- console.log(`This will fetch ${yellow(totalBlocks.toString())} blocks from ${sourceLabel}.`);
33075
- if (useHiro) {
33076
- console.log(dim("Note: Hiro API fetches are slower due to per-tx event lookups."));
33077
- }
33078
- const confirmed = await confirm({
33079
- message: "Continue?",
33080
- default: true
33081
- });
33082
- if (!confirmed) {
33083
- info("Cancelled");
33084
- process.exit(0);
33085
- }
33086
- }
33087
- const batchDelay = opts.delay ? Number.parseInt(opts.delay) : useHiro ? 500 : 0;
33088
- if (useHiro && batchDelay > 0) {
33089
- info(`Pacing: ${batchDelay}ms delay between batches (concurrency: ${concurrency})`);
33090
- }
33091
- let fetched = 0;
33092
- let errors = 0;
33093
- let consecutiveErrors = 0;
33094
- const startTime = Date.now();
33095
- for (const range of ranges) {
33096
- const heights = [];
33097
- for (let h = range.start;h <= range.end; h++) {
33098
- heights.push(h);
33099
- }
33100
- for (let i = 0;i < heights.length; i += concurrency) {
33101
- const batch = heights.slice(i, i + concurrency);
33102
- const results = await Promise.allSettled(batch.map(async (height) => {
33103
- let block;
33104
- if (useLocal) {
33105
- const db = getDb();
33106
- block = await localClient.getBlockForReplay(db, height);
33107
- } else if (useHiro) {
33108
- block = await hiroClient.getBlockForIndexer(height);
33109
- } else {
33110
- block = await nodeClient.getBlock(height);
33111
- }
33112
- if (!block) {
33113
- throw new Error(`Block ${height} not found`);
33114
- }
33115
- const res = await fetch(`${indexerUrl}/new_block`, {
33116
- method: "POST",
33117
- headers: {
33118
- "Content-Type": "application/json",
33119
- "X-Source": "backfill"
33120
- },
33121
- body: JSON.stringify(block)
33122
- });
33123
- if (!res.ok) {
33124
- throw new Error(`Indexer rejected block ${height}: ${res.status}`);
33125
- }
33126
- return height;
33127
- }));
33128
- for (const result of results) {
33129
- if (result.status === "fulfilled") {
33130
- fetched++;
33131
- consecutiveErrors = 0;
33132
- } else {
33133
- errors++;
33134
- consecutiveErrors++;
33135
- console.log(red(`
33136
- ✗ ${result.reason}`));
33137
- }
33138
- }
33139
- if (consecutiveErrors >= 5) {
33140
- const cooldown = Math.min(consecutiveErrors * 2000, 30000);
33141
- process.stdout.write(`
33142
- ${yellow(`Backing off ${cooldown / 1000}s after ${consecutiveErrors} consecutive errors...`)}`);
33143
- await new Promise((r) => setTimeout(r, cooldown));
33144
- }
33145
- const elapsed = (Date.now() - startTime) / 1000;
33146
- const rate = fetched / elapsed;
33147
- const remaining = totalBlocks - fetched - errors;
33148
- const eta = rate > 0 ? Math.round(remaining / rate) : 0;
33149
- const etaStr = eta > 3600 ? `${Math.floor(eta / 3600)}h ${Math.floor(eta % 3600 / 60)}m` : eta > 60 ? `${Math.floor(eta / 60)}m ${eta % 60}s` : `${eta}s`;
33150
- const pct = Math.round((fetched + errors) / totalBlocks * 100);
33151
- process.stdout.write(`\r ${green(`${fetched}`)} fetched, ${errors > 0 ? red(`${errors} errors`) : "0 errors"} (${pct}%) ${dim(`${rate.toFixed(1)} blk/s — ETA ${etaStr}`)} `);
33152
- if (batchDelay > 0) {
33153
- await new Promise((r) => setTimeout(r, batchDelay));
33154
- }
33155
- }
33156
- }
33157
- console.log("");
33158
- console.log("");
33159
- if (errors === 0) {
33160
- success(`Backfill complete: ${fetched} blocks indexed`);
33161
- } else {
33162
- warn(`Backfill complete: ${fetched} indexed, ${errors} errors`);
33163
- }
33164
- process.exit(0);
33165
- } catch (err) {
33166
- error(`Backfill failed: ${err}`);
33167
- process.exit(1);
33168
- }
33169
- });
33170
- }
33171
- // src/commands/db.ts
33172
- init_config();
33173
- init_dev_state();
33174
- init_output();
33175
- import { confirm as confirm2 } from "@inquirer/prompts";
33176
- import { getDb as getDb2, sql } from "@secondlayer/shared/db";
33177
- import {
33178
- countMissingBlocks as countMissingBlocks2,
33179
- findGaps as findGaps2
33180
- } from "@secondlayer/shared/db/queries/integrity";
33181
- import { StacksNodeClient as StacksNodeClient2 } from "@secondlayer/shared/node";
33182
- var DEV_DATABASE_URL2 = "postgres://postgres:postgres@localhost:5432/secondlayer_dev";
33183
33124
  function registerDbCommand(program2) {
33184
33125
  const dbCmd = program2.command("db").description("Inspect indexer database tables").hook("preAction", async () => {
33185
33126
  await requireLocalNetwork();
@@ -33213,9 +33154,9 @@ function registerDbCommand(program2) {
33213
33154
  }
33214
33155
  function ensureDb() {
33215
33156
  if (!process.env.DATABASE_URL) {
33216
- process.env.DATABASE_URL = DEV_DATABASE_URL2;
33157
+ process.env.DATABASE_URL = DEV_DATABASE_URL;
33217
33158
  }
33218
- return getDb2();
33159
+ return getDb();
33219
33160
  }
33220
33161
  async function showOverview(_limit) {
33221
33162
  try {
@@ -33339,8 +33280,8 @@ async function showEvents(limit, json) {
33339
33280
  async function showGaps(limit, json) {
33340
33281
  try {
33341
33282
  const db = ensureDb();
33342
- const gaps = await findGaps2(db, limit);
33343
- const missing = await countMissingBlocks2(db);
33283
+ const gaps = await findGaps(db, limit);
33284
+ const missing = await countMissingBlocks(db);
33344
33285
  if (json) {
33345
33286
  console.log(JSON.stringify({ gaps, totalMissingBlocks: missing }, null, 2));
33346
33287
  process.exit(0);
@@ -33383,7 +33324,7 @@ async function resetDatabase(skipConfirm) {
33383
33324
  console.log(dim("Note: Subgraph configurations will be preserved."));
33384
33325
  console.log("");
33385
33326
  if (!skipConfirm) {
33386
- const confirmed = await confirm2({
33327
+ const confirmed = await confirm({
33387
33328
  message: "Are you sure you want to reset the database?",
33388
33329
  default: false
33389
33330
  });
@@ -33420,7 +33361,7 @@ async function resyncDatabase(skipConfirm, backfill) {
33420
33361
  console.log(dim("Note: Subgraph configurations will be preserved."));
33421
33362
  console.log("");
33422
33363
  if (!skipConfirm) {
33423
- const confirmed = await confirm2({
33364
+ const confirmed = await confirm({
33424
33365
  message: "Are you sure you want to resync?",
33425
33366
  default: false
33426
33367
  });
@@ -33458,7 +33399,7 @@ async function resyncDatabase(skipConfirm, backfill) {
33458
33399
  if (backfill) {
33459
33400
  console.log("");
33460
33401
  info("Starting backfill from node...");
33461
- const nodeClient = new StacksNodeClient2;
33402
+ const nodeClient = new StacksNodeClient;
33462
33403
  const healthy = await nodeClient.isHealthy();
33463
33404
  if (!healthy) {
33464
33405
  warn(`Cannot reach Stacks node at ${nodeClient.getRpcUrl()}`);
@@ -33522,9 +33463,9 @@ async function resyncDatabase(skipConfirm, backfill) {
33522
33463
  }
33523
33464
  }
33524
33465
  // src/commands/subgraphs.ts
33525
- import { existsSync, mkdirSync, watch } from "node:fs";
33526
- import { resolve } from "node:path";
33527
- import { confirm as confirm3 } from "@inquirer/prompts";
33466
+ import { existsSync as existsSync2, mkdirSync, watch } from "node:fs";
33467
+ import { resolve as resolve2 } from "node:path";
33468
+ import { confirm as confirm2 } from "@inquirer/prompts";
33528
33469
 
33529
33470
  // src/generators/subgraph-scaffold.ts
33530
33471
  init_format();
@@ -33725,7 +33666,6 @@ function subgraphTypeToTS(type) {
33725
33666
  }
33726
33667
 
33727
33668
  // src/commands/subgraphs.ts
33728
- init_api_client();
33729
33669
  init_config();
33730
33670
  init_fs();
33731
33671
  init_output();
@@ -33789,13 +33729,13 @@ init_api();
33789
33729
  function registerSubgraphsCommand(program2) {
33790
33730
  const subgraphs = program2.command("subgraphs").description("Manage materialized subgraphs");
33791
33731
  subgraphs.command("new <name>").description("Scaffold a new subgraph definition file").action(async (name) => {
33792
- const dir = resolve("subgraphs");
33793
- const filePath = resolve(dir, `${name}.ts`);
33794
- if (existsSync(filePath)) {
33732
+ const dir = resolve2("subgraphs");
33733
+ const filePath = resolve2(dir, `${name}.ts`);
33734
+ if (existsSync2(filePath)) {
33795
33735
  error(`File already exists: ${filePath}`);
33796
33736
  process.exit(1);
33797
33737
  }
33798
- if (!existsSync(dir)) {
33738
+ if (!existsSync2(dir)) {
33799
33739
  mkdirSync(dir, { recursive: true });
33800
33740
  }
33801
33741
  const content = generateSubgraphTemplate(name);
@@ -33805,8 +33745,8 @@ function registerSubgraphsCommand(program2) {
33805
33745
  });
33806
33746
  subgraphs.command("dev <file>").description("Watch a subgraph file and auto-redeploy on change").action(async (file) => {
33807
33747
  await requireLocalNetwork();
33808
- const absPath = resolve(file);
33809
- if (!existsSync(absPath)) {
33748
+ const absPath = resolve2(file);
33749
+ if (!existsSync2(absPath)) {
33810
33750
  error(`File not found: ${absPath}`);
33811
33751
  process.exit(1);
33812
33752
  }
@@ -33820,9 +33760,9 @@ function registerSubgraphsCommand(program2) {
33820
33760
  const def = mod.default ?? mod;
33821
33761
  const { validateSubgraphDefinition } = await import("@secondlayer/subgraphs/validate");
33822
33762
  const { deploySchema } = await import("@secondlayer/subgraphs");
33823
- const { getDb: getDb3 } = await import("@secondlayer/shared/db");
33763
+ const { getDb: getDb2 } = await import("@secondlayer/shared/db");
33824
33764
  validateSubgraphDefinition(def);
33825
- const db = getDb3();
33765
+ const db = getDb2();
33826
33766
  const result = await deploySchema(db, def, absPath, {
33827
33767
  forceReindex: false
33828
33768
  });
@@ -33866,7 +33806,7 @@ Stopped watching.`);
33866
33806
  });
33867
33807
  subgraphs.command("deploy <file>").description("Deploy a subgraph definition file").option("--version <semver>", "Explicit version (default: auto-increment patch)").option("--force", "Skip confirmation prompt for reindex operations").action(async (file, options2) => {
33868
33808
  try {
33869
- const absPath = resolve(file);
33809
+ const absPath = resolve2(file);
33870
33810
  const config = await loadConfig();
33871
33811
  info(`Loading subgraph from ${absPath}`);
33872
33812
  const mod = await import(absPath);
@@ -33875,8 +33815,8 @@ Stopped watching.`);
33875
33815
  validateSubgraphDefinition(def);
33876
33816
  if (config.network !== "local") {
33877
33817
  info(`Bundling for remote deploy (${config.network})...`);
33878
- const { readFile: readFile2 } = await import("node:fs/promises");
33879
- const source = await readFile2(absPath, "utf8");
33818
+ const { readFile: readFile4 } = await import("node:fs/promises");
33819
+ const source = await readFile4(absPath, "utf8");
33880
33820
  const { bundleSubgraphCode } = await import("@secondlayer/bundler");
33881
33821
  const bundled = await bundleSubgraphCode(source);
33882
33822
  const handlerCode = bundled.handlerCode;
@@ -33906,7 +33846,7 @@ Stopped watching.`);
33906
33846
  info(` + columns: ${t}.${cols.join(", ")}`);
33907
33847
  }
33908
33848
  }
33909
- const confirmed = options2.force || await confirm3({
33849
+ const confirmed = options2.force || await confirm2({
33910
33850
  message: "⚠ This will drop all data and reindex from scratch. Continue?"
33911
33851
  });
33912
33852
  if (!confirmed) {
@@ -33927,8 +33867,8 @@ Stopped watching.`);
33927
33867
  }
33928
33868
  } else {
33929
33869
  const { deploySchema } = await import("@secondlayer/subgraphs");
33930
- const { getDb: getDb3, closeDb } = await import("@secondlayer/shared/db");
33931
- const db = getDb3();
33870
+ const { getDb: getDb2, closeDb } = await import("@secondlayer/shared/db");
33871
+ const db = getDb2();
33932
33872
  const result = await deploySchema(db, def, absPath, {
33933
33873
  version: options2.version
33934
33874
  });
@@ -34148,8 +34088,8 @@ ${rows.length} row(s)`));
34148
34088
  subgraphs.command("delete <name>").description("Delete a subgraph and its data").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
34149
34089
  try {
34150
34090
  if (!options2.yes) {
34151
- const { confirm: confirm4 } = await import("@inquirer/prompts");
34152
- const ok = await confirm4({
34091
+ const { confirm: confirm3 } = await import("@inquirer/prompts");
34092
+ const ok = await confirm3({
34153
34093
  message: `Delete subgraph "${name}" and all its data? This cannot be undone.`
34154
34094
  });
34155
34095
  if (!ok) {
@@ -34200,7 +34140,7 @@ ${rows.length} row(s)`));
34200
34140
  error("--output <path> is required");
34201
34141
  process.exit(1);
34202
34142
  }
34203
- const outPath = resolve(options2.output);
34143
+ const outPath = resolve2(options2.output);
34204
34144
  const network = inferNetwork(contractAddress) ?? "mainnet";
34205
34145
  const apiKey = options2.apiKey ?? process.env.HIRO_API_KEY;
34206
34146
  info(`Fetching ABI for ${contractAddress}...`);
@@ -34212,8 +34152,8 @@ ${rows.length} row(s)`));
34212
34152
  contractId: contractAddress,
34213
34153
  functions: abi.functions
34214
34154
  });
34215
- const dir = resolve(outPath, "..");
34216
- if (!existsSync(dir))
34155
+ const dir = resolve2(outPath, "..");
34156
+ if (!existsSync2(dir))
34217
34157
  mkdirSync(dir, { recursive: true });
34218
34158
  await writeTextFile(outPath, content);
34219
34159
  success(`Created ${outPath}`);
@@ -34229,13 +34169,13 @@ ${rows.length} row(s)`));
34229
34169
  error("--output <path> is required");
34230
34170
  process.exit(1);
34231
34171
  }
34232
- const outPath = resolve(options2.output);
34172
+ const outPath = resolve2(options2.output);
34233
34173
  info(`Fetching subgraph metadata for "${subgraphName}"...`);
34234
34174
  const subgraphDetail = await getSubgraphApi(subgraphName);
34235
34175
  info("Generating typed client...");
34236
34176
  const content = await generateSubgraphConsumer(subgraphName, subgraphDetail);
34237
- const dir = resolve(outPath, "..");
34238
- if (!existsSync(dir))
34177
+ const dir = resolve2(outPath, "..");
34178
+ if (!existsSync2(dir))
34239
34179
  mkdirSync(dir, { recursive: true });
34240
34180
  await writeTextFile(outPath, content);
34241
34181
  success(`Created ${outPath}`);
@@ -34424,7 +34364,6 @@ async function stackStop(options2) {
34424
34364
  console.log("");
34425
34365
  }
34426
34366
  // src/commands/doctor.ts
34427
- init_api_client();
34428
34367
  init_config();
34429
34368
 
34430
34369
  // src/lib/health.ts
@@ -34567,6 +34506,7 @@ async function checkHealth() {
34567
34506
  }
34568
34507
 
34569
34508
  // src/commands/doctor.ts
34509
+ init_http();
34570
34510
  init_network();
34571
34511
  init_output();
34572
34512
  function registerDoctorCommand(program2) {
@@ -34581,40 +34521,36 @@ function registerDoctorCommand(program2) {
34581
34521
  }
34582
34522
  async function runHostedDoctor(jsonOutput) {
34583
34523
  const config = await loadConfig();
34584
- const apiUrl = resolveApiUrl(config);
34524
+ const apiUrl = process.env.SL_PLATFORM_API_URL ?? "https://api.secondlayer.tools";
34585
34525
  const issues = [];
34586
34526
  const results = { network: config.network, apiUrl };
34587
34527
  let apiHealthy = false;
34588
34528
  let statusData = null;
34589
34529
  try {
34590
- const res = await fetch(`${apiUrl}/status`, {
34591
- headers: authHeaders(config)
34592
- });
34593
- apiHealthy = res.ok;
34594
- if (res.ok) {
34595
- statusData = await res.json();
34596
- } else if (res.status === 401) {
34597
- issues.push("Authentication failed. Run: sl auth login");
34530
+ statusData = await httpPlatform("/status");
34531
+ apiHealthy = true;
34532
+ } catch (err) {
34533
+ if (err instanceof CliHttpError) {
34534
+ if (err.code === "SESSION_EXPIRED") {
34535
+ issues.push("Not authenticated. Run: sl login");
34536
+ } else {
34537
+ issues.push(`API error: ${err.code}`);
34538
+ }
34598
34539
  } else {
34599
- issues.push(`API returned HTTP ${res.status}`);
34540
+ issues.push(`Cannot reach API at ${apiUrl}`);
34600
34541
  }
34601
- } catch {
34602
- issues.push(`Cannot reach API at ${apiUrl}`);
34603
34542
  }
34604
34543
  results.apiHealthy = apiHealthy;
34605
34544
  let authOk = false;
34606
34545
  let account = null;
34607
34546
  try {
34608
- const res = await fetch(`${apiUrl}/api/accounts/me`, {
34609
- headers: authHeaders(config)
34610
- });
34611
- if (res.ok) {
34612
- authOk = true;
34613
- account = await res.json();
34614
- } else if (res.status === 401) {
34615
- issues.push("Not authenticated. Run: sl auth login");
34547
+ account = await getAccountProfile();
34548
+ authOk = true;
34549
+ } catch (err) {
34550
+ if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED") {
34551
+ issues.push("Not authenticated. Run: sl login");
34616
34552
  }
34617
- } catch {}
34553
+ }
34618
34554
  results.authOk = authOk;
34619
34555
  results.account = account;
34620
34556
  if (jsonOutput) {
@@ -34777,261 +34713,6 @@ async function runLocalDoctor(jsonOutput) {
34777
34713
  }
34778
34714
  console.log("");
34779
34715
  }
34780
- // src/commands/auth.ts
34781
- init_api_client();
34782
- init_config();
34783
- init_output();
34784
- import { hostname } from "node:os";
34785
- import { input } from "@inquirer/prompts";
34786
- function registerAuthCommand(program2) {
34787
- const auth = program2.command("auth").description("Manage authentication and API keys");
34788
- auth.command("login").description("Login with email via magic link").action(async () => {
34789
- const config = await loadConfig();
34790
- const apiUrl = resolveApiUrl(config);
34791
- if (!apiUrl) {
34792
- error("No API URL configured. Set network with: sl config set network testnet");
34793
- process.exit(1);
34794
- }
34795
- const email = await input({
34796
- message: "Email:",
34797
- validate: (v) => v.includes("@") || "Enter a valid email"
34798
- });
34799
- try {
34800
- const mlRes = await fetch(`${apiUrl}/api/auth/magic-link`, {
34801
- method: "POST",
34802
- headers: { "Content-Type": "application/json" },
34803
- body: JSON.stringify({ email })
34804
- });
34805
- await assertOk(mlRes);
34806
- console.log(dim("Check your email for a 6-digit login code."));
34807
- const code = await input({
34808
- message: "Code:",
34809
- validate: (v) => /^\d{6}$/.test(v.trim()) || "Enter the 6-digit code from your email"
34810
- });
34811
- const verifyRes = await fetch(`${apiUrl}/api/auth/verify`, {
34812
- method: "POST",
34813
- headers: { "Content-Type": "application/json" },
34814
- body: JSON.stringify({ code: code.trim(), email })
34815
- });
34816
- await assertOk(verifyRes);
34817
- const result = await verifyRes.json();
34818
- const sessionHeaders = {
34819
- Authorization: `Bearer ${result.sessionToken}`,
34820
- "Content-Type": "application/json"
34821
- };
34822
- const keyName = `cli-${hostname().toLowerCase()}`;
34823
- const listRes = await fetch(`${apiUrl}/api/keys`, {
34824
- headers: sessionHeaders
34825
- });
34826
- if (listRes.ok) {
34827
- const { keys: keys2 } = await listRes.json();
34828
- const existing = keys2.find((k) => k.name === keyName && k.status === "active");
34829
- if (existing) {
34830
- await fetch(`${apiUrl}/api/keys/${existing.id}`, {
34831
- method: "DELETE",
34832
- headers: sessionHeaders
34833
- });
34834
- }
34835
- }
34836
- const createRes = await fetch(`${apiUrl}/api/keys`, {
34837
- method: "POST",
34838
- headers: sessionHeaders,
34839
- body: JSON.stringify({ name: keyName })
34840
- });
34841
- await assertOk(createRes);
34842
- const { key, prefix } = await createRes.json();
34843
- config.apiKey = key;
34844
- await saveConfig(config);
34845
- try {
34846
- await fetch(`${apiUrl}/api/auth/logout`, {
34847
- method: "POST",
34848
- headers: sessionHeaders
34849
- });
34850
- } catch {}
34851
- success(`Authenticated as ${result.account.email}`);
34852
- console.log(dim(`Key: ${prefix}...`));
34853
- console.log(dim(`Network: ${config.network}`));
34854
- console.log(dim(`API: ${apiUrl}`));
34855
- } catch (err) {
34856
- error(`Login failed: ${err}`);
34857
- process.exit(1);
34858
- }
34859
- });
34860
- auth.command("logout").description("Revoke API key and remove from config").action(async () => {
34861
- const config = await loadConfig();
34862
- const apiUrl = resolveApiUrl(config);
34863
- if (!config.apiKey) {
34864
- error("Not logged in.");
34865
- process.exit(1);
34866
- }
34867
- try {
34868
- const headers = authHeaders(config);
34869
- const listRes = await fetch(`${apiUrl}/api/keys`, { headers });
34870
- if (listRes.ok) {
34871
- const { keys: keys2 } = await listRes.json();
34872
- const currentPrefix = config.apiKey.slice(0, 14);
34873
- const match = keys2.find((k) => currentPrefix.startsWith(k.prefix));
34874
- if (match) {
34875
- await fetch(`${apiUrl}/api/keys/${match.id}`, {
34876
- method: "DELETE",
34877
- headers
34878
- });
34879
- }
34880
- }
34881
- } catch {}
34882
- delete config.apiKey;
34883
- await saveConfig(config);
34884
- success("Logged out. API key revoked.");
34885
- });
34886
- auth.command("status").description("Show current auth status").action(async () => {
34887
- const config = await loadConfig();
34888
- const apiUrl = resolveApiUrl(config);
34889
- const pairs = [
34890
- ["Network", config.network],
34891
- ["API", apiUrl || "(not configured)"],
34892
- [
34893
- "API Key",
34894
- config.apiKey ? `${config.apiKey.slice(0, 14)}...` : "(none)"
34895
- ]
34896
- ];
34897
- if (config.apiKey && apiUrl) {
34898
- try {
34899
- const res = await fetch(`${apiUrl}/api/accounts/me`, {
34900
- headers: authHeaders(config)
34901
- });
34902
- if (res.ok) {
34903
- const data = await res.json();
34904
- pairs.push(["Email", data.email]);
34905
- pairs.push(["Plan", data.plan]);
34906
- }
34907
- } catch {}
34908
- }
34909
- console.log(formatKeyValue(pairs));
34910
- });
34911
- const keys = auth.command("keys").description("Manage API keys");
34912
- keys.command("list").description("List API keys for this account").action(async () => {
34913
- const config = await loadConfig();
34914
- const apiUrl = resolveApiUrl(config);
34915
- const headers = authHeaders(config);
34916
- try {
34917
- const res = await fetch(`${apiUrl}/api/keys`, { headers });
34918
- if (!res.ok)
34919
- throw new Error(`HTTP ${res.status}`);
34920
- const { keys: keyList } = await res.json();
34921
- if (keyList.length === 0) {
34922
- console.log(dim("No API keys."));
34923
- return;
34924
- }
34925
- for (const k of keyList) {
34926
- const used = k.lastUsedAt ? new Date(k.lastUsedAt).toLocaleDateString() : "never";
34927
- console.log(` ${k.prefix}... ${k.name ?? "(unnamed)"} ${k.status} last used: ${used}`);
34928
- }
34929
- } catch (err) {
34930
- error(`Failed to list keys: ${err}`);
34931
- process.exit(1);
34932
- }
34933
- });
34934
- keys.command("create").description("Create a new API key").option("--name <name>", "Name for the API key").action(async (options2) => {
34935
- const config = await loadConfig();
34936
- const apiUrl = resolveApiUrl(config);
34937
- const headers = {
34938
- ...authHeaders(config),
34939
- "Content-Type": "application/json"
34940
- };
34941
- try {
34942
- const res = await fetch(`${apiUrl}/api/keys`, {
34943
- method: "POST",
34944
- headers,
34945
- body: JSON.stringify({ name: options2.name })
34946
- });
34947
- await assertOk(res);
34948
- const { key, prefix } = await res.json();
34949
- success(`Created API key: ${prefix}...`);
34950
- console.log();
34951
- console.log(` ${key}`);
34952
- console.log();
34953
- console.log(dim("Save this key — it won't be shown again."));
34954
- } catch (err) {
34955
- error(`Failed to create key: ${err}`);
34956
- process.exit(1);
34957
- }
34958
- });
34959
- keys.command("revoke <id>").description("Revoke an API key by ID or prefix").action(async (idOrPrefix) => {
34960
- const config = await loadConfig();
34961
- const apiUrl = resolveApiUrl(config);
34962
- const headers = authHeaders(config);
34963
- try {
34964
- let keyId = idOrPrefix;
34965
- if (!idOrPrefix.includes("-")) {
34966
- const listRes = await fetch(`${apiUrl}/api/keys`, { headers });
34967
- if (!listRes.ok)
34968
- throw new Error(`HTTP ${listRes.status}`);
34969
- const { keys: keyList } = await listRes.json();
34970
- const match = keyList.find((k) => k.prefix.startsWith(idOrPrefix) || k.prefix === idOrPrefix);
34971
- if (!match) {
34972
- error(`No key found matching "${idOrPrefix}"`);
34973
- process.exit(1);
34974
- }
34975
- keyId = match.id;
34976
- }
34977
- const res = await fetch(`${apiUrl}/api/keys/${keyId}`, {
34978
- method: "DELETE",
34979
- headers
34980
- });
34981
- await assertOk(res);
34982
- success(`Revoked key ${idOrPrefix}`);
34983
- } catch (err) {
34984
- error(`Failed to revoke key: ${err}`);
34985
- process.exit(1);
34986
- }
34987
- });
34988
- const defaultKeyName = `cli-${hostname().toLowerCase()}`;
34989
- keys.command("rotate").description("Revoke current API key and create a new one").option("--name <name>", "Name for the new API key", defaultKeyName).action(async (options2) => {
34990
- await rotateKey(options2);
34991
- });
34992
- auth.command("rotate").description("Revoke current API key and create a new one").option("--name <name>", "Name for the new API key", defaultKeyName).action(async (options2) => {
34993
- await rotateKey(options2);
34994
- });
34995
- }
34996
- async function rotateKey(options2) {
34997
- const config = await loadConfig();
34998
- const apiUrl = resolveApiUrl(config);
34999
- const headers = authHeaders(config);
35000
- if (!config.apiKey) {
35001
- error("Not logged in. Run `sl auth login` first.");
35002
- process.exit(1);
35003
- }
35004
- try {
35005
- if (config.apiKey) {
35006
- const listRes = await fetch(`${apiUrl}/api/keys`, { headers });
35007
- if (listRes.ok) {
35008
- const { keys } = await listRes.json();
35009
- const currentPrefix = config.apiKey.slice(0, 14);
35010
- const current = keys.find((k) => currentPrefix.startsWith(k.prefix));
35011
- if (current) {
35012
- await fetch(`${apiUrl}/api/keys/${current.id}`, {
35013
- method: "DELETE",
35014
- headers
35015
- });
35016
- console.log(dim(`Revoked old key: ${current.prefix}...`));
35017
- }
35018
- }
35019
- }
35020
- const createRes = await fetch(`${apiUrl}/api/keys`, {
35021
- method: "POST",
35022
- headers: { ...headers, "Content-Type": "application/json" },
35023
- body: JSON.stringify({ name: options2.name })
35024
- });
35025
- await assertOk(createRes);
35026
- const { key, prefix } = await createRes.json();
35027
- config.apiKey = key;
35028
- await saveConfig(config);
35029
- success(`Rotated to new key ${prefix}...`);
35030
- } catch (err) {
35031
- error(`Rotation failed: ${err}`);
35032
- process.exit(1);
35033
- }
35034
- }
35035
34716
  // src/commands/local.ts
35036
34717
  init_config();
35037
34718
  init_dev_state();
@@ -35301,7 +34982,6 @@ function formatLogLine3(service, line) {
35301
34982
  return `${prefix} ${line}`;
35302
34983
  }
35303
34984
  // src/commands/marketplace.ts
35304
- init_api_client();
35305
34985
  init_output();
35306
34986
  function registerMarketplaceCommand(program2) {
35307
34987
  const marketplace = program2.command("marketplace").alias("mp").description("Browse the public subgraph marketplace");
@@ -35344,7 +35024,10 @@ ${result.meta.total} subgraph(s) total`));
35344
35024
  console.log(formatKeyValue([
35345
35025
  ["Name", detail.name],
35346
35026
  ["Description", detail.description ?? dim("—")],
35347
- ["Creator", detail.creator?.displayName ?? detail.creator?.slug ?? dim("—")],
35027
+ [
35028
+ "Creator",
35029
+ detail.creator?.displayName ?? detail.creator?.slug ?? dim("—")
35030
+ ],
35348
35031
  ["Status", detail.status],
35349
35032
  ["Version", detail.version],
35350
35033
  ["Tags", (detail.tags ?? []).join(", ") || dim("—")],
@@ -35382,290 +35065,464 @@ Endpoints:`));
35382
35065
  });
35383
35066
  }
35384
35067
  // src/commands/whoami.ts
35385
- init_api_client();
35386
35068
  init_config();
35069
+ init_http();
35387
35070
  init_output();
35071
+ init_project_file();
35072
+ init_session();
35388
35073
  function registerWhoamiCommand(program2) {
35389
- program2.command("whoami").description("Show current authenticated account").action(async () => {
35390
- const config = await loadConfig();
35391
- const apiUrl = resolveApiUrl(config);
35392
- if (!config.apiKey) {
35393
- error("Not authenticated. Run: sl auth login");
35394
- process.exit(1);
35074
+ program2.command("whoami").description("Show current authenticated account + active project + tenant").action(async () => {
35075
+ const session = await readSession();
35076
+ if (!session) {
35077
+ error("Not logged in. Run: sl login");
35078
+ process.exit(0);
35395
35079
  }
35080
+ const rows = [];
35081
+ rows.push(["Email", session.email]);
35396
35082
  try {
35397
- const res = await fetch(`${apiUrl}/api/accounts/me`, {
35398
- headers: authHeaders(config)
35399
- });
35400
- if (res.status === 401) {
35401
- error("Not authenticated. Run: sl auth login");
35083
+ const account = await httpPlatform("/api/accounts/me");
35084
+ rows.push(["Plan", account.plan]);
35085
+ } catch (err) {
35086
+ if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED") {
35087
+ error("Session expired. Run: sl login");
35402
35088
  process.exit(1);
35403
35089
  }
35404
- if (!res.ok) {
35405
- throw new Error(`HTTP ${res.status}`);
35406
- }
35407
- const data = await res.json();
35408
- console.log(formatKeyValue([
35409
- ["Email", data.email],
35410
- ["Plan", data.plan],
35411
- ["Network", config.network],
35412
- ["API", dim(apiUrl)]
35413
- ]));
35414
- } catch (err) {
35415
- error(`Failed to fetch account: ${err}`);
35416
- process.exit(1);
35090
+ throw err;
35417
35091
  }
35092
+ const config = await loadConfig();
35093
+ const active = await readActiveProject(process.cwd(), config.defaultProject);
35094
+ if (active) {
35095
+ rows.push(["Project", active.slug]);
35096
+ rows.push(["Project source", dim(active.resolvedFrom)]);
35097
+ } else {
35098
+ rows.push(["Project", dim("(none — run `sl project create <name>`)")]);
35099
+ }
35100
+ try {
35101
+ const tenant = await httpPlatform("/api/tenants/me");
35102
+ if (tenant.tenant) {
35103
+ const trialDays = Math.max(0, Math.ceil((new Date(tenant.tenant.trialEndsAt).getTime() - Date.now()) / (24 * 60 * 60 * 1000)));
35104
+ rows.push(["Instance", tenant.tenant.apiUrl]);
35105
+ rows.push(["Status", tenant.tenant.status]);
35106
+ rows.push([
35107
+ "Trial",
35108
+ `${trialDays} day${trialDays === 1 ? "" : "s"} left`
35109
+ ]);
35110
+ } else {
35111
+ rows.push([
35112
+ "Instance",
35113
+ dim("(none — run `sl instance create --plan launch`)")
35114
+ ]);
35115
+ }
35116
+ } catch {}
35117
+ console.log(formatKeyValue(rows));
35418
35118
  });
35419
35119
  }
35420
- // src/commands/workflows.ts
35421
- init_config();
35120
+ // src/commands/login.ts
35121
+ init_http();
35422
35122
  init_output();
35423
- import { existsSync as existsSync2 } from "node:fs";
35424
- import { resolve as resolve7 } from "node:path";
35425
- import { SecondLayer as SecondLayer2 } from "@secondlayer/sdk";
35426
- function formatValidationError(err) {
35427
- if (err != null && typeof err === "object" && "issues" in err && Array.isArray(err.issues)) {
35428
- error("Workflow validation failed:");
35429
- for (const issue of err.issues) {
35430
- const path = issue.path?.length ? issue.path.join(".") : "(root)";
35431
- error(` ${path}: ${issue.message}`);
35432
- }
35433
- } else {
35434
- error(`Failed to validate workflow: ${err}`);
35435
- }
35436
- }
35437
- function getClient2() {
35438
- const apiKey = process.env.SECONDLAYER_API_KEY;
35439
- if (!apiKey) {
35440
- error("SECONDLAYER_API_KEY required. Run: sl auth login");
35441
- process.exit(1);
35442
- }
35443
- return new SecondLayer2({ apiKey });
35444
- }
35445
- function registerWorkflowsCommand(program2) {
35446
- const workflows = program2.command("workflows").description("Manage workflows");
35447
- workflows.command("deploy <file>").description("Validate and deploy a workflow definition file").action(async (file) => {
35123
+ init_session();
35124
+ import { input as input2 } from "@inquirer/prompts";
35125
+ function registerLoginCommand(program2) {
35126
+ program2.command("login").description("Log in to Secondlayer (magic-link email)").action(async () => {
35127
+ const email = await input2({
35128
+ message: "Email",
35129
+ validate: (v) => /^.+@.+\..+$/.test(v) ? true : "Invalid email"
35130
+ });
35448
35131
  try {
35449
- const absPath = resolve7(file);
35450
- if (!existsSync2(absPath)) {
35451
- error(`File not found: ${absPath}`);
35452
- process.exit(1);
35132
+ const res = await httpPlatformAnon("/api/auth/magic-link", {
35133
+ method: "POST",
35134
+ body: { email }
35135
+ });
35136
+ info("Check your inbox for a 6-digit code.");
35137
+ if (res.code) {
35138
+ info(dim(`(DEV_MODE code: ${res.code})`));
35453
35139
  }
35454
- info(`Loading workflow from ${absPath}`);
35455
- const mod = await import(absPath);
35456
- const def = mod.default ?? mod;
35457
- const { validateWorkflowDefinition } = await import("@secondlayer/workflows/validate");
35458
- const result = validateWorkflowDefinition(def);
35459
- const config = await loadConfig();
35460
- if (config.network !== "local") {
35461
- info(`Bundling for remote deploy (${config.network})...`);
35462
- const { readFile: readFile2 } = await import("node:fs/promises");
35463
- const source = await readFile2(absPath, "utf8");
35464
- const { bundleWorkflowCode } = await import("@secondlayer/bundler");
35465
- const bundled = await bundleWorkflowCode(source);
35466
- const deployResult = await getClient2().workflows.deploy({
35467
- name: bundled.name,
35468
- trigger: bundled.trigger,
35469
- handlerCode: bundled.handlerCode,
35470
- sourceCode: bundled.sourceCode,
35471
- retries: bundled.retries,
35472
- timeout: bundled.timeout
35473
- });
35474
- success(`Workflow "${def.name}" ${deployResult.action} → v${deployResult.version} (remote)`);
35140
+ } catch (err) {
35141
+ if (err instanceof CliHttpError) {
35142
+ error(err.message);
35475
35143
  } else {
35476
- success(`Workflow "${result.name}" is valid`);
35477
- info(`Trigger: ${result.trigger.type}`);
35478
- if (result.retries) {
35479
- info(`Retries: maxAttempts=${result.retries.maxAttempts ?? "default"}`);
35480
- }
35481
- if (result.timeout) {
35482
- info(`Timeout: ${result.timeout}ms`);
35483
- }
35144
+ error(err instanceof Error ? err.message : String(err));
35484
35145
  }
35485
- } catch (err) {
35486
- formatValidationError(err);
35487
35146
  process.exit(1);
35488
35147
  }
35489
- });
35490
- workflows.command("validate <file>").description("Validate a workflow definition without deploying").action(async (file) => {
35148
+ const code = await input2({
35149
+ message: "Enter the 6-digit code",
35150
+ validate: (v) => /^\d{6}$/.test(v) ? true : "Expected 6 digits"
35151
+ });
35491
35152
  try {
35492
- const absPath = resolve7(file);
35493
- if (!existsSync2(absPath)) {
35494
- error(`File not found: ${absPath}`);
35495
- process.exit(1);
35496
- }
35497
- const mod = await import(absPath);
35498
- const def = mod.default ?? mod;
35499
- const { validateWorkflowDefinition } = await import("@secondlayer/workflows/validate");
35500
- const result = validateWorkflowDefinition(def);
35501
- success(`Workflow "${result.name}" is valid`);
35502
- info(`Trigger: ${result.trigger.type}`);
35503
- if (result.retries) {
35504
- info(`Retries: maxAttempts=${result.retries.maxAttempts ?? "default"}, backoffMs=${result.retries.backoffMs ?? 1000}, multiplier=${result.retries.backoffMultiplier ?? 2}`);
35505
- }
35506
- if (result.timeout) {
35507
- info(`Timeout: ${result.timeout}ms`);
35508
- }
35153
+ const verified = await httpPlatformAnon("/api/auth/verify", {
35154
+ method: "POST",
35155
+ body: { email, code }
35156
+ });
35157
+ const expiresAt = new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString();
35158
+ await writeSession({
35159
+ token: verified.sessionToken,
35160
+ email: verified.account.email,
35161
+ accountId: verified.account.id,
35162
+ expiresAt
35163
+ });
35164
+ success(`Logged in as ${verified.account.email}`);
35165
+ info(dim("Run 'sl whoami' to see your account status."));
35509
35166
  } catch (err) {
35510
- formatValidationError(err);
35167
+ if (err instanceof CliHttpError) {
35168
+ error(err.message);
35169
+ } else {
35170
+ error(err instanceof Error ? err.message : String(err));
35171
+ }
35511
35172
  process.exit(1);
35512
35173
  }
35513
35174
  });
35514
- workflows.command("list").alias("ls").description("List all workflows").option("--json", "Output as JSON").action(async (options2) => {
35175
+ }
35176
+ // src/commands/logout.ts
35177
+ init_http();
35178
+ init_output();
35179
+ init_session();
35180
+ function registerLogoutCommand(program2) {
35181
+ program2.command("logout").description("Log out and revoke the local session").action(async () => {
35182
+ const session = await readSession();
35183
+ if (!session) {
35184
+ info("Not logged in.");
35185
+ return;
35186
+ }
35515
35187
  try {
35516
- const { workflows: items } = await getClient2().workflows.list();
35517
- if (options2.json) {
35518
- console.log(JSON.stringify(items, null, 2));
35519
- return;
35520
- }
35521
- if (items.length === 0) {
35522
- console.log("No workflows deployed");
35523
- return;
35188
+ await httpPlatform("/api/auth/logout", { method: "POST" });
35189
+ } catch (err) {
35190
+ if (err instanceof CliHttpError) {
35191
+ warn(`Server logout failed (${err.code}) — clearing local session anyway`);
35524
35192
  }
35525
- const rows = items.map((w) => {
35526
- const statusColor = w.status === "active" ? green : yellow;
35527
- return [w.name, statusColor(w.status), w.triggerType, w.createdAt];
35193
+ }
35194
+ await clearSession();
35195
+ success("Logged out.");
35196
+ });
35197
+ }
35198
+ // src/commands/instance.ts
35199
+ init_config();
35200
+ init_http();
35201
+ init_output();
35202
+ init_project_file();
35203
+ init_resolve_tenant();
35204
+ import { confirm as confirm4, input as input3, select as select3 } from "@inquirer/prompts";
35205
+ function registerInstanceCommand(program2) {
35206
+ const instance = program2.command("instance").description("Manage your dedicated Secondlayer instance");
35207
+ instance.command("create").description("Provision a new dedicated instance for the active project").option("--plan <plan>", "Plan: launch | grow | scale", "launch").action(async (opts) => {
35208
+ guardOssMode();
35209
+ const activeSlug = await requireActiveProject();
35210
+ const plan = opts.plan;
35211
+ if (!["launch", "grow", "scale"].includes(plan)) {
35212
+ error(`Invalid plan: ${plan} (expected launch, grow, or scale)`);
35213
+ process.exit(1);
35214
+ }
35215
+ try {
35216
+ const res = await httpPlatform(`/api/projects/${encodeURIComponent(activeSlug)}/instance`, {
35217
+ method: "POST",
35218
+ body: { plan }
35528
35219
  });
35529
- console.log(formatTable(["Name", "Status", "Trigger", "Created"], rows));
35530
- console.log(dim(`
35531
- ${items.length} workflow(s) total`));
35220
+ success(`Instance provisioned: ${res.tenant.slug}`);
35221
+ printKeyReveal(res.tenant, res.credentials);
35532
35222
  } catch (err) {
35533
- error(`Failed to list workflows: ${err}`);
35534
- process.exit(1);
35223
+ handleInstanceError(err, "provision instance");
35535
35224
  }
35536
35225
  });
35537
- workflows.command("get <name>").description("Get workflow details").option("--json", "Output as JSON").action(async (name, options2) => {
35538
- try {
35539
- const detail = await getClient2().workflows.get(name);
35540
- if (options2.json) {
35541
- console.log(JSON.stringify(detail, null, 2));
35226
+ instance.command("info").description("Show the active project's instance").action(async () => {
35227
+ guardOssMode();
35228
+ await renderInstanceInfo();
35229
+ });
35230
+ instance.command("resize").description("Change your instance plan (brief downtime)").option("--plan <plan>", "Target plan: launch | grow | scale").option("--yes", "Skip confirm").action(async (opts) => {
35231
+ guardOssMode();
35232
+ let target = opts.plan;
35233
+ if (!target) {
35234
+ const answer = await select3({
35235
+ message: "Target plan",
35236
+ choices: [
35237
+ {
35238
+ value: "launch",
35239
+ name: "Launch — $99/mo (1 vCPU · 2 GB · 10 GB)"
35240
+ },
35241
+ { value: "grow", name: "Grow — $249/mo (2 vCPU · 4 GB · 50 GB)" },
35242
+ {
35243
+ value: "scale",
35244
+ name: "Scale — $599/mo (4 vCPU · 8 GB · 200 GB)"
35245
+ }
35246
+ ]
35247
+ });
35248
+ target = answer;
35249
+ }
35250
+ if (!opts.yes) {
35251
+ const ok = await confirm4({
35252
+ message: `Resize to ${target}? ~30s downtime while containers recreate. Data preserved.`,
35253
+ default: false
35254
+ });
35255
+ if (!ok) {
35256
+ info("Cancelled.");
35542
35257
  return;
35543
35258
  }
35544
- console.log(formatKeyValue([
35545
- ["Name", detail.name],
35546
- ["Status", detail.status],
35547
- ["Trigger", detail.triggerType],
35548
- ["Total Runs", String(detail.totalRuns)],
35549
- ["Last Run", detail.lastRunAt ?? "never"],
35550
- ["Timeout", detail.timeout ? `${detail.timeout}ms` : "default"],
35551
- ["Created", detail.createdAt],
35552
- ["Updated", detail.updatedAt]
35553
- ]));
35259
+ }
35260
+ try {
35261
+ await httpPlatform("/api/tenants/me/resize", {
35262
+ method: "POST",
35263
+ body: { plan: target }
35264
+ });
35265
+ success(`Resized to ${target}.`);
35554
35266
  } catch (err) {
35555
- error(`Failed to get workflow: ${err}`);
35556
- process.exit(1);
35267
+ handleInstanceError(err, "resize");
35557
35268
  }
35558
35269
  });
35559
- workflows.command("trigger <name>").description("Trigger a workflow run").option("--input <json>", "Input JSON string").action(async (name, options2) => {
35270
+ instance.command("suspend").description("Stop your instance (data preserved)").action(async () => {
35271
+ guardOssMode();
35560
35272
  try {
35561
- const input3 = options2.input ? JSON.parse(options2.input) : undefined;
35562
- const result = await getClient2().workflows.trigger(name, input3);
35563
- success(`Triggered workflow "${name}"`);
35564
- info(`Run ID: ${result.runId}`);
35273
+ await httpPlatform("/api/tenants/me/suspend", { method: "POST" });
35274
+ success("Instance suspended.");
35565
35275
  } catch (err) {
35566
- error(`Failed to trigger workflow: ${err}`);
35567
- process.exit(1);
35276
+ handleInstanceError(err, "suspend");
35568
35277
  }
35569
35278
  });
35570
- workflows.command("runs <name>").description("List runs for a workflow").option("--status <status>", "Filter by status").option("--limit <n>", "Max runs to return", "20").option("--json", "Output as JSON").action(async (name, options2) => {
35279
+ instance.command("resume").description("Start a suspended instance").action(async () => {
35280
+ guardOssMode();
35571
35281
  try {
35572
- const { runs } = await getClient2().workflows.listRuns(name, {
35573
- status: options2.status,
35574
- limit: options2.limit ? Number.parseInt(options2.limit, 10) : undefined
35282
+ await httpPlatform("/api/tenants/me/resume", { method: "POST" });
35283
+ success("Instance resumed.");
35284
+ } catch (err) {
35285
+ handleInstanceError(err, "resume");
35286
+ }
35287
+ });
35288
+ instance.command("delete").description("Permanently delete your instance + all data").option("--yes", "Skip typed-slug confirm").action(async (opts) => {
35289
+ guardOssMode();
35290
+ const info_ = await httpPlatform("/api/tenants/me").catch(() => null);
35291
+ if (!info_?.tenant) {
35292
+ warn("No instance to delete.");
35293
+ return;
35294
+ }
35295
+ const slug = info_.tenant.slug;
35296
+ if (!opts.yes) {
35297
+ const typed = await input3({
35298
+ message: `Type the slug "${slug}" to confirm permanent deletion`,
35299
+ validate: (v) => v === slug ? true : "Slug must match exactly"
35575
35300
  });
35576
- if (options2.json) {
35577
- console.log(JSON.stringify(runs, null, 2));
35578
- return;
35579
- }
35580
- if (runs.length === 0) {
35581
- console.log("No runs found");
35301
+ if (typed !== slug)
35582
35302
  return;
35583
- }
35584
- const rows = runs.map((r) => {
35585
- const statusColor = r.status === "completed" ? green : r.status === "failed" ? (s) => `\x1B[31m${s}\x1B[0m` : yellow;
35586
- return [
35587
- r.id.slice(0, 8),
35588
- statusColor(r.status),
35589
- `${r.duration}ms`,
35590
- String(r.aiTokensUsed),
35591
- r.triggeredAt
35592
- ];
35593
- });
35594
- console.log(formatTable(["ID", "Status", "Duration", "AI Tokens", "Triggered"], rows));
35595
- console.log(dim(`
35596
- ${runs.length} run(s)`));
35303
+ }
35304
+ try {
35305
+ await httpPlatform("/api/tenants/me", { method: "DELETE" });
35306
+ success("Instance deleted.");
35597
35307
  } catch (err) {
35598
- error(`Failed to list runs: ${err}`);
35599
- process.exit(1);
35308
+ handleInstanceError(err, "delete");
35600
35309
  }
35601
35310
  });
35602
- workflows.command("pause <name>").description("Pause a workflow").action(async (name) => {
35311
+ const keys = instance.command("keys").description("Rotate long-lived keys (service, anon)");
35312
+ keys.command("rotate").description("Rotate one or both keys").option("--service", "Rotate the service key").option("--anon", "Rotate the anon key").option("--both", "Rotate both keys (nuclear)").action(async (opts) => {
35313
+ guardOssMode();
35314
+ let type;
35315
+ if (opts.both || opts.service && opts.anon)
35316
+ type = "both";
35317
+ else if (opts.service)
35318
+ type = "service";
35319
+ else if (opts.anon)
35320
+ type = "anon";
35321
+ else {
35322
+ const answer = await select3({
35323
+ message: "Which key(s) to rotate?",
35324
+ choices: [
35325
+ {
35326
+ value: "service",
35327
+ name: "Service key (full access, server-side)"
35328
+ },
35329
+ { value: "anon", name: "Anon key (read-only, client-safe)" },
35330
+ {
35331
+ value: "both",
35332
+ name: "Both (nuclear — offboarding/leak response)"
35333
+ }
35334
+ ]
35335
+ });
35336
+ type = answer;
35337
+ }
35603
35338
  try {
35604
- await getClient2().workflows.pause(name);
35605
- success(`Paused workflow "${name}"`);
35339
+ const res = await httpPlatform("/api/tenants/me/keys/rotate", {
35340
+ method: "POST",
35341
+ body: { type }
35342
+ });
35343
+ success(`${type === "both" ? "Keys" : `${type} key`} rotated.`);
35344
+ const rows = [];
35345
+ if (res.rotated.serviceKey)
35346
+ rows.push(["New service key", res.rotated.serviceKey]);
35347
+ if (res.rotated.anonKey)
35348
+ rows.push(["New anon key", res.rotated.anonKey]);
35349
+ console.log("");
35350
+ console.log(warn_box("⚠ Shown once. Save these now — we can't retrieve them later."));
35351
+ console.log("");
35352
+ console.log(formatKeyValue(rows));
35353
+ console.log("");
35606
35354
  } catch (err) {
35607
- error(`Failed to pause workflow: ${err}`);
35355
+ handleInstanceError(err, "rotate keys");
35356
+ }
35357
+ });
35358
+ }
35359
+ function guardOssMode() {
35360
+ if (isOssMode()) {
35361
+ error("`sl instance` commands are for hosted deployments. For OSS use `sl local` / `sl stack` or your own provisioning.");
35362
+ process.exit(1);
35363
+ }
35364
+ }
35365
+ async function requireActiveProject() {
35366
+ const config = await loadConfig();
35367
+ const active = await readActiveProject(process.cwd(), config.defaultProject);
35368
+ if (!active) {
35369
+ error("No active project — run `sl project create <name>` or `sl project use <slug>` first.");
35370
+ process.exit(1);
35371
+ }
35372
+ return active.slug;
35373
+ }
35374
+ async function renderInstanceInfo() {
35375
+ try {
35376
+ const res = await httpPlatform("/api/tenants/me");
35377
+ if (!res.tenant) {
35378
+ info("No instance for the active project. Run `sl instance create --plan launch`.");
35379
+ return;
35380
+ }
35381
+ const t = res.tenant;
35382
+ const trialDays = Math.max(0, Math.ceil((new Date(t.trialEndsAt).getTime() - Date.now()) / (24 * 60 * 60 * 1000)));
35383
+ console.log(formatKeyValue([
35384
+ ["URL", t.apiUrl],
35385
+ ["Plan", t.plan],
35386
+ ["Status", t.status],
35387
+ ["Trial", `${trialDays} day${trialDays === 1 ? "" : "s"} left`],
35388
+ ["Created", new Date(t.createdAt).toLocaleString()]
35389
+ ]));
35390
+ } catch (err) {
35391
+ handleInstanceError(err, "fetch instance");
35392
+ }
35393
+ }
35394
+ function printKeyReveal(tenant, creds) {
35395
+ console.log("");
35396
+ console.log(blue("━".repeat(60)));
35397
+ console.log(blue(" Save your keys — shown once. Can't retrieve later."));
35398
+ console.log(blue("━".repeat(60)));
35399
+ console.log("");
35400
+ console.log(formatKeyValue([
35401
+ ["URL", creds.apiUrl],
35402
+ ["Plan", tenant.plan],
35403
+ ["Service key", green(creds.serviceKey)],
35404
+ ["Anon key", green(creds.anonKey)]
35405
+ ]));
35406
+ console.log("");
35407
+ console.log(dim("Run `sl subgraphs deploy <file>` to deploy your first subgraph."));
35408
+ console.log("");
35409
+ }
35410
+ function warn_box(message) {
35411
+ return `${"━".repeat(message.length + 4)}
35412
+ ${message}
35413
+ ${"━".repeat(message.length + 4)}`;
35414
+ }
35415
+ function handleInstanceError(err, action) {
35416
+ if (err instanceof CliHttpError) {
35417
+ if (err.code === "SESSION_EXPIRED") {
35418
+ error("Session expired. Run: sl login");
35419
+ process.exit(1);
35420
+ }
35421
+ if (err.code === "TRIAL_EXPIRED") {
35422
+ error(err.message);
35423
+ error("Add a payment method at the dashboard to keep your instance running.");
35424
+ process.exit(1);
35425
+ }
35426
+ if (err.code === "TENANT_SUSPENDED") {
35427
+ error("Instance is suspended. Run: sl instance resume");
35428
+ process.exit(1);
35429
+ }
35430
+ if (err.code === "INSTANCE_EXISTS") {
35431
+ error("This project already has an instance. Run `sl instance info` to see it.");
35608
35432
  process.exit(1);
35609
35433
  }
35434
+ error(err.message);
35435
+ process.exit(1);
35436
+ }
35437
+ error(`Failed to ${action}: ${err instanceof Error ? err.message : String(err)}`);
35438
+ process.exit(1);
35439
+ }
35440
+ // src/commands/project.ts
35441
+ init_config();
35442
+ init_http();
35443
+ init_output();
35444
+ init_project_file();
35445
+ import { input as input4 } from "@inquirer/prompts";
35446
+ function registerProjectCommand(program2) {
35447
+ const project = program2.command("project").description("Manage Secondlayer projects");
35448
+ project.command("create [name]").description("Create a new project").action(async (nameArg) => {
35449
+ const name = nameArg ?? await input4({
35450
+ message: "Project name",
35451
+ validate: (v) => v.length >= 2 ? true : "Name must be at least 2 characters"
35452
+ });
35453
+ try {
35454
+ const res = await httpPlatform("/api/projects", { method: "POST", body: { name } });
35455
+ success(`Created project ${res.project.name} (${res.project.slug})`);
35456
+ const path = await writeActiveProject(res.project.slug, process.cwd());
35457
+ info(dim(`Bound to this directory → ${path}`));
35458
+ info(dim(`Next: sl instance create --plan launch`));
35459
+ } catch (err) {
35460
+ handleProjectError(err);
35461
+ }
35610
35462
  });
35611
- workflows.command("resume <name>").description("Resume a paused workflow").action(async (name) => {
35463
+ project.command("list").description("List projects in your account").action(async () => {
35612
35464
  try {
35613
- await getClient2().workflows.resume(name);
35614
- success(`Resumed workflow "${name}"`);
35465
+ const res = await httpPlatform("/api/projects");
35466
+ if (res.projects.length === 0) {
35467
+ info("No projects yet — run `sl project create <name>` to start.");
35468
+ return;
35469
+ }
35470
+ const active = await readActiveProject(process.cwd(), (await loadConfig()).defaultProject);
35471
+ const rows = res.projects.map((p) => [
35472
+ p.slug === active?.slug ? `* ${p.slug}` : ` ${p.slug}`,
35473
+ p.name,
35474
+ p.network,
35475
+ new Date(p.createdAt).toLocaleDateString()
35476
+ ]);
35477
+ console.log(formatTable(["", "Name", "Network", "Created"], rows));
35478
+ if (active) {
35479
+ console.log(dim(`Active: ${active.slug} (from ${active.resolvedFrom})`));
35480
+ }
35615
35481
  } catch (err) {
35616
- error(`Failed to resume workflow: ${err}`);
35617
- process.exit(1);
35482
+ handleProjectError(err);
35618
35483
  }
35619
35484
  });
35620
- workflows.command("templates [id]").description("List workflow templates, or print a template's source to stdout").option("--json", "Output as JSON (list mode only)").action(async (id, options2) => {
35621
- const { templates, getTemplateById } = await import("@secondlayer/workflows/templates");
35622
- if (id) {
35623
- const template = getTemplateById(id);
35624
- if (!template) {
35625
- error(`Template not found: ${id}`);
35626
- info(`Available: ${templates.map((t) => t.id).join(", ")}`);
35485
+ project.command("use <slug>").description("Bind this directory to a project (writes ./.secondlayer/project)").action(async (slug) => {
35486
+ try {
35487
+ await httpPlatform(`/api/projects/${encodeURIComponent(slug)}`);
35488
+ } catch (err) {
35489
+ if (err instanceof CliHttpError && err.status === 404) {
35490
+ error(`Project "${slug}" not found — run 'sl project list' to see available projects`);
35627
35491
  process.exit(1);
35628
35492
  }
35629
- process.stdout.write(template.code);
35630
- return;
35493
+ handleProjectError(err);
35631
35494
  }
35632
- if (options2.json) {
35633
- console.log(JSON.stringify(templates.map(({ code: _code, ...rest }) => rest), null, 2));
35495
+ const path = await writeActiveProject(slug, process.cwd());
35496
+ success(`Bound to project "${slug}"`);
35497
+ info(dim(`Written to ${path}`));
35498
+ });
35499
+ project.command("current").description("Show the active project for this directory").action(async () => {
35500
+ const config = await loadConfig();
35501
+ const active = await readActiveProject(process.cwd(), config.defaultProject);
35502
+ if (!active) {
35503
+ info("No active project.");
35504
+ info(dim("Run 'sl project create <name>' or 'sl project use <slug>'."));
35634
35505
  return;
35635
35506
  }
35636
- const rows = templates.map((t) => [
35637
- t.id,
35638
- t.category,
35639
- t.trigger,
35640
- t.description
35641
- ]);
35642
- console.log(formatTable(["Id", "Category", "Trigger", "Description"], rows));
35643
- console.log(dim(`
35644
- ${templates.length} template(s). Pipe source with: sl workflows templates <id> > workflows/<name>.ts`));
35507
+ console.log(active.slug);
35508
+ console.log(dim(`(from ${active.resolvedFrom})`));
35645
35509
  });
35646
- workflows.command("delete <name>").description("Delete a workflow").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
35647
- try {
35648
- if (!options2.yes) {
35649
- const { confirm: confirm5 } = await import("@inquirer/prompts");
35650
- const ok = await confirm5({
35651
- message: `Delete workflow "${name}"? This cannot be undone.`
35652
- });
35653
- if (!ok) {
35654
- info("Cancelled");
35655
- return;
35656
- }
35657
- }
35658
- await getClient2().workflows.delete(name);
35659
- success(`Deleted workflow "${name}"`);
35660
- } catch (err) {
35661
- error(`Failed to delete workflow: ${err}`);
35510
+ }
35511
+ function handleProjectError(err) {
35512
+ if (err instanceof CliHttpError) {
35513
+ if (err.code === "SESSION_EXPIRED") {
35514
+ error("Session expired. Run: sl login");
35662
35515
  process.exit(1);
35663
35516
  }
35664
- });
35517
+ error(err.message);
35518
+ process.exit(1);
35519
+ }
35520
+ error(err instanceof Error ? err.message : String(err));
35521
+ process.exit(1);
35665
35522
  }
35666
35523
  // src/cli.ts
35667
35524
  var { version } = package_default;
35668
- program.name("secondlayer").alias("sl").description("SecondLayer CLI — subgraphs, workflows, and real-time indexing for Stacks").version(version).option("--network <network>", "Override network (local, testnet, mainnet)");
35525
+ program.name("secondlayer").alias("sl").description("SecondLayer CLI — dedicated Stacks indexing + real-time subgraphs").version(version).option("--network <network>", "Override network (local, testnet, mainnet)");
35669
35526
  program.hook("preAction", (thisCommand) => {
35670
35527
  const net3 = thisCommand.opts().network;
35671
35528
  if (net3)
@@ -35673,10 +35530,11 @@ program.hook("preAction", (thisCommand) => {
35673
35530
  });
35674
35531
  program.addHelpText("after", `
35675
35532
  Quickstart:
35676
- $ sl auth login # Authenticate
35677
- $ sl subgraphs new my-subgraph # Scaffold a subgraph
35678
- $ sl workflows new my-workflow # Scaffold a workflow
35679
- $ sl status # Check system health
35533
+ $ sl login # Authenticate (magic-link email)
35534
+ $ sl project create my-app # Scaffold a project (tenant + data)
35535
+ $ sl project use my-app # Bind this directory to the project
35536
+ $ sl instance create --plan launch # Provision a dedicated instance
35537
+ $ sl subgraphs deploy ./x.ts # Deploy a subgraph — targets your instance
35680
35538
  `);
35681
35539
  program.command("generate [files...]").aliases(["gen", "codegen"]).description("Generate TypeScript interfaces from Clarity contracts").option("-c, --config <path>", "Path to config file").option("-o, --out <path>", "Output file path (required when using direct files)").option("-k, --api-key <key>", "Hiro API key (or set HIRO_API_KEY env var)").option("-w, --watch", "Watch for changes").action(async (files, options3) => {
35682
35540
  const { generate: generate2 } = await Promise.resolve().then(() => (init_generate(), exports_generate));
@@ -35686,20 +35544,21 @@ program.command("init").description("Initialize a new secondlayer.config.ts file
35686
35544
  const { init: init3 } = await Promise.resolve().then(() => (init_init(), exports_init));
35687
35545
  await init3();
35688
35546
  });
35547
+ registerLoginCommand(program);
35548
+ registerLogoutCommand(program);
35549
+ registerWhoamiCommand(program);
35550
+ registerProjectCommand(program);
35551
+ registerInstanceCommand(program);
35689
35552
  registerSubgraphsCommand(program);
35690
- registerWorkflowsCommand(program);
35691
35553
  registerMarketplaceCommand(program);
35692
35554
  registerStatusCommand(program);
35693
- registerLocalCommand(program);
35694
- registerAccountCommand(program);
35695
35555
  registerStackCommand(program);
35696
35556
  registerDbCommand(program);
35697
- registerSyncCommand(program);
35698
35557
  registerDoctorCommand(program);
35699
35558
  registerConfigCommand(program);
35700
- registerAuthCommand(program);
35701
- registerWhoamiCommand(program);
35559
+ registerLocalCommand(program);
35560
+ registerAccountCommand(program);
35702
35561
  program.parse();
35703
35562
 
35704
- //# debugId=68B9BDC7A5E4D6A864756E2164756E21
35563
+ //# debugId=E8F09B3E58038C8F64756E2164756E21
35705
35564
  //# sourceMappingURL=cli.js.map