@secondlayer/cli 2.2.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/cli.js +1200 -1519
  2. package/dist/cli.js.map +23 -20
  3. package/package.json +4 -4
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 = (input4) => {
15433
- let value = `${input4}`;
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 = (input4, maxLength, toNumber) => {
15476
+ var pad = (input5, maxLength, toNumber) => {
15450
15477
  if (maxLength > 0) {
15451
- let dash = input4[0] === "-" ? "-" : "";
15478
+ let dash = input5[0] === "-" ? "-" : "";
15452
15479
  if (dash)
15453
- input4 = input4.slice(1);
15454
- input4 = dash + input4.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(input4);
15484
+ return String(input5);
15458
15485
  }
15459
- return input4;
15486
+ return input5;
15460
15487
  };
15461
- var toMaxLen = (input4, maxLength) => {
15462
- let negative = input4[0] === "-" ? "-" : "";
15488
+ var toMaxLen = (input5, maxLength) => {
15489
+ let negative = input5[0] === "-" ? "-" : "";
15463
15490
  if (negative) {
15464
- input4 = input4.slice(1);
15491
+ input5 = input5.slice(1);
15465
15492
  maxLength--;
15466
15493
  }
15467
- while (input4.length < maxLength)
15468
- input4 = "0" + input4;
15469
- return negative ? "-" + input4 : input4;
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 = (input4, options2 = {}) => {
15839
- if (typeof input4 !== "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 (input4.length > max) {
15845
- throw new SyntaxError(`Input length (${input4.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: input4, 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 = input4.length;
15879
+ const length = input5.length;
15853
15880
  let index = 0;
15854
15881
  let depth = 0;
15855
15882
  let value;
15856
- const advance = () => input4[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 = (input4, options2 = {}) => {
16078
+ var braces = (input5, options2 = {}) => {
16052
16079
  let output = [];
16053
- if (Array.isArray(input4)) {
16054
- for (const pattern of input4) {
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(input4, 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 = (input4, options2 = {}) => parse2(input4, options2);
16071
- braces.stringify = (input4, options2 = {}) => {
16072
- if (typeof input4 === "string") {
16073
- return stringify2(braces.parse(input4, 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(input4, options2);
16102
+ return stringify2(input5, options2);
16076
16103
  };
16077
- braces.compile = (input4, options2 = {}) => {
16078
- if (typeof input4 === "string") {
16079
- input4 = braces.parse(input4, options2);
16104
+ braces.compile = (input5, options2 = {}) => {
16105
+ if (typeof input5 === "string") {
16106
+ input5 = braces.parse(input5, options2);
16080
16107
  }
16081
- return compile(input4, options2);
16108
+ return compile(input5, options2);
16082
16109
  };
16083
- braces.expand = (input4, options2 = {}) => {
16084
- if (typeof input4 === "string") {
16085
- input4 = braces.parse(input4, options2);
16110
+ braces.expand = (input5, options2 = {}) => {
16111
+ if (typeof input5 === "string") {
16112
+ input5 = braces.parse(input5, options2);
16086
16113
  }
16087
- let result = expand(input4, 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 = (input4, options2 = {}) => {
16097
- if (input4 === "" || input4.length < 3) {
16098
- return [input4];
16123
+ braces.create = (input5, options2 = {}) => {
16124
+ if (input5 === "" || input5.length < 3) {
16125
+ return [input5];
16099
16126
  }
16100
- return options2.expand !== true ? braces.compile(input4, options2) : braces.expand(input4, 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 = (input4, char, lastIdx) => {
16279
- const idx = input4.lastIndexOf(char, lastIdx);
16305
+ exports.escapeLast = (input5, char, lastIdx) => {
16306
+ const idx = input5.lastIndexOf(char, lastIdx);
16280
16307
  if (idx === -1)
16281
- return input4;
16282
- if (input4[idx - 1] === "\\")
16283
- return exports.escapeLast(input4, char, idx - 1);
16284
- return `${input4.slice(0, idx)}\\${input4.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 = (input4, state = {}) => {
16287
- let output = input4;
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 = (input4, state = {}, options2 = {}) => {
16321
+ exports.wrapOutput = (input5, state = {}, options2 = {}) => {
16295
16322
  const prepend = options2.contains ? "" : "^";
16296
16323
  const append = options2.contains ? "" : "$";
16297
- let output = `${prepend}(?:${input4})${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 = (input4, options2) => {
16360
+ var scan = (input5, options2) => {
16334
16361
  const opts = options2 || {};
16335
- const length = input4.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 = input4;
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: input4,
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 = input4.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 < input4.length) {
16604
- const value = input4.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 = (input4, options2) => {
16648
- if (typeof input4 !== "string") {
16674
+ var parse2 = (input5, options2) => {
16675
+ if (typeof input5 !== "string") {
16649
16676
  throw new TypeError("Expected a string");
16650
16677
  }
16651
- input4 = REPLACEMENTS[input4] || input4;
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 = input4.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: input4,
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
- input4 = utils.removePrefix(input4, state);
16708
- len = input4.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) => input4[state.index + n];
16716
- const advance = state.advance = () => input4[++state.index] || "";
16717
- const remaining = () => input4.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(input4)) {
16834
+ if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input5)) {
16808
16835
  let backslashes = false;
16809
- let output = input4.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 === input4 && opts.contains === true) {
16844
- state.output = input4;
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 = input4[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 = (input4, 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 = input4.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
- input4 = REPLACEMENTS[input4] || input4;
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(input4, 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((input4) => picomatch(input4, 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 = (input4, returnObject = false) => {
17434
- const { isMatch, match, output } = picomatch.test(input4, regex, options2, { glob, posix });
17435
- const result = { glob, state, regex, posix, input: input4, 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(input4)) {
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 = (input4, regex, options2, { glob, posix } = {}) => {
17461
- if (typeof input4 !== "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 (input4 === "") {
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 = input4 === glob;
17470
- let output = match && format ? format(input4) : input4;
17496
+ let match = input5 === glob;
17497
+ let output = match && format ? format(input5) : input5;
17471
17498
  if (match === false) {
17472
- output = format ? format(input4) : input4;
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(input4, 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 = (input4, 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(input4));
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 = (input4, options2) => scan(input4, 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 = (input4, options2 = {}, returnOutput = false, returnState = false) => {
17513
- if (!input4 || typeof input4 !== "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 && (input4[0] === "." || input4[0] === "*")) {
17518
- parsed.output = parse2.fastpaths(input4, 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(input4, 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, input4, 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(input4) : input4);
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(input4) {
18006
- return typeof input4 === "string";
18032
+ function isString(input5) {
18033
+ return typeof input5 === "string";
18007
18034
  }
18008
18035
  exports.isString = isString;
18009
- function isEmpty(input4) {
18010
- return input4 === "";
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(input4, settings) {
18041
- const patterns = processPatterns(input4, 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(input4, settings) {
18053
- let patterns = input4;
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(input4) {
20010
- const source = [].concat(input4);
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: (input4) => "*".repeat(input4.length) },
22379
- emoji: { scale: 2, render: (input4) => "\uD83D\uDE03".repeat(input4.length) },
22380
- invisible: { scale: 0, render: (input4) => "" },
22381
- default: { scale: 1, render: (input4) => `${input4}` }
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 = (input4, choices) => Promise.resolve(choices.filter((item) => item.title.slice(0, input4.length).toLowerCase() === input4.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 (input4) => input4;
25705
+ return (input5) => input5;
25679
25706
  }
25680
25707
  const openCode = `\x1B[${open}m`;
25681
25708
  const closeCode = `\x1B[${close}m`;
25682
- return (input4) => {
25683
- const string = input4 + "";
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(input4) {
27793
- if (typeof input4 === "string") {
27794
- return stripFinalNewlineString(input4);
27819
+ function stripFinalNewline(input5) {
27820
+ if (typeof input5 === "string") {
27821
+ return stripFinalNewlineString(input5);
27795
27822
  }
27796
- if (!(ArrayBuffer.isView(input4) && input4.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(input4);
27826
+ return stripFinalNewlineBinary(input5);
27800
27827
  }
27801
- var stripFinalNewlineString = (input4) => input4.at(-1) === LF ? input4.slice(0, input4.at(-2) === CR ? -2 : -1) : input4, stripFinalNewlineBinary = (input4) => input4.at(-1) === LF_BINARY ? input4.subarray(0, input4.at(-2) === CR_BINARY ? -2 : -1) : input4, 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: input4, inputFile }, fdNumber) => fdNumber === 0 ? [
28841
- ...handleInputOption(input4),
28867
+ var handleInputOptions = ({ input: input5, inputFile }, fdNumber) => fdNumber === 0 ? [
28868
+ ...handleInputOption(input5),
28842
28869
  ...handleInputFileOption(inputFile)
28843
- ] : [], handleInputOption = (input4) => input4 === undefined ? [] : [{
28844
- type: getInputType(input4),
28845
- value: input4,
28870
+ ] : [], handleInputOption = (input5) => input5 === undefined ? [] : [{
28871
+ type: getInputType(input5),
28872
+ value: input5,
28846
28873
  optionName: "input"
28847
- }], getInputType = (input4) => {
28848
- if (isReadableStream(input4, { checkOpen: false })) {
28874
+ }], getInputType = (input5) => {
28875
+ if (isReadableStream(input5, { checkOpen: false })) {
28849
28876
  return "nodeStream";
28850
28877
  }
28851
- if (typeof input4 === "string") {
28878
+ if (typeof input5 === "string") {
28852
28879
  return "string";
28853
28880
  }
28854
- if (isUint8Array(input4)) {
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: input4, inputFile, stdio }) => input4 === 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(input4) {
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(input4);
32110
+ return contractIdPattern.test(input5);
32084
32111
  }
32085
32112
  async function parseInputs(inputs) {
32086
32113
  const files = [];
32087
32114
  const contractIds = [];
32088
- for (const input4 of inputs) {
32089
- if (isContractAddress(input4)) {
32090
- contractIds.push(input4);
32115
+ for (const input5 of inputs) {
32116
+ if (isContractAddress(input5)) {
32117
+ contractIds.push(input5);
32091
32118
  continue;
32092
32119
  }
32093
- if (input4.includes("*") || input4.includes("?")) {
32094
- const matches = await import_fast_glob.default(input4, { 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 (input4.endsWith(".clar")) {
32103
- const absolutePath = path10.resolve(process.cwd(), input4);
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.2.0",
32413
+ version: "3.1.0",
32387
32414
  description: "CLI for subgraphs and blockchain indexing on Stacks",
32388
32415
  type: "module",
32389
32416
  bin: {
@@ -32425,10 +32452,10 @@ var package_default = {
32425
32452
  dependencies: {
32426
32453
  "@inquirer/prompts": "^8.2.0",
32427
32454
  "@secondlayer/bundler": "^0.3.0",
32428
- "@secondlayer/sdk": "^1.0.0",
32429
- "@secondlayer/shared": "^1.1.0",
32455
+ "@secondlayer/sdk": "^2.0.0",
32456
+ "@secondlayer/shared": "^2.1.0",
32430
32457
  "@secondlayer/stacks": "^0.3.0",
32431
- "@secondlayer/subgraphs": "^0.11.7",
32458
+ "@secondlayer/subgraphs": "^0.11.8",
32432
32459
  "@secondlayer/workflows": "^1.1.0",
32433
32460
  "@biomejs/js-api": "^0.7.0",
32434
32461
  "@biomejs/wasm-nodejs": "^1.9.0",
@@ -32450,8 +32477,92 @@ 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 getTenantClient() {
32525
+ const { apiUrl, ephemeralKey } = await resolveActiveTenant();
32526
+ return new SecondLayer({ baseUrl: apiUrl, apiKey: ephemeralKey });
32527
+ }
32528
+ async function listSubgraphsApi() {
32529
+ return (await getTenantClient()).subgraphs.list();
32530
+ }
32531
+ async function getSubgraphApi(name) {
32532
+ return (await getTenantClient()).subgraphs.get(name);
32533
+ }
32534
+ async function reindexSubgraphApi(name, options) {
32535
+ return (await getTenantClient()).subgraphs.reindex(name, options);
32536
+ }
32537
+ async function backfillSubgraphApi(name, options) {
32538
+ return (await getTenantClient()).subgraphs.backfill(name, options);
32539
+ }
32540
+ async function stopSubgraphApi(name) {
32541
+ return (await getTenantClient()).subgraphs.stop(name);
32542
+ }
32543
+ async function deleteSubgraphApi(name) {
32544
+ return (await getTenantClient()).subgraphs.delete(name);
32545
+ }
32546
+ async function deploySubgraphApi(data) {
32547
+ return (await getTenantClient()).subgraphs.deploy(data);
32548
+ }
32549
+ async function querySubgraphTable(name, table, params = {}) {
32550
+ return (await getTenantClient()).subgraphs.queryTable(name, table, params);
32551
+ }
32552
+ async function querySubgraphTableCount(name, table, params = {}) {
32553
+ return (await getTenantClient()).subgraphs.queryTableCount(name, table, params);
32554
+ }
32555
+ async function getSubgraphGaps(name, opts) {
32556
+ return (await getTenantClient()).subgraphs.gaps(name, opts);
32557
+ }
32558
+ async function getAccountProfile() {
32559
+ return httpPlatform("/api/accounts/me");
32560
+ }
32561
+ async function updateAccountProfile(data) {
32562
+ return httpPlatform("/api/accounts/me", { method: "PATCH", body: data });
32563
+ }
32564
+
32453
32565
  // src/commands/account.ts
32454
- init_api_client();
32455
32566
  init_output();
32456
32567
  function registerAccountCommand(program2) {
32457
32568
  const account = program2.command("account").description("Manage your account profile");
@@ -32497,8 +32608,8 @@ init_config();
32497
32608
 
32498
32609
  // src/lib/detect.ts
32499
32610
  init_docker();
32500
- import { homedir as homedir2 } from "node:os";
32501
- import { join as join2 } from "node:path";
32611
+ import { homedir as homedir4 } from "node:os";
32612
+ import { join as join4 } from "node:path";
32502
32613
  var STACKS_CONTAINER_PATTERNS = [
32503
32614
  "stacks-blockchain",
32504
32615
  "stacks-node",
@@ -32566,8 +32677,8 @@ async function findDockerComposeRoot(startPath) {
32566
32677
  let current = startPath;
32567
32678
  while (current && current !== "/") {
32568
32679
  try {
32569
- const composeYml = Bun.file(join2(current, "docker-compose.yml"));
32570
- const composeYaml = Bun.file(join2(current, "docker-compose.yaml"));
32680
+ const composeYml = Bun.file(join4(current, "docker-compose.yml"));
32681
+ const composeYaml = Bun.file(join4(current, "docker-compose.yaml"));
32571
32682
  if (await composeYml.exists() || await composeYaml.exists()) {
32572
32683
  return current;
32573
32684
  }
@@ -32614,9 +32725,9 @@ var SEARCH_PATTERNS = [
32614
32725
  "/Volumes/stacks-node",
32615
32726
  "/Volumes/*/stacks-blockchain-docker",
32616
32727
  "/Volumes/*/stacks-node",
32617
- `${homedir2()}/stacks-blockchain-docker`,
32618
- `${homedir2()}/stacks-node`,
32619
- `${homedir2()}/stacks-*`,
32728
+ `${homedir4()}/stacks-blockchain-docker`,
32729
+ `${homedir4()}/stacks-node`,
32730
+ `${homedir4()}/stacks-*`,
32620
32731
  "/opt/stacks-blockchain-docker",
32621
32732
  "/opt/stacks-node",
32622
32733
  "/opt/stacks-*"
@@ -32663,8 +32774,8 @@ async function isValidStacksNodeDir(path) {
32663
32774
  return true;
32664
32775
  }
32665
32776
  try {
32666
- const composeYml = Bun.file(join2(path, "docker-compose.yml"));
32667
- const composeYaml = Bun.file(join2(path, "docker-compose.yaml"));
32777
+ const composeYml = Bun.file(join4(path, "docker-compose.yml"));
32778
+ const composeYaml = Bun.file(join4(path, "docker-compose.yaml"));
32668
32779
  const hasCompose = await composeYml.exists() || await composeYaml.exists();
32669
32780
  if (!hasCompose) {
32670
32781
  return false;
@@ -32677,7 +32788,7 @@ async function isValidStacksNodeDir(path) {
32677
32788
  }
32678
32789
  }
32679
32790
  async function detectNetworkFromFilesystem(path) {
32680
- const envFile = Bun.file(join2(path, ".env"));
32791
+ const envFile = Bun.file(join4(path, ".env"));
32681
32792
  if (await envFile.exists()) {
32682
32793
  try {
32683
32794
  const content = await envFile.text();
@@ -32689,12 +32800,12 @@ async function detectNetworkFromFilesystem(path) {
32689
32800
  }
32690
32801
  } catch {}
32691
32802
  }
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"));
32803
+ const testnetConfig = Bun.file(join4(path, "configurations/testnet"));
32804
+ const mainnetConfig = Bun.file(join4(path, "configurations/mainnet"));
32805
+ const activeConfig = Bun.file(join4(path, "configurations/active"));
32695
32806
  if (await activeConfig.exists()) {
32696
32807
  try {
32697
- const result = await Bun.$`readlink ${join2(path, "configurations/active")}`.quiet().nothrow();
32808
+ const result = await Bun.$`readlink ${join4(path, "configurations/active")}`.quiet().nothrow();
32698
32809
  const link = result.stdout.toString().trim();
32699
32810
  if (link.includes("testnet"))
32700
32811
  return "testnet";
@@ -32707,7 +32818,7 @@ async function detectNetworkFromFilesystem(path) {
32707
32818
  }
32708
32819
  async function isComposeProjectRunning(path) {
32709
32820
  try {
32710
- const result = await Bun.$`docker compose -f ${join2(path, "docker-compose.yml")} ps -q`.quiet().nothrow();
32821
+ const result = await Bun.$`docker compose -f ${join4(path, "docker-compose.yml")} ps -q`.quiet().nothrow();
32711
32822
  return result.exitCode === 0 && result.stdout.toString().trim().length > 0;
32712
32823
  } catch {
32713
32824
  return false;
@@ -32787,9 +32898,8 @@ function registerConfigCommand(program2) {
32787
32898
  async function printConfigTree(cfg) {
32788
32899
  const defaults = getDefaultConfig();
32789
32900
  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);
32901
+ if (cfg.defaultProject) {
32902
+ printValue("defaultProject", cfg.defaultProject, false);
32793
32903
  }
32794
32904
  const resolvedDataDir = getDataDir(cfg);
32795
32905
  const dataDirDisplay = cfg.dataDir === resolvedDataDir ? cfg.dataDir : `${cfg.dataDir} ${dim(`→ ${resolvedDataDir}`)}`;
@@ -32858,30 +32968,24 @@ async function validateDatabaseConnection(url) {
32858
32968
  }
32859
32969
  }
32860
32970
  // src/commands/status.ts
32861
- init_api_client();
32862
32971
  init_config();
32972
+ init_http();
32863
32973
  init_output();
32864
32974
  function registerStatusCommand(program2) {
32865
32975
  program2.command("status").description("Show system status").option("--json", "Output as JSON").action(async (options) => {
32866
32976
  const config = await loadConfig();
32867
32977
  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();
32978
+ const status = await httpPlatform("/status");
32879
32979
  if (options.json) {
32880
32980
  console.log(JSON.stringify(status, null, 2));
32881
32981
  return;
32882
32982
  }
32883
32983
  printStatus(status);
32884
- } catch {
32984
+ } catch (err) {
32985
+ if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED") {
32986
+ console.error("Not logged in. Run: sl login");
32987
+ process.exit(1);
32988
+ }
32885
32989
  console.log("");
32886
32990
  console.log(blue("System Status"));
32887
32991
  console.log(` ${red("NOT RUNNING")}`);
@@ -32890,7 +32994,7 @@ function registerStatusCommand(program2) {
32890
32994
  console.log(dim(" API service is not running."));
32891
32995
  console.log(dim(" Start with: sl local start"));
32892
32996
  } else {
32893
- console.log(dim(` Can't reach ${config.network} API at ${resolveApiUrl(config)}`));
32997
+ console.log(dim(" Can't reach the platform API."));
32894
32998
  console.log(dim(" Check your connection or try again."));
32895
32999
  }
32896
33000
  console.log("");
@@ -32952,234 +33056,18 @@ function printStatus(status) {
32952
33056
  }
32953
33057
  console.log(dim(`Last updated: ${status.timestamp}`));
32954
33058
  }
32955
- // src/commands/sync.ts
33059
+ // src/commands/db.ts
32956
33060
  init_config();
33061
+ init_dev_state();
32957
33062
  init_output();
32958
33063
  import { confirm } from "@inquirer/prompts";
32959
- import { getDb } from "@secondlayer/shared/db";
33064
+ import { getDb, sql } from "@secondlayer/shared/db";
32960
33065
  import {
32961
33066
  countMissingBlocks,
32962
33067
  findGaps
32963
33068
  } from "@secondlayer/shared/db/queries/integrity";
32964
33069
  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
33070
  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
33071
  function registerDbCommand(program2) {
33184
33072
  const dbCmd = program2.command("db").description("Inspect indexer database tables").hook("preAction", async () => {
33185
33073
  await requireLocalNetwork();
@@ -33213,9 +33101,9 @@ function registerDbCommand(program2) {
33213
33101
  }
33214
33102
  function ensureDb() {
33215
33103
  if (!process.env.DATABASE_URL) {
33216
- process.env.DATABASE_URL = DEV_DATABASE_URL2;
33104
+ process.env.DATABASE_URL = DEV_DATABASE_URL;
33217
33105
  }
33218
- return getDb2();
33106
+ return getDb();
33219
33107
  }
33220
33108
  async function showOverview(_limit) {
33221
33109
  try {
@@ -33339,8 +33227,8 @@ async function showEvents(limit, json) {
33339
33227
  async function showGaps(limit, json) {
33340
33228
  try {
33341
33229
  const db = ensureDb();
33342
- const gaps = await findGaps2(db, limit);
33343
- const missing = await countMissingBlocks2(db);
33230
+ const gaps = await findGaps(db, limit);
33231
+ const missing = await countMissingBlocks(db);
33344
33232
  if (json) {
33345
33233
  console.log(JSON.stringify({ gaps, totalMissingBlocks: missing }, null, 2));
33346
33234
  process.exit(0);
@@ -33383,7 +33271,7 @@ async function resetDatabase(skipConfirm) {
33383
33271
  console.log(dim("Note: Subgraph configurations will be preserved."));
33384
33272
  console.log("");
33385
33273
  if (!skipConfirm) {
33386
- const confirmed = await confirm2({
33274
+ const confirmed = await confirm({
33387
33275
  message: "Are you sure you want to reset the database?",
33388
33276
  default: false
33389
33277
  });
@@ -33420,7 +33308,7 @@ async function resyncDatabase(skipConfirm, backfill) {
33420
33308
  console.log(dim("Note: Subgraph configurations will be preserved."));
33421
33309
  console.log("");
33422
33310
  if (!skipConfirm) {
33423
- const confirmed = await confirm2({
33311
+ const confirmed = await confirm({
33424
33312
  message: "Are you sure you want to resync?",
33425
33313
  default: false
33426
33314
  });
@@ -33458,7 +33346,7 @@ async function resyncDatabase(skipConfirm, backfill) {
33458
33346
  if (backfill) {
33459
33347
  console.log("");
33460
33348
  info("Starting backfill from node...");
33461
- const nodeClient = new StacksNodeClient2;
33349
+ const nodeClient = new StacksNodeClient;
33462
33350
  const healthy = await nodeClient.isHealthy();
33463
33351
  if (!healthy) {
33464
33352
  warn(`Cannot reach Stacks node at ${nodeClient.getRpcUrl()}`);
@@ -33522,9 +33410,9 @@ async function resyncDatabase(skipConfirm, backfill) {
33522
33410
  }
33523
33411
  }
33524
33412
  // 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";
33413
+ import { existsSync as existsSync2, mkdirSync, watch } from "node:fs";
33414
+ import { resolve as resolve2 } from "node:path";
33415
+ import { confirm as confirm2 } from "@inquirer/prompts";
33528
33416
 
33529
33417
  // src/generators/subgraph-scaffold.ts
33530
33418
  init_format();
@@ -33725,7 +33613,6 @@ function subgraphTypeToTS(type) {
33725
33613
  }
33726
33614
 
33727
33615
  // src/commands/subgraphs.ts
33728
- init_api_client();
33729
33616
  init_config();
33730
33617
  init_fs();
33731
33618
  init_output();
@@ -33789,13 +33676,13 @@ init_api();
33789
33676
  function registerSubgraphsCommand(program2) {
33790
33677
  const subgraphs = program2.command("subgraphs").description("Manage materialized subgraphs");
33791
33678
  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)) {
33679
+ const dir = resolve2("subgraphs");
33680
+ const filePath = resolve2(dir, `${name}.ts`);
33681
+ if (existsSync2(filePath)) {
33795
33682
  error(`File already exists: ${filePath}`);
33796
33683
  process.exit(1);
33797
33684
  }
33798
- if (!existsSync(dir)) {
33685
+ if (!existsSync2(dir)) {
33799
33686
  mkdirSync(dir, { recursive: true });
33800
33687
  }
33801
33688
  const content = generateSubgraphTemplate(name);
@@ -33805,8 +33692,8 @@ function registerSubgraphsCommand(program2) {
33805
33692
  });
33806
33693
  subgraphs.command("dev <file>").description("Watch a subgraph file and auto-redeploy on change").action(async (file) => {
33807
33694
  await requireLocalNetwork();
33808
- const absPath = resolve(file);
33809
- if (!existsSync(absPath)) {
33695
+ const absPath = resolve2(file);
33696
+ if (!existsSync2(absPath)) {
33810
33697
  error(`File not found: ${absPath}`);
33811
33698
  process.exit(1);
33812
33699
  }
@@ -33820,9 +33707,9 @@ function registerSubgraphsCommand(program2) {
33820
33707
  const def = mod.default ?? mod;
33821
33708
  const { validateSubgraphDefinition } = await import("@secondlayer/subgraphs/validate");
33822
33709
  const { deploySchema } = await import("@secondlayer/subgraphs");
33823
- const { getDb: getDb3 } = await import("@secondlayer/shared/db");
33710
+ const { getDb: getDb2 } = await import("@secondlayer/shared/db");
33824
33711
  validateSubgraphDefinition(def);
33825
- const db = getDb3();
33712
+ const db = getDb2();
33826
33713
  const result = await deploySchema(db, def, absPath, {
33827
33714
  forceReindex: false
33828
33715
  });
@@ -33866,7 +33753,7 @@ Stopped watching.`);
33866
33753
  });
33867
33754
  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
33755
  try {
33869
- const absPath = resolve(file);
33756
+ const absPath = resolve2(file);
33870
33757
  const config = await loadConfig();
33871
33758
  info(`Loading subgraph from ${absPath}`);
33872
33759
  const mod = await import(absPath);
@@ -33875,8 +33762,8 @@ Stopped watching.`);
33875
33762
  validateSubgraphDefinition(def);
33876
33763
  if (config.network !== "local") {
33877
33764
  info(`Bundling for remote deploy (${config.network})...`);
33878
- const { readFile: readFile2 } = await import("node:fs/promises");
33879
- const source = await readFile2(absPath, "utf8");
33765
+ const { readFile: readFile4 } = await import("node:fs/promises");
33766
+ const source = await readFile4(absPath, "utf8");
33880
33767
  const { bundleSubgraphCode } = await import("@secondlayer/bundler");
33881
33768
  const bundled = await bundleSubgraphCode(source);
33882
33769
  const handlerCode = bundled.handlerCode;
@@ -33906,7 +33793,7 @@ Stopped watching.`);
33906
33793
  info(` + columns: ${t}.${cols.join(", ")}`);
33907
33794
  }
33908
33795
  }
33909
- const confirmed = options2.force || await confirm3({
33796
+ const confirmed = options2.force || await confirm2({
33910
33797
  message: "⚠ This will drop all data and reindex from scratch. Continue?"
33911
33798
  });
33912
33799
  if (!confirmed) {
@@ -33927,8 +33814,8 @@ Stopped watching.`);
33927
33814
  }
33928
33815
  } else {
33929
33816
  const { deploySchema } = await import("@secondlayer/subgraphs");
33930
- const { getDb: getDb3, closeDb } = await import("@secondlayer/shared/db");
33931
- const db = getDb3();
33817
+ const { getDb: getDb2, closeDb } = await import("@secondlayer/shared/db");
33818
+ const db = getDb2();
33932
33819
  const result = await deploySchema(db, def, absPath, {
33933
33820
  version: options2.version
33934
33821
  });
@@ -34148,8 +34035,8 @@ ${rows.length} row(s)`));
34148
34035
  subgraphs.command("delete <name>").description("Delete a subgraph and its data").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
34149
34036
  try {
34150
34037
  if (!options2.yes) {
34151
- const { confirm: confirm4 } = await import("@inquirer/prompts");
34152
- const ok = await confirm4({
34038
+ const { confirm: confirm3 } = await import("@inquirer/prompts");
34039
+ const ok = await confirm3({
34153
34040
  message: `Delete subgraph "${name}" and all its data? This cannot be undone.`
34154
34041
  });
34155
34042
  if (!ok) {
@@ -34163,44 +34050,13 @@ ${rows.length} row(s)`));
34163
34050
  handleApiError(err, "delete subgraph");
34164
34051
  }
34165
34052
  });
34166
- subgraphs.command("publish <name>").description("Publish a subgraph to the marketplace").option("--tags <tags>", "Tags (comma-separated, max 5)").option("--description <desc>", "Public description (max 500 chars)").option("--json", "Output as JSON").action(async (name, options2) => {
34167
- try {
34168
- const opts = {};
34169
- if (options2.tags) {
34170
- opts.tags = options2.tags.split(",").map((t) => t.trim());
34171
- }
34172
- if (options2.description) {
34173
- opts.description = options2.description;
34174
- }
34175
- const result = await publishSubgraphApi(name, opts);
34176
- if (options2.json) {
34177
- console.log(JSON.stringify(result, null, 2));
34178
- return;
34179
- }
34180
- success(result.message);
34181
- } catch (err) {
34182
- handleApiError(err, "publish subgraph");
34183
- }
34184
- });
34185
- subgraphs.command("unpublish <name>").description("Remove a subgraph from the marketplace").option("--json", "Output as JSON").action(async (name, options2) => {
34186
- try {
34187
- const result = await unpublishSubgraphApi(name);
34188
- if (options2.json) {
34189
- console.log(JSON.stringify(result, null, 2));
34190
- return;
34191
- }
34192
- success(result.message);
34193
- } catch (err) {
34194
- handleApiError(err, "unpublish subgraph");
34195
- }
34196
- });
34197
- subgraphs.command("scaffold <contractAddress>").description("Scaffold a defineSubgraph() file from a contract ABI").option("-o, --output <path>", "Output file path (required)").option("--api-key <key>", "Hiro API key").action(async (contractAddress, options2) => {
34053
+ subgraphs.command("scaffold <contractAddress>").description("Scaffold a defineSubgraph() file from a contract ABI").option("-o, --output <path>", "Output file path (required)").option("--api-key <key>", "Hiro API key").action(async (contractAddress, options2) => {
34198
34054
  try {
34199
34055
  if (!options2.output) {
34200
34056
  error("--output <path> is required");
34201
34057
  process.exit(1);
34202
34058
  }
34203
- const outPath = resolve(options2.output);
34059
+ const outPath = resolve2(options2.output);
34204
34060
  const network = inferNetwork(contractAddress) ?? "mainnet";
34205
34061
  const apiKey = options2.apiKey ?? process.env.HIRO_API_KEY;
34206
34062
  info(`Fetching ABI for ${contractAddress}...`);
@@ -34212,8 +34068,8 @@ ${rows.length} row(s)`));
34212
34068
  contractId: contractAddress,
34213
34069
  functions: abi.functions
34214
34070
  });
34215
- const dir = resolve(outPath, "..");
34216
- if (!existsSync(dir))
34071
+ const dir = resolve2(outPath, "..");
34072
+ if (!existsSync2(dir))
34217
34073
  mkdirSync(dir, { recursive: true });
34218
34074
  await writeTextFile(outPath, content);
34219
34075
  success(`Created ${outPath}`);
@@ -34229,13 +34085,13 @@ ${rows.length} row(s)`));
34229
34085
  error("--output <path> is required");
34230
34086
  process.exit(1);
34231
34087
  }
34232
- const outPath = resolve(options2.output);
34088
+ const outPath = resolve2(options2.output);
34233
34089
  info(`Fetching subgraph metadata for "${subgraphName}"...`);
34234
34090
  const subgraphDetail = await getSubgraphApi(subgraphName);
34235
34091
  info("Generating typed client...");
34236
34092
  const content = await generateSubgraphConsumer(subgraphName, subgraphDetail);
34237
- const dir = resolve(outPath, "..");
34238
- if (!existsSync(dir))
34093
+ const dir = resolve2(outPath, "..");
34094
+ if (!existsSync2(dir))
34239
34095
  mkdirSync(dir, { recursive: true });
34240
34096
  await writeTextFile(outPath, content);
34241
34097
  success(`Created ${outPath}`);
@@ -34424,7 +34280,6 @@ async function stackStop(options2) {
34424
34280
  console.log("");
34425
34281
  }
34426
34282
  // src/commands/doctor.ts
34427
- init_api_client();
34428
34283
  init_config();
34429
34284
 
34430
34285
  // src/lib/health.ts
@@ -34567,6 +34422,7 @@ async function checkHealth() {
34567
34422
  }
34568
34423
 
34569
34424
  // src/commands/doctor.ts
34425
+ init_http();
34570
34426
  init_network();
34571
34427
  init_output();
34572
34428
  function registerDoctorCommand(program2) {
@@ -34581,40 +34437,36 @@ function registerDoctorCommand(program2) {
34581
34437
  }
34582
34438
  async function runHostedDoctor(jsonOutput) {
34583
34439
  const config = await loadConfig();
34584
- const apiUrl = resolveApiUrl(config);
34440
+ const apiUrl = process.env.SL_PLATFORM_API_URL ?? "https://api.secondlayer.tools";
34585
34441
  const issues = [];
34586
34442
  const results = { network: config.network, apiUrl };
34587
34443
  let apiHealthy = false;
34588
34444
  let statusData = null;
34589
34445
  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");
34446
+ statusData = await httpPlatform("/status");
34447
+ apiHealthy = true;
34448
+ } catch (err) {
34449
+ if (err instanceof CliHttpError) {
34450
+ if (err.code === "SESSION_EXPIRED") {
34451
+ issues.push("Not authenticated. Run: sl login");
34452
+ } else {
34453
+ issues.push(`API error: ${err.code}`);
34454
+ }
34598
34455
  } else {
34599
- issues.push(`API returned HTTP ${res.status}`);
34456
+ issues.push(`Cannot reach API at ${apiUrl}`);
34600
34457
  }
34601
- } catch {
34602
- issues.push(`Cannot reach API at ${apiUrl}`);
34603
34458
  }
34604
34459
  results.apiHealthy = apiHealthy;
34605
34460
  let authOk = false;
34606
34461
  let account = null;
34607
34462
  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");
34463
+ account = await getAccountProfile();
34464
+ authOk = true;
34465
+ } catch (err) {
34466
+ if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED") {
34467
+ issues.push("Not authenticated. Run: sl login");
34616
34468
  }
34617
- } catch {}
34469
+ }
34618
34470
  results.authOk = authOk;
34619
34471
  results.account = account;
34620
34472
  if (jsonOutput) {
@@ -34777,261 +34629,6 @@ async function runLocalDoctor(jsonOutput) {
34777
34629
  }
34778
34630
  console.log("");
34779
34631
  }
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
34632
  // src/commands/local.ts
35036
34633
  init_config();
35037
34634
  init_dev_state();
@@ -35300,437 +34897,521 @@ function formatLogLine3(service, line) {
35300
34897
  }
35301
34898
  return `${prefix} ${line}`;
35302
34899
  }
35303
- // src/commands/marketplace.ts
35304
- init_api_client();
34900
+ // src/commands/whoami.ts
34901
+ init_config();
34902
+ init_http();
35305
34903
  init_output();
35306
- function registerMarketplaceCommand(program2) {
35307
- const marketplace = program2.command("marketplace").alias("mp").description("Browse the public subgraph marketplace");
35308
- marketplace.command("browse").description("List public subgraphs").option("--tags <tags>", "Filter by tags (comma-separated)").option("--search <query>", "Search by name or description").option("--sort <field>", "Sort by: recent, popular, name", "recent").option("--limit <n>", "Max results", "20").option("--json", "Output as JSON").action(async (options2) => {
35309
- try {
35310
- const result = await browseMarketplace({
35311
- tags: options2.tags ? options2.tags.split(",").map((t) => t.trim()) : undefined,
35312
- search: options2.search,
35313
- sort: options2.sort,
35314
- limit: Number.parseInt(options2.limit ?? "20", 10)
35315
- });
35316
- if (options2.json) {
35317
- console.log(JSON.stringify(result, null, 2));
35318
- return;
35319
- }
35320
- if (result.data.length === 0) {
35321
- console.log(dim("No public subgraphs found"));
35322
- return;
35323
- }
35324
- const rows = result.data.map((s) => [
35325
- s.name,
35326
- s.creator?.displayName ?? s.creator?.slug ?? dim("—"),
35327
- (s.tags ?? []).join(", ") || dim("—"),
35328
- s.status
35329
- ]);
35330
- console.log(formatTable(["Name", "Creator", "Tags", "Status"], rows));
35331
- console.log(dim(`
35332
- ${result.meta.total} subgraph(s) total`));
35333
- } catch (err) {
35334
- handleApiError(err, "browse marketplace");
34904
+ init_project_file();
34905
+ init_session();
34906
+ function registerWhoamiCommand(program2) {
34907
+ program2.command("whoami").description("Show current authenticated account + active project + tenant").action(async () => {
34908
+ const session = await readSession();
34909
+ if (!session) {
34910
+ error("Not logged in. Run: sl login");
34911
+ process.exit(0);
35335
34912
  }
35336
- });
35337
- marketplace.command("view <name>").description("View a public subgraph's details").option("--json", "Output as JSON").action(async (name, options2) => {
34913
+ const rows = [];
34914
+ rows.push(["Email", session.email]);
35338
34915
  try {
35339
- const detail = await getMarketplaceSubgraph(name);
35340
- if (options2.json) {
35341
- console.log(JSON.stringify(detail, null, 2));
35342
- return;
35343
- }
35344
- console.log(formatKeyValue([
35345
- ["Name", detail.name],
35346
- ["Description", detail.description ?? dim("—")],
35347
- ["Creator", detail.creator?.displayName ?? detail.creator?.slug ?? dim("—")],
35348
- ["Status", detail.status],
35349
- ["Version", detail.version],
35350
- ["Tags", (detail.tags ?? []).join(", ") || dim("—")],
35351
- ["Tables", detail.tables?.join(", ") ?? dim("—")],
35352
- ["Start Block", String(detail.startBlock)],
35353
- ["Last Processed", String(detail.lastProcessedBlock)],
35354
- ["Queries (7d)", String(detail.usage?.totalQueries7d ?? 0)],
35355
- ["Queries (30d)", String(detail.usage?.totalQueries30d ?? 0)],
35356
- ["Created", detail.createdAt]
35357
- ]));
35358
- if (detail.tableSchemas) {
35359
- console.log(dim(`
35360
- Endpoints:`));
35361
- for (const [table, schema] of Object.entries(detail.tableSchemas)) {
35362
- console.log(` ${cyan(table)} — ${schema.rowCount} rows — ${schema.endpoint}`);
35363
- }
35364
- }
34916
+ const account = await httpPlatform("/api/accounts/me");
34917
+ rows.push(["Plan", account.plan]);
35365
34918
  } catch (err) {
35366
- handleApiError(err, "view subgraph");
34919
+ if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED") {
34920
+ error("Session expired. Run: sl login");
34921
+ process.exit(1);
34922
+ }
34923
+ throw err;
34924
+ }
34925
+ const config = await loadConfig();
34926
+ const active = await readActiveProject(process.cwd(), config.defaultProject);
34927
+ if (active) {
34928
+ rows.push(["Project", active.slug]);
34929
+ rows.push(["Project source", dim(active.resolvedFrom)]);
34930
+ } else {
34931
+ rows.push(["Project", dim("(none — run `sl project create <name>`)")]);
35367
34932
  }
35368
- });
35369
- marketplace.command("fork <name>").description("Fork a public subgraph into your account").option("--name <newName>", "Name for the forked subgraph").option("--json", "Output as JSON").action(async (name, options2) => {
35370
34933
  try {
35371
- const result = await forkMarketplaceSubgraph(name, options2.name);
35372
- if (options2.json) {
35373
- console.log(JSON.stringify(result, null, 2));
35374
- return;
34934
+ const tenant = await httpPlatform("/api/tenants/me");
34935
+ if (tenant.tenant) {
34936
+ const trialDays = Math.max(0, Math.ceil((new Date(tenant.tenant.trialEndsAt).getTime() - Date.now()) / (24 * 60 * 60 * 1000)));
34937
+ rows.push(["Instance", tenant.tenant.apiUrl]);
34938
+ rows.push(["Status", tenant.tenant.status]);
34939
+ rows.push([
34940
+ "Trial",
34941
+ `${trialDays} day${trialDays === 1 ? "" : "s"} left`
34942
+ ]);
34943
+ } else {
34944
+ rows.push([
34945
+ "Instance",
34946
+ dim("(none — run `sl instance create --plan launch`)")
34947
+ ]);
35375
34948
  }
35376
- success(`Forked ${result.forkedFrom} as ${result.name}`);
35377
- console.log(dim(`Subgraph ID: ${result.subgraphId}`));
35378
- console.log(dim("Indexing will start automatically from the source's start block."));
35379
- } catch (err) {
35380
- handleApiError(err, "fork subgraph");
35381
- }
34949
+ } catch {}
34950
+ console.log(formatKeyValue(rows));
35382
34951
  });
35383
34952
  }
35384
- // src/commands/secrets.ts
35385
- init_api_client();
35386
- init_config();
34953
+ // src/commands/login.ts
34954
+ init_http();
35387
34955
  init_output();
35388
- import { input as input3, password } from "@inquirer/prompts";
35389
- function registerSecretsCommand(program2) {
35390
- const secrets = program2.command("secrets").description("Manage workflow signer secrets (HMAC shared secrets for Remote Signer)");
35391
- secrets.command("list").description("List secret names for the authenticated account").action(async () => {
35392
- const { apiUrl, headers } = await apiContext();
35393
- const res = await fetch(`${apiUrl}/api/secrets`, { headers });
35394
- await assertOk(res);
35395
- const { secrets: rows } = await res.json();
35396
- if (rows.length === 0) {
35397
- dim("No secrets set. Add one with: sl secrets set <name> <value>");
35398
- return;
35399
- }
35400
- const table = formatTable(["Name", "Created", "Updated"], rows.map((r) => [
35401
- r.name,
35402
- new Date(r.createdAt).toLocaleString(),
35403
- new Date(r.updatedAt).toLocaleString()
35404
- ]));
35405
- console.log(table);
35406
- });
35407
- secrets.command("set <name> [value]").description("Set or rotate a secret. If value is omitted, reads from stdin prompt.").action(async (name, value) => {
35408
- const resolved = value ?? await password({ message: `Value for "${name}":`, mask: true });
35409
- if (!resolved) {
35410
- error("Value cannot be empty");
35411
- process.exit(1);
35412
- }
35413
- const { apiUrl, headers } = await apiContext();
35414
- const res = await fetch(`${apiUrl}/api/secrets/${encodeURIComponent(name)}`, {
35415
- method: "PUT",
35416
- headers: { ...headers, "Content-Type": "application/json" },
35417
- body: JSON.stringify({ value: resolved })
35418
- });
35419
- await assertOk(res);
35420
- success(`Secret "${name}" set`);
35421
- console.log(formatKeyValue([
35422
- ["name", name],
35423
- ["action", "upsert"]
35424
- ]));
35425
- });
35426
- secrets.command("rotate <name>").description("Rotate a secret (prompts for new value, replaces existing)").action(async (name) => {
35427
- const next = await password({
35428
- message: `New value for "${name}":`,
35429
- mask: true
34956
+ init_session();
34957
+ import { input as input2 } from "@inquirer/prompts";
34958
+ function registerLoginCommand(program2) {
34959
+ program2.command("login").description("Log in to Secondlayer (magic-link email)").action(async () => {
34960
+ const email = await input2({
34961
+ message: "Email",
34962
+ validate: (v) => /^.+@.+\..+$/.test(v) ? true : "Invalid email"
35430
34963
  });
35431
- if (!next) {
35432
- error("Value cannot be empty");
34964
+ try {
34965
+ const res = await httpPlatformAnon("/api/auth/magic-link", {
34966
+ method: "POST",
34967
+ body: { email }
34968
+ });
34969
+ info("Check your inbox for a 6-digit code.");
34970
+ if (res.code) {
34971
+ info(dim(`(DEV_MODE code: ${res.code})`));
34972
+ }
34973
+ } catch (err) {
34974
+ if (err instanceof CliHttpError) {
34975
+ error(err.message);
34976
+ } else {
34977
+ error(err instanceof Error ? err.message : String(err));
34978
+ }
35433
34979
  process.exit(1);
35434
34980
  }
35435
- const confirmed = await input3({
35436
- message: `Type "${name}" to confirm rotation:`
34981
+ const code = await input2({
34982
+ message: "Enter the 6-digit code",
34983
+ validate: (v) => /^\d{6}$/.test(v) ? true : "Expected 6 digits"
35437
34984
  });
35438
- if (confirmed !== name) {
35439
- error("Confirmation mismatch aborting");
34985
+ try {
34986
+ const verified = await httpPlatformAnon("/api/auth/verify", {
34987
+ method: "POST",
34988
+ body: { email, code }
34989
+ });
34990
+ const expiresAt = new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString();
34991
+ await writeSession({
34992
+ token: verified.sessionToken,
34993
+ email: verified.account.email,
34994
+ accountId: verified.account.id,
34995
+ expiresAt
34996
+ });
34997
+ success(`Logged in as ${verified.account.email}`);
34998
+ info(dim("Run 'sl whoami' to see your account status."));
34999
+ } catch (err) {
35000
+ if (err instanceof CliHttpError) {
35001
+ error(err.message);
35002
+ } else {
35003
+ error(err instanceof Error ? err.message : String(err));
35004
+ }
35440
35005
  process.exit(1);
35441
35006
  }
35442
- const { apiUrl, headers } = await apiContext();
35443
- const res = await fetch(`${apiUrl}/api/secrets/${encodeURIComponent(name)}`, {
35444
- method: "PUT",
35445
- headers: { ...headers, "Content-Type": "application/json" },
35446
- body: JSON.stringify({ value: next })
35447
- });
35448
- await assertOk(res);
35449
- success(`Secret "${name}" rotated`);
35450
- dim("Workflows using this secret will pick it up within 5 minutes.");
35451
35007
  });
35452
- secrets.command("delete <name>").description("Delete a secret").action(async (name) => {
35453
- const confirmed = await input3({
35454
- message: `Type "${name}" to confirm deletion:`
35455
- });
35456
- if (confirmed !== name) {
35457
- error("Confirmation mismatch — aborting");
35458
- process.exit(1);
35008
+ }
35009
+ // src/commands/logout.ts
35010
+ init_http();
35011
+ init_output();
35012
+ init_session();
35013
+ function registerLogoutCommand(program2) {
35014
+ program2.command("logout").description("Log out and revoke the local session").action(async () => {
35015
+ const session = await readSession();
35016
+ if (!session) {
35017
+ info("Not logged in.");
35018
+ return;
35019
+ }
35020
+ try {
35021
+ await httpPlatform("/api/auth/logout", { method: "POST" });
35022
+ } catch (err) {
35023
+ if (err instanceof CliHttpError) {
35024
+ warn(`Server logout failed (${err.code}) — clearing local session anyway`);
35025
+ }
35459
35026
  }
35460
- const { apiUrl, headers } = await apiContext();
35461
- const res = await fetch(`${apiUrl}/api/secrets/${encodeURIComponent(name)}`, { method: "DELETE", headers });
35462
- await assertOk(res);
35463
- success(`Secret "${name}" deleted`);
35027
+ await clearSession();
35028
+ success("Logged out.");
35464
35029
  });
35465
35030
  }
35466
- async function apiContext() {
35467
- const config = await loadConfig();
35468
- const apiUrl = resolveApiUrl(config);
35469
- if (!apiUrl) {
35470
- error("No API URL configured. Set network with: sl config set network testnet");
35471
- process.exit(1);
35472
- }
35473
- return { apiUrl, headers: authHeaders(config) };
35474
- }
35475
- // src/commands/whoami.ts
35476
- init_api_client();
35031
+ // src/commands/instance.ts
35477
35032
  init_config();
35033
+ init_http();
35478
35034
  init_output();
35479
- function registerWhoamiCommand(program2) {
35480
- program2.command("whoami").description("Show current authenticated account").action(async () => {
35481
- const config = await loadConfig();
35482
- const apiUrl = resolveApiUrl(config);
35483
- if (!config.apiKey) {
35484
- error("Not authenticated. Run: sl auth login");
35035
+ init_project_file();
35036
+ init_resolve_tenant();
35037
+ import { confirm as confirm4, input as input3, select as select3 } from "@inquirer/prompts";
35038
+ function registerInstanceCommand(program2) {
35039
+ const instance = program2.command("instance").description("Manage your dedicated Secondlayer instance");
35040
+ instance.command("create").description("Provision a new dedicated instance for the active project").option("--plan <plan>", "Plan: launch | grow | scale", "launch").action(async (opts) => {
35041
+ guardOssMode();
35042
+ const activeSlug = await requireActiveProject();
35043
+ const plan = opts.plan;
35044
+ if (!["launch", "grow", "scale"].includes(plan)) {
35045
+ error(`Invalid plan: ${plan} (expected launch, grow, or scale)`);
35485
35046
  process.exit(1);
35486
35047
  }
35487
35048
  try {
35488
- const res = await fetch(`${apiUrl}/api/accounts/me`, {
35489
- headers: authHeaders(config)
35049
+ const res = await httpPlatform(`/api/projects/${encodeURIComponent(activeSlug)}/instance`, {
35050
+ method: "POST",
35051
+ body: { plan }
35490
35052
  });
35491
- if (res.status === 401) {
35492
- error("Not authenticated. Run: sl auth login");
35493
- process.exit(1);
35494
- }
35495
- if (!res.ok) {
35496
- throw new Error(`HTTP ${res.status}`);
35497
- }
35498
- const data = await res.json();
35499
- console.log(formatKeyValue([
35500
- ["Email", data.email],
35501
- ["Plan", data.plan],
35502
- ["Network", config.network],
35503
- ["API", dim(apiUrl)]
35504
- ]));
35053
+ success(`Instance provisioned: ${res.tenant.slug}`);
35054
+ printKeyReveal(res.tenant, res.credentials);
35505
35055
  } catch (err) {
35506
- error(`Failed to fetch account: ${err}`);
35507
- process.exit(1);
35056
+ handleInstanceError(err, "provision instance");
35508
35057
  }
35509
35058
  });
35510
- }
35511
- // src/commands/workflows.ts
35512
- init_config();
35513
- init_output();
35514
- import { existsSync as existsSync2 } from "node:fs";
35515
- import { resolve as resolve7 } from "node:path";
35516
- import { SecondLayer as SecondLayer2 } from "@secondlayer/sdk";
35517
- function formatValidationError(err) {
35518
- if (err != null && typeof err === "object" && "issues" in err && Array.isArray(err.issues)) {
35519
- error("Workflow validation failed:");
35520
- for (const issue of err.issues) {
35521
- const path = issue.path?.length ? issue.path.join(".") : "(root)";
35522
- error(` ${path}: ${issue.message}`);
35059
+ instance.command("info").description("Show the active project's instance").action(async () => {
35060
+ guardOssMode();
35061
+ await renderInstanceInfo();
35062
+ });
35063
+ 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) => {
35064
+ guardOssMode();
35065
+ let target = opts.plan;
35066
+ if (!target) {
35067
+ const answer = await select3({
35068
+ message: "Target plan",
35069
+ choices: [
35070
+ {
35071
+ value: "launch",
35072
+ name: "Launch — $99/mo (1 vCPU · 2 GB · 10 GB)"
35073
+ },
35074
+ { value: "grow", name: "Grow — $249/mo (2 vCPU · 4 GB · 50 GB)" },
35075
+ {
35076
+ value: "scale",
35077
+ name: "Scale — $599/mo (4 vCPU · 8 GB · 200 GB)"
35078
+ }
35079
+ ]
35080
+ });
35081
+ target = answer;
35523
35082
  }
35524
- } else {
35525
- error(`Failed to validate workflow: ${err}`);
35526
- }
35527
- }
35528
- function getClient2() {
35529
- const apiKey = process.env.SECONDLAYER_API_KEY;
35530
- if (!apiKey) {
35531
- error("SECONDLAYER_API_KEY required. Run: sl auth login");
35532
- process.exit(1);
35533
- }
35534
- return new SecondLayer2({ apiKey });
35535
- }
35536
- function registerWorkflowsCommand(program2) {
35537
- const workflows = program2.command("workflows").description("Manage workflows");
35538
- workflows.command("deploy <file>").description("Validate and deploy a workflow definition file").action(async (file) => {
35539
- try {
35540
- const absPath = resolve7(file);
35541
- if (!existsSync2(absPath)) {
35542
- error(`File not found: ${absPath}`);
35543
- process.exit(1);
35544
- }
35545
- info(`Loading workflow from ${absPath}`);
35546
- const mod = await import(absPath);
35547
- const def = mod.default ?? mod;
35548
- const { validateWorkflowDefinition } = await import("@secondlayer/workflows/validate");
35549
- const result = validateWorkflowDefinition(def);
35550
- const config = await loadConfig();
35551
- if (config.network !== "local") {
35552
- info(`Bundling for remote deploy (${config.network})...`);
35553
- const { readFile: readFile2 } = await import("node:fs/promises");
35554
- const source = await readFile2(absPath, "utf8");
35555
- const { bundleWorkflowCode } = await import("@secondlayer/bundler");
35556
- const bundled = await bundleWorkflowCode(source);
35557
- const deployResult = await getClient2().workflows.deploy({
35558
- name: bundled.name,
35559
- trigger: bundled.trigger,
35560
- handlerCode: bundled.handlerCode,
35561
- sourceCode: bundled.sourceCode,
35562
- retries: bundled.retries,
35563
- timeout: bundled.timeout
35564
- });
35565
- success(`Workflow "${def.name}" ${deployResult.action} → v${deployResult.version} (remote)`);
35566
- } else {
35567
- success(`Workflow "${result.name}" is valid`);
35568
- info(`Trigger: ${result.trigger.type}`);
35569
- if (result.retries) {
35570
- info(`Retries: maxAttempts=${result.retries.maxAttempts ?? "default"}`);
35571
- }
35572
- if (result.timeout) {
35573
- info(`Timeout: ${result.timeout}ms`);
35574
- }
35083
+ if (!opts.yes) {
35084
+ const ok = await confirm4({
35085
+ message: `Resize to ${target}? ~30s downtime while containers recreate. Data preserved.`,
35086
+ default: false
35087
+ });
35088
+ if (!ok) {
35089
+ info("Cancelled.");
35090
+ return;
35575
35091
  }
35092
+ }
35093
+ try {
35094
+ await httpPlatform("/api/tenants/me/resize", {
35095
+ method: "POST",
35096
+ body: { plan: target }
35097
+ });
35098
+ success(`Resized to ${target}.`);
35576
35099
  } catch (err) {
35577
- formatValidationError(err);
35578
- process.exit(1);
35100
+ handleInstanceError(err, "resize");
35579
35101
  }
35580
35102
  });
35581
- workflows.command("validate <file>").description("Validate a workflow definition without deploying").action(async (file) => {
35103
+ instance.command("suspend").description("Stop your instance (data preserved)").action(async () => {
35104
+ guardOssMode();
35582
35105
  try {
35583
- const absPath = resolve7(file);
35584
- if (!existsSync2(absPath)) {
35585
- error(`File not found: ${absPath}`);
35586
- process.exit(1);
35587
- }
35588
- const mod = await import(absPath);
35589
- const def = mod.default ?? mod;
35590
- const { validateWorkflowDefinition } = await import("@secondlayer/workflows/validate");
35591
- const result = validateWorkflowDefinition(def);
35592
- success(`Workflow "${result.name}" is valid`);
35593
- info(`Trigger: ${result.trigger.type}`);
35594
- if (result.retries) {
35595
- info(`Retries: maxAttempts=${result.retries.maxAttempts ?? "default"}, backoffMs=${result.retries.backoffMs ?? 1000}, multiplier=${result.retries.backoffMultiplier ?? 2}`);
35596
- }
35597
- if (result.timeout) {
35598
- info(`Timeout: ${result.timeout}ms`);
35599
- }
35106
+ await httpPlatform("/api/tenants/me/suspend", { method: "POST" });
35107
+ success("Instance suspended.");
35600
35108
  } catch (err) {
35601
- formatValidationError(err);
35602
- process.exit(1);
35109
+ handleInstanceError(err, "suspend");
35603
35110
  }
35604
35111
  });
35605
- workflows.command("list").alias("ls").description("List all workflows").option("--json", "Output as JSON").action(async (options2) => {
35112
+ instance.command("resume").description("Start a suspended instance").action(async () => {
35113
+ guardOssMode();
35606
35114
  try {
35607
- const { workflows: items } = await getClient2().workflows.list();
35608
- if (options2.json) {
35609
- console.log(JSON.stringify(items, null, 2));
35610
- return;
35611
- }
35612
- if (items.length === 0) {
35613
- console.log("No workflows deployed");
35115
+ await httpPlatform("/api/tenants/me/resume", { method: "POST" });
35116
+ success("Instance resumed.");
35117
+ } catch (err) {
35118
+ handleInstanceError(err, "resume");
35119
+ }
35120
+ });
35121
+ instance.command("delete").description("Permanently delete your instance + all data").option("--yes", "Skip typed-slug confirm").action(async (opts) => {
35122
+ guardOssMode();
35123
+ const info_ = await httpPlatform("/api/tenants/me").catch(() => null);
35124
+ if (!info_?.tenant) {
35125
+ warn("No instance to delete.");
35126
+ return;
35127
+ }
35128
+ const slug = info_.tenant.slug;
35129
+ if (!opts.yes) {
35130
+ const typed = await input3({
35131
+ message: `Type the slug "${slug}" to confirm permanent deletion`,
35132
+ validate: (v) => v === slug ? true : "Slug must match exactly"
35133
+ });
35134
+ if (typed !== slug)
35614
35135
  return;
35615
- }
35616
- const rows = items.map((w) => {
35617
- const statusColor = w.status === "active" ? green : yellow;
35618
- return [w.name, statusColor(w.status), w.triggerType, w.createdAt];
35136
+ }
35137
+ try {
35138
+ await httpPlatform("/api/tenants/me", { method: "DELETE" });
35139
+ success("Instance deleted.");
35140
+ } catch (err) {
35141
+ handleInstanceError(err, "delete");
35142
+ }
35143
+ });
35144
+ const keys = instance.command("keys").description("Rotate long-lived keys (service, anon)");
35145
+ 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) => {
35146
+ guardOssMode();
35147
+ let type;
35148
+ if (opts.both || opts.service && opts.anon)
35149
+ type = "both";
35150
+ else if (opts.service)
35151
+ type = "service";
35152
+ else if (opts.anon)
35153
+ type = "anon";
35154
+ else {
35155
+ const answer = await select3({
35156
+ message: "Which key(s) to rotate?",
35157
+ choices: [
35158
+ {
35159
+ value: "service",
35160
+ name: "Service key (full access, server-side)"
35161
+ },
35162
+ { value: "anon", name: "Anon key (read-only, client-safe)" },
35163
+ {
35164
+ value: "both",
35165
+ name: "Both (nuclear — offboarding/leak response)"
35166
+ }
35167
+ ]
35619
35168
  });
35620
- console.log(formatTable(["Name", "Status", "Trigger", "Created"], rows));
35621
- console.log(dim(`
35622
- ${items.length} workflow(s) total`));
35169
+ type = answer;
35170
+ }
35171
+ try {
35172
+ const res = await httpPlatform("/api/tenants/me/keys/rotate", {
35173
+ method: "POST",
35174
+ body: { type }
35175
+ });
35176
+ success(`${type === "both" ? "Keys" : `${type} key`} rotated.`);
35177
+ const rows = [];
35178
+ if (res.rotated.serviceKey)
35179
+ rows.push(["New service key", res.rotated.serviceKey]);
35180
+ if (res.rotated.anonKey)
35181
+ rows.push(["New anon key", res.rotated.anonKey]);
35182
+ console.log("");
35183
+ console.log(warn_box("⚠ Shown once. Save these now — we can't retrieve them later."));
35184
+ console.log("");
35185
+ console.log(formatKeyValue(rows));
35186
+ console.log("");
35623
35187
  } catch (err) {
35624
- error(`Failed to list workflows: ${err}`);
35625
- process.exit(1);
35188
+ handleInstanceError(err, "rotate keys");
35626
35189
  }
35627
35190
  });
35628
- workflows.command("get <name>").description("Get workflow details").option("--json", "Output as JSON").action(async (name, options2) => {
35191
+ const db = instance.command("db").description("Get a DATABASE_URL for direct Postgres access (via SSH tunnel)");
35192
+ db.command("info", { isDefault: true }).description("Print SSH tunnel command + DATABASE_URL for the instance").action(async () => {
35193
+ guardOssMode();
35629
35194
  try {
35630
- const detail = await getClient2().workflows.get(name);
35631
- if (options2.json) {
35632
- console.log(JSON.stringify(detail, null, 2));
35633
- return;
35634
- }
35635
- console.log(formatKeyValue([
35636
- ["Name", detail.name],
35637
- ["Status", detail.status],
35638
- ["Trigger", detail.triggerType],
35639
- ["Total Runs", String(detail.totalRuns)],
35640
- ["Last Run", detail.lastRunAt ?? "never"],
35641
- ["Timeout", detail.timeout ? `${detail.timeout}ms` : "default"],
35642
- ["Created", detail.createdAt],
35643
- ["Updated", detail.updatedAt]
35644
- ]));
35195
+ const res = await httpPlatform("/api/tenants/me/db-access");
35196
+ console.log("");
35197
+ console.log(dim("1. Upload your public key (one time):"));
35198
+ console.log(dim(" sl instance db add-key ~/.ssh/id_ed25519.pub"));
35199
+ console.log("");
35200
+ console.log(dim("2. Open the SSH tunnel in a separate terminal:"));
35201
+ console.log(green(` ${res.sshCommand}`));
35202
+ console.log("");
35203
+ console.log(dim("3. Use this DATABASE_URL while the tunnel is open:"));
35204
+ console.log(green(` ${res.databaseUrl}`));
35205
+ console.log("");
35645
35206
  } catch (err) {
35646
- error(`Failed to get workflow: ${err}`);
35647
- process.exit(1);
35207
+ handleInstanceError(err, "fetch db access info");
35648
35208
  }
35649
35209
  });
35650
- workflows.command("trigger <name>").description("Trigger a workflow run").option("--input <json>", "Input JSON string").action(async (name, options2) => {
35210
+ db.command("add-key <path>").description("Upload an SSH public key to the bastion for this instance").action(async (path) => {
35211
+ guardOssMode();
35212
+ let publicKey;
35651
35213
  try {
35652
- const input4 = options2.input ? JSON.parse(options2.input) : undefined;
35653
- const result = await getClient2().workflows.trigger(name, input4);
35654
- success(`Triggered workflow "${name}"`);
35655
- info(`Run ID: ${result.runId}`);
35214
+ publicKey = (await Bun.file(path).text()).trim();
35656
35215
  } catch (err) {
35657
- error(`Failed to trigger workflow: ${err}`);
35216
+ error(`Could not read ${path}: ${err instanceof Error ? err.message : String(err)}`);
35217
+ process.exit(1);
35218
+ }
35219
+ if (!publicKey) {
35220
+ error(`${path} is empty`);
35658
35221
  process.exit(1);
35659
35222
  }
35660
- });
35661
- 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) => {
35662
35223
  try {
35663
- const { runs } = await getClient2().workflows.listRuns(name, {
35664
- status: options2.status,
35665
- limit: options2.limit ? Number.parseInt(options2.limit, 10) : undefined
35224
+ await httpPlatform("/api/tenants/me/db-access/key", { method: "POST", body: { publicKey } });
35225
+ success("Bastion key installed. You can now open the SSH tunnel.");
35226
+ } catch (err) {
35227
+ handleInstanceError(err, "upload bastion key");
35228
+ }
35229
+ });
35230
+ db.command("revoke-key").description("Revoke bastion access for this instance").option("-y, --yes", "Skip confirmation").action(async (opts) => {
35231
+ guardOssMode();
35232
+ if (!opts.yes) {
35233
+ const ok = await confirm4({
35234
+ message: "Revoke bastion access for this instance?",
35235
+ default: false
35666
35236
  });
35667
- if (options2.json) {
35668
- console.log(JSON.stringify(runs, null, 2));
35237
+ if (!ok)
35669
35238
  return;
35670
- }
35671
- if (runs.length === 0) {
35672
- console.log("No runs found");
35673
- return;
35674
- }
35675
- const rows = runs.map((r) => {
35676
- const statusColor = r.status === "completed" ? green : r.status === "failed" ? (s) => `\x1B[31m${s}\x1B[0m` : yellow;
35677
- return [
35678
- r.id.slice(0, 8),
35679
- statusColor(r.status),
35680
- `${r.duration}ms`,
35681
- String(r.aiTokensUsed),
35682
- r.triggeredAt
35683
- ];
35684
- });
35685
- console.log(formatTable(["ID", "Status", "Duration", "AI Tokens", "Triggered"], rows));
35686
- console.log(dim(`
35687
- ${runs.length} run(s)`));
35239
+ }
35240
+ try {
35241
+ await httpPlatform("/api/tenants/me/db-access/key", { method: "DELETE" });
35242
+ success("Bastion access revoked.");
35688
35243
  } catch (err) {
35689
- error(`Failed to list runs: ${err}`);
35690
- process.exit(1);
35244
+ handleInstanceError(err, "revoke bastion key");
35691
35245
  }
35692
35246
  });
35693
- workflows.command("pause <name>").description("Pause a workflow").action(async (name) => {
35247
+ }
35248
+ function guardOssMode() {
35249
+ if (isOssMode()) {
35250
+ error("`sl instance` commands are for hosted deployments. For OSS use `sl local` / `sl stack` or your own provisioning.");
35251
+ process.exit(1);
35252
+ }
35253
+ }
35254
+ async function requireActiveProject() {
35255
+ const config = await loadConfig();
35256
+ const active = await readActiveProject(process.cwd(), config.defaultProject);
35257
+ if (!active) {
35258
+ error("No active project — run `sl project create <name>` or `sl project use <slug>` first.");
35259
+ process.exit(1);
35260
+ }
35261
+ return active.slug;
35262
+ }
35263
+ async function renderInstanceInfo() {
35264
+ try {
35265
+ const res = await httpPlatform("/api/tenants/me");
35266
+ if (!res.tenant) {
35267
+ info("No instance for the active project. Run `sl instance create --plan launch`.");
35268
+ return;
35269
+ }
35270
+ const t = res.tenant;
35271
+ const trialDays = Math.max(0, Math.ceil((new Date(t.trialEndsAt).getTime() - Date.now()) / (24 * 60 * 60 * 1000)));
35272
+ console.log(formatKeyValue([
35273
+ ["URL", t.apiUrl],
35274
+ ["Plan", t.plan],
35275
+ ["Status", t.status],
35276
+ ["Trial", `${trialDays} day${trialDays === 1 ? "" : "s"} left`],
35277
+ ["Created", new Date(t.createdAt).toLocaleString()]
35278
+ ]));
35279
+ } catch (err) {
35280
+ handleInstanceError(err, "fetch instance");
35281
+ }
35282
+ }
35283
+ function printKeyReveal(tenant, creds) {
35284
+ console.log("");
35285
+ console.log(blue("━".repeat(60)));
35286
+ console.log(blue(" Save your keys — shown once. Can't retrieve later."));
35287
+ console.log(blue("━".repeat(60)));
35288
+ console.log("");
35289
+ console.log(formatKeyValue([
35290
+ ["URL", creds.apiUrl],
35291
+ ["Plan", tenant.plan],
35292
+ ["Service key", green(creds.serviceKey)],
35293
+ ["Anon key", green(creds.anonKey)]
35294
+ ]));
35295
+ console.log("");
35296
+ console.log(dim("Run `sl subgraphs deploy <file>` to deploy your first subgraph."));
35297
+ console.log("");
35298
+ }
35299
+ function warn_box(message) {
35300
+ return `${"━".repeat(message.length + 4)}
35301
+ ${message}
35302
+ ${"━".repeat(message.length + 4)}`;
35303
+ }
35304
+ function handleInstanceError(err, action) {
35305
+ if (err instanceof CliHttpError) {
35306
+ if (err.code === "SESSION_EXPIRED") {
35307
+ error("Session expired. Run: sl login");
35308
+ process.exit(1);
35309
+ }
35310
+ if (err.code === "TRIAL_EXPIRED") {
35311
+ error(err.message);
35312
+ error("Add a payment method at the dashboard to keep your instance running.");
35313
+ process.exit(1);
35314
+ }
35315
+ if (err.code === "TENANT_SUSPENDED") {
35316
+ error("Instance is suspended. Run: sl instance resume");
35317
+ process.exit(1);
35318
+ }
35319
+ if (err.code === "INSTANCE_EXISTS") {
35320
+ error("This project already has an instance. Run `sl instance info` to see it.");
35321
+ process.exit(1);
35322
+ }
35323
+ error(err.message);
35324
+ process.exit(1);
35325
+ }
35326
+ error(`Failed to ${action}: ${err instanceof Error ? err.message : String(err)}`);
35327
+ process.exit(1);
35328
+ }
35329
+ // src/commands/project.ts
35330
+ init_config();
35331
+ init_http();
35332
+ init_output();
35333
+ init_project_file();
35334
+ import { input as input4 } from "@inquirer/prompts";
35335
+ function registerProjectCommand(program2) {
35336
+ const project = program2.command("project").description("Manage Secondlayer projects");
35337
+ project.command("create [name]").description("Create a new project").action(async (nameArg) => {
35338
+ const name = nameArg ?? await input4({
35339
+ message: "Project name",
35340
+ validate: (v) => v.length >= 2 ? true : "Name must be at least 2 characters"
35341
+ });
35694
35342
  try {
35695
- await getClient2().workflows.pause(name);
35696
- success(`Paused workflow "${name}"`);
35343
+ const res = await httpPlatform("/api/projects", { method: "POST", body: { name } });
35344
+ success(`Created project ${res.project.name} (${res.project.slug})`);
35345
+ const path = await writeActiveProject(res.project.slug, process.cwd());
35346
+ info(dim(`Bound to this directory → ${path}`));
35347
+ info(dim(`Next: sl instance create --plan launch`));
35697
35348
  } catch (err) {
35698
- error(`Failed to pause workflow: ${err}`);
35699
- process.exit(1);
35349
+ handleProjectError(err);
35700
35350
  }
35701
35351
  });
35702
- workflows.command("resume <name>").description("Resume a paused workflow").action(async (name) => {
35352
+ project.command("list").description("List projects in your account").action(async () => {
35703
35353
  try {
35704
- await getClient2().workflows.resume(name);
35705
- success(`Resumed workflow "${name}"`);
35354
+ const res = await httpPlatform("/api/projects");
35355
+ if (res.projects.length === 0) {
35356
+ info("No projects yet — run `sl project create <name>` to start.");
35357
+ return;
35358
+ }
35359
+ const active = await readActiveProject(process.cwd(), (await loadConfig()).defaultProject);
35360
+ const rows = res.projects.map((p) => [
35361
+ p.slug === active?.slug ? `* ${p.slug}` : ` ${p.slug}`,
35362
+ p.name,
35363
+ p.network,
35364
+ new Date(p.createdAt).toLocaleDateString()
35365
+ ]);
35366
+ console.log(formatTable(["", "Name", "Network", "Created"], rows));
35367
+ if (active) {
35368
+ console.log(dim(`Active: ${active.slug} (from ${active.resolvedFrom})`));
35369
+ }
35706
35370
  } catch (err) {
35707
- error(`Failed to resume workflow: ${err}`);
35708
- process.exit(1);
35371
+ handleProjectError(err);
35709
35372
  }
35710
35373
  });
35711
- workflows.command("delete <name>").description("Delete a workflow").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
35374
+ project.command("use <slug>").description("Bind this directory to a project (writes ./.secondlayer/project)").action(async (slug) => {
35712
35375
  try {
35713
- if (!options2.yes) {
35714
- const { confirm: confirm5 } = await import("@inquirer/prompts");
35715
- const ok = await confirm5({
35716
- message: `Delete workflow "${name}"? This cannot be undone.`
35717
- });
35718
- if (!ok) {
35719
- info("Cancelled");
35720
- return;
35721
- }
35722
- }
35723
- await getClient2().workflows.delete(name);
35724
- success(`Deleted workflow "${name}"`);
35376
+ await httpPlatform(`/api/projects/${encodeURIComponent(slug)}`);
35725
35377
  } catch (err) {
35726
- error(`Failed to delete workflow: ${err}`);
35727
- process.exit(1);
35378
+ if (err instanceof CliHttpError && err.status === 404) {
35379
+ error(`Project "${slug}" not found — run 'sl project list' to see available projects`);
35380
+ process.exit(1);
35381
+ }
35382
+ handleProjectError(err);
35383
+ }
35384
+ const path = await writeActiveProject(slug, process.cwd());
35385
+ success(`Bound to project "${slug}"`);
35386
+ info(dim(`Written to ${path}`));
35387
+ });
35388
+ project.command("current").description("Show the active project for this directory").action(async () => {
35389
+ const config = await loadConfig();
35390
+ const active = await readActiveProject(process.cwd(), config.defaultProject);
35391
+ if (!active) {
35392
+ info("No active project.");
35393
+ info(dim("Run 'sl project create <name>' or 'sl project use <slug>'."));
35394
+ return;
35728
35395
  }
35396
+ console.log(active.slug);
35397
+ console.log(dim(`(from ${active.resolvedFrom})`));
35729
35398
  });
35730
35399
  }
35400
+ function handleProjectError(err) {
35401
+ if (err instanceof CliHttpError) {
35402
+ if (err.code === "SESSION_EXPIRED") {
35403
+ error("Session expired. Run: sl login");
35404
+ process.exit(1);
35405
+ }
35406
+ error(err.message);
35407
+ process.exit(1);
35408
+ }
35409
+ error(err instanceof Error ? err.message : String(err));
35410
+ process.exit(1);
35411
+ }
35731
35412
  // src/cli.ts
35732
35413
  var { version } = package_default;
35733
- 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)");
35414
+ program.name("secondlayer").alias("sl").description("SecondLayer CLI — dedicated Stacks indexing + real-time subgraphs").version(version).option("--network <network>", "Override network (local, testnet, mainnet)");
35734
35415
  program.hook("preAction", (thisCommand) => {
35735
35416
  const net3 = thisCommand.opts().network;
35736
35417
  if (net3)
@@ -35738,10 +35419,11 @@ program.hook("preAction", (thisCommand) => {
35738
35419
  });
35739
35420
  program.addHelpText("after", `
35740
35421
  Quickstart:
35741
- $ sl auth login # Authenticate
35742
- $ sl subgraphs new my-subgraph # Scaffold a subgraph
35743
- $ sl workflows new my-workflow # Scaffold a workflow
35744
- $ sl status # Check system health
35422
+ $ sl login # Authenticate (magic-link email)
35423
+ $ sl project create my-app # Scaffold a project (tenant + data)
35424
+ $ sl project use my-app # Bind this directory to the project
35425
+ $ sl instance create --plan launch # Provision a dedicated instance
35426
+ $ sl subgraphs deploy ./x.ts # Deploy a subgraph — targets your instance
35745
35427
  `);
35746
35428
  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) => {
35747
35429
  const { generate: generate2 } = await Promise.resolve().then(() => (init_generate(), exports_generate));
@@ -35751,21 +35433,20 @@ program.command("init").description("Initialize a new secondlayer.config.ts file
35751
35433
  const { init: init3 } = await Promise.resolve().then(() => (init_init(), exports_init));
35752
35434
  await init3();
35753
35435
  });
35436
+ registerLoginCommand(program);
35437
+ registerLogoutCommand(program);
35438
+ registerWhoamiCommand(program);
35439
+ registerProjectCommand(program);
35440
+ registerInstanceCommand(program);
35754
35441
  registerSubgraphsCommand(program);
35755
- registerWorkflowsCommand(program);
35756
- registerSecretsCommand(program);
35757
- registerMarketplaceCommand(program);
35758
35442
  registerStatusCommand(program);
35759
- registerLocalCommand(program);
35760
- registerAccountCommand(program);
35761
35443
  registerStackCommand(program);
35762
35444
  registerDbCommand(program);
35763
- registerSyncCommand(program);
35764
35445
  registerDoctorCommand(program);
35765
35446
  registerConfigCommand(program);
35766
- registerAuthCommand(program);
35767
- registerWhoamiCommand(program);
35447
+ registerLocalCommand(program);
35448
+ registerAccountCommand(program);
35768
35449
  program.parse();
35769
35450
 
35770
- //# debugId=217C08CACE85108C64756E2164756E21
35451
+ //# debugId=395566BC0854202D64756E2164756E21
35771
35452
  //# sourceMappingURL=cli.js.map