@secondlayer/cli 1.12.2 → 2.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 +414 -2221
  2. package/dist/cli.js.map +22 -36
  3. package/package.json +7 -6
package/dist/cli.js CHANGED
@@ -2229,9 +2229,6 @@ function migrateConfig(raw) {
2229
2229
  if (typeof old.dataDir === "string") {
2230
2230
  migrated.dataDir = old.dataDir;
2231
2231
  }
2232
- if (typeof old.defaultEndpointUrl === "string") {
2233
- migrated.defaultEndpointUrl = old.defaultEndpointUrl;
2234
- }
2235
2232
  if (typeof old.nodeInstallPath === "string" || typeof old.nodeNetwork === "string") {
2236
2233
  migrated.node = {
2237
2234
  installPath: old.nodeInstallPath || "",
@@ -2273,9 +2270,6 @@ async function loadConfig() {
2273
2270
  }
2274
2271
  }
2275
2272
  config = applyEnvOverrides(config);
2276
- if (!config.defaultEndpointUrl && config.network === "local") {
2277
- config.defaultEndpointUrl = LOCAL_ENDPOINT_URL;
2278
- }
2279
2273
  return config;
2280
2274
  }
2281
2275
  function applyEnvOverrides(config) {
@@ -2304,12 +2298,6 @@ function applyEnvOverrides(config) {
2304
2298
  result.ports = { ...result.ports, indexer: port };
2305
2299
  }
2306
2300
  }
2307
- if (process.env.SL_RECEIVER_PORT) {
2308
- const port = Number.parseInt(process.env.SL_RECEIVER_PORT, 10);
2309
- if (!isNaN(port) && port > 0 && port <= 65535) {
2310
- result.ports = { ...result.ports, receiver: port };
2311
- }
2312
- }
2313
2301
  if (process.env.STACKS_NODE_RPC_URL) {
2314
2302
  result.nodeRpcUrl = process.env.STACKS_NODE_RPC_URL;
2315
2303
  }
@@ -2388,7 +2376,6 @@ async function requireLocalNetwork() {
2388
2376
  console.error(`Error: 'sl local' commands require local mode.`);
2389
2377
  console.error(` Current context: ${config.network} (hosted)`);
2390
2378
  console.error("");
2391
- console.error(` To view stream logs, use: sl logs <stream>`);
2392
2379
  console.error(` To check system status, use: sl status`);
2393
2380
  console.error("");
2394
2381
  console.error(` To switch to local mode: sl config set network local`);
@@ -2401,13 +2388,12 @@ function isDefaultValue(config, key) {
2401
2388
  const defaultValue = getConfigValue(DEFAULT_CONFIG, key);
2402
2389
  return JSON.stringify(currentValue) === JSON.stringify(defaultValue);
2403
2390
  }
2404
- var PortsSchema, NodeSchema, DatabaseSchema, NetworkSchema, API_URLS, ConfigSchema, CONFIG_DIR, CONFIG_PATH, LOCAL_ENDPOINT_URL = "http://localhost:3900/receiver", DEFAULT_CONFIG;
2391
+ var PortsSchema, NodeSchema, DatabaseSchema, NetworkSchema, API_URLS, ConfigSchema, CONFIG_DIR, CONFIG_PATH, DEFAULT_CONFIG;
2405
2392
  var init_config = __esm(() => {
2406
2393
  init_fs();
2407
2394
  PortsSchema = z.object({
2408
2395
  api: z.number().int().min(1).max(65535).default(3800),
2409
- indexer: z.number().int().min(1).max(65535).default(3700),
2410
- receiver: z.number().int().min(1).max(65535).default(3900)
2396
+ indexer: z.number().int().min(1).max(65535).default(3700)
2411
2397
  });
2412
2398
  NodeSchema = z.object({
2413
2399
  installPath: z.string().min(1),
@@ -2429,9 +2415,8 @@ var init_config = __esm(() => {
2429
2415
  apiKey: z.string().optional(),
2430
2416
  nodeRpcUrl: z.string().url().optional(),
2431
2417
  dataDir: z.string().default("~/.secondlayer/data"),
2432
- defaultEndpointUrl: z.string().url().optional(),
2433
2418
  node: NodeSchema.optional(),
2434
- ports: PortsSchema.default({ api: 3800, indexer: 3700, receiver: 3900 }),
2419
+ ports: PortsSchema.default({ api: 3800, indexer: 3700 }),
2435
2420
  database: DatabaseSchema.default({ type: "docker" })
2436
2421
  });
2437
2422
  CONFIG_DIR = join(homedir(), ".secondlayer");
@@ -2439,49 +2424,12 @@ var init_config = __esm(() => {
2439
2424
  DEFAULT_CONFIG = {
2440
2425
  network: "mainnet",
2441
2426
  dataDir: "~/.secondlayer/data",
2442
- ports: { api: 3800, indexer: 3700, receiver: 3900 },
2427
+ ports: { api: 3800, indexer: 3700 },
2443
2428
  database: { type: "docker" }
2444
2429
  };
2445
2430
  });
2446
2431
 
2447
2432
  // src/lib/api-client.ts
2448
- var exports_api_client = {};
2449
- __export(exports_api_client, {
2450
- updateStreamByName: () => updateStreamByName,
2451
- updateStream: () => updateStream,
2452
- updateAccountProfile: () => updateAccountProfile,
2453
- unpublishSubgraphApi: () => unpublishSubgraphApi,
2454
- stopSubgraphApi: () => stopSubgraphApi,
2455
- rotateSecret: () => rotateSecret,
2456
- resumeAllStreams: () => resumeAllStreams,
2457
- resolveStreamId: () => resolveStreamId,
2458
- reindexSubgraphApi: () => reindexSubgraphApi,
2459
- querySubgraphTableCount: () => querySubgraphTableCount,
2460
- querySubgraphTable: () => querySubgraphTable,
2461
- publishSubgraphApi: () => publishSubgraphApi,
2462
- pauseAllStreams: () => pauseAllStreams,
2463
- listSubgraphsApi: () => listSubgraphsApi,
2464
- listStreams: () => listStreams,
2465
- handleApiError: () => handleApiError,
2466
- getSubgraphGaps: () => getSubgraphGaps,
2467
- getSubgraphApi: () => getSubgraphApi,
2468
- getStream: () => getStream,
2469
- getQueueStats: () => getQueueStats,
2470
- getMarketplaceSubgraph: () => getMarketplaceSubgraph,
2471
- getAccountProfile: () => getAccountProfile,
2472
- forkMarketplaceSubgraph: () => forkMarketplaceSubgraph,
2473
- enableStream: () => enableStream,
2474
- disableStream: () => disableStream,
2475
- deploySubgraphApi: () => deploySubgraphApi,
2476
- deleteSubgraphApi: () => deleteSubgraphApi,
2477
- deleteStream: () => deleteStream,
2478
- createStream: () => createStream,
2479
- browseMarketplace: () => browseMarketplace,
2480
- backfillSubgraphApi: () => backfillSubgraphApi,
2481
- authHeaders: () => authHeaders,
2482
- assertOk: () => assertOk,
2483
- ApiError: () => ApiError
2484
- });
2485
2433
  import { SecondLayer } from "@secondlayer/sdk";
2486
2434
  import { ApiError } from "@secondlayer/sdk";
2487
2435
  async function assertOk(res) {
@@ -2506,6 +2454,19 @@ function handleApiError(err, action) {
2506
2454
  console.error(`Error: Failed to ${action}: ${err}`);
2507
2455
  process.exit(1);
2508
2456
  }
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");
2466
+ }
2467
+ }
2468
+ };
2469
+ }
2509
2470
  async function getClient() {
2510
2471
  const config = await loadConfig();
2511
2472
  const baseUrl = resolveApiUrl(config);
@@ -2514,45 +2475,6 @@ async function getClient() {
2514
2475
  function authHeaders(config) {
2515
2476
  return SecondLayer.authHeaders(config.apiKey);
2516
2477
  }
2517
- async function createStream(data) {
2518
- return (await getClient()).streams.create(data);
2519
- }
2520
- async function updateStream(id, data) {
2521
- return (await getClient()).streams.update(id, data);
2522
- }
2523
- async function updateStreamByName(name, data) {
2524
- return (await getClient()).streams.updateByName(name, data);
2525
- }
2526
- async function listStreams(params) {
2527
- return (await getClient()).streams.list(params);
2528
- }
2529
- async function resolveStreamId(partialId) {
2530
- return (await getClient()).streams.resolveStreamId(partialId);
2531
- }
2532
- async function getStream(id) {
2533
- return (await getClient()).streams.get(id);
2534
- }
2535
- async function deleteStream(id) {
2536
- return (await getClient()).streams.delete(id);
2537
- }
2538
- async function enableStream(id) {
2539
- return (await getClient()).streams.enable(id);
2540
- }
2541
- async function disableStream(id) {
2542
- return (await getClient()).streams.disable(id);
2543
- }
2544
- async function rotateSecret(id) {
2545
- return (await getClient()).streams.rotateSecret(id);
2546
- }
2547
- async function pauseAllStreams() {
2548
- return (await getClient()).streams.pauseAll();
2549
- }
2550
- async function resumeAllStreams() {
2551
- return (await getClient()).streams.resumeAll();
2552
- }
2553
- async function getQueueStats() {
2554
- return (await getClient()).getQueueStats();
2555
- }
2556
2478
  async function listSubgraphsApi() {
2557
2479
  return (await getClient()).subgraphs.list();
2558
2480
  }
@@ -4755,15 +4677,15 @@ __export(exports_dev_state, {
4755
4677
  clearDevState: () => clearDevState
4756
4678
  });
4757
4679
  import { homedir as homedir3 } from "node:os";
4758
- import { join as join4 } from "node:path";
4680
+ import { join as join3 } from "node:path";
4759
4681
  function getLogsDir() {
4760
4682
  return LOGS_DIR;
4761
4683
  }
4762
4684
  function getLogFile(service) {
4763
- return join4(LOGS_DIR, `${service}.log`);
4685
+ return join3(LOGS_DIR, `${service}.log`);
4764
4686
  }
4765
4687
  async function ensureDirs() {
4766
- await Bun.$`mkdir -p ${STREAMS_DIR3}`.quiet();
4688
+ await Bun.$`mkdir -p ${STATE_DIR}`.quiet();
4767
4689
  await Bun.$`mkdir -p ${LOGS_DIR}`.quiet();
4768
4690
  }
4769
4691
  async function loadDevState() {
@@ -4815,11 +4737,11 @@ async function isDevRunning() {
4815
4737
  const running = await getRunningServices();
4816
4738
  return Object.keys(running).length > 0;
4817
4739
  }
4818
- var STREAMS_DIR3, DEV_STATE_PATH, LOGS_DIR;
4740
+ var STATE_DIR, DEV_STATE_PATH, LOGS_DIR;
4819
4741
  var init_dev_state = __esm(() => {
4820
- STREAMS_DIR3 = join4(homedir3(), ".secondlayer");
4821
- DEV_STATE_PATH = join4(STREAMS_DIR3, "dev.json");
4822
- LOGS_DIR = join4(STREAMS_DIR3, "logs");
4742
+ STATE_DIR = join3(homedir3(), ".secondlayer");
4743
+ DEV_STATE_PATH = join3(STATE_DIR, "dev.json");
4744
+ LOGS_DIR = join3(STATE_DIR, "logs");
4823
4745
  });
4824
4746
 
4825
4747
  // src/utils/format.ts
@@ -6188,7 +6110,7 @@ var require_get_stream = __commonJS((exports, module) => {
6188
6110
  this.name = "MaxBufferError";
6189
6111
  }
6190
6112
  }
6191
- async function getStream2(inputStream, options) {
6113
+ async function getStream(inputStream, options) {
6192
6114
  if (!inputStream) {
6193
6115
  throw new Error("Expected a stream");
6194
6116
  }
@@ -6221,9 +6143,9 @@ var require_get_stream = __commonJS((exports, module) => {
6221
6143
  });
6222
6144
  return stream2.getBufferedValue();
6223
6145
  }
6224
- module.exports = getStream2;
6225
- module.exports.buffer = (stream2, options) => getStream2(stream2, { ...options, encoding: "buffer" });
6226
- module.exports.array = (stream2, options) => getStream2(stream2, { ...options, array: true });
6146
+ module.exports = getStream;
6147
+ module.exports.buffer = (stream2, options) => getStream(stream2, { ...options, encoding: "buffer" });
6148
+ module.exports.array = (stream2, options) => getStream(stream2, { ...options, array: true });
6227
6149
  module.exports.MaxBufferError = MaxBufferError;
6228
6150
  });
6229
6151
 
@@ -6688,9 +6610,9 @@ function lowercaseKeys(object) {
6688
6610
 
6689
6611
  // ../../node_modules/responselike/index.js
6690
6612
  import { Readable as ReadableStream2 } from "node:stream";
6691
- var Response2;
6613
+ var Response;
6692
6614
  var init_responselike = __esm(() => {
6693
- Response2 = class Response2 extends ReadableStream2 {
6615
+ Response = class Response extends ReadableStream2 {
6694
6616
  statusCode;
6695
6617
  headers;
6696
6618
  body;
@@ -7128,7 +7050,7 @@ class CacheableRequest {
7128
7050
  response.once("end", resolve);
7129
7051
  });
7130
7052
  const headers = convertHeaders(revalidatedPolicy.policy.responseHeaders());
7131
- response = new Response2({ statusCode: revalidate.statusCode, headers, body: revalidate.body, url: revalidate.url });
7053
+ response = new Response({ statusCode: revalidate.statusCode, headers, body: revalidate.body, url: revalidate.url });
7132
7054
  response.cachePolicy = revalidatedPolicy.policy;
7133
7055
  response.fromCache = true;
7134
7056
  }
@@ -7204,7 +7126,7 @@ class CacheableRequest {
7204
7126
  const policy = import_http_cache_semantics.default.fromObject(cacheEntry.cachePolicy);
7205
7127
  if (policy.satisfiesWithoutRevalidation(options_) && !options_.forceRefresh) {
7206
7128
  const headers = convertHeaders(policy.responseHeaders());
7207
- const response = new Response2({ statusCode: cacheEntry.statusCode, headers, body: cacheEntry.body, url: cacheEntry.url });
7129
+ const response = new Response({ statusCode: cacheEntry.statusCode, headers, body: cacheEntry.body, url: cacheEntry.url });
7208
7130
  response.cachePolicy = policy;
7209
7131
  response.fromCache = true;
7210
7132
  ee.emit("response", response);
@@ -7467,7 +7389,7 @@ var require_get_stream2 = __commonJS((exports, module) => {
7467
7389
  this.name = "MaxBufferError";
7468
7390
  }
7469
7391
  }
7470
- async function getStream3(inputStream, options) {
7392
+ async function getStream2(inputStream, options) {
7471
7393
  if (!inputStream) {
7472
7394
  throw new Error("Expected a stream");
7473
7395
  }
@@ -7500,9 +7422,9 @@ var require_get_stream2 = __commonJS((exports, module) => {
7500
7422
  });
7501
7423
  return stream3.getBufferedValue();
7502
7424
  }
7503
- module.exports = getStream3;
7504
- module.exports.buffer = (stream3, options) => getStream3(stream3, { ...options, encoding: "buffer" });
7505
- module.exports.array = (stream3, options) => getStream3(stream3, { ...options, array: true });
7425
+ module.exports = getStream2;
7426
+ module.exports.buffer = (stream3, options) => getStream2(stream3, { ...options, encoding: "buffer" });
7427
+ module.exports.array = (stream3, options) => getStream2(stream3, { ...options, array: true });
7506
7428
  module.exports.MaxBufferError = MaxBufferError;
7507
7429
  });
7508
7430
 
@@ -9304,23 +9226,23 @@ var require_client_request = __commonJS((exports, module) => {
9304
9226
  var kPendingAgentPromise = Symbol("pendingAgentPromise");
9305
9227
 
9306
9228
  class ClientRequest extends Writable {
9307
- constructor(input2, options, callback) {
9229
+ constructor(input, options, callback) {
9308
9230
  super({
9309
9231
  autoDestroy: false,
9310
9232
  emitClose: false
9311
9233
  });
9312
- if (typeof input2 === "string") {
9313
- input2 = urlToHttpOptions(new URL2(input2));
9314
- } else if (input2 instanceof URL2) {
9315
- input2 = urlToHttpOptions(input2);
9234
+ if (typeof input === "string") {
9235
+ input = urlToHttpOptions(new URL2(input));
9236
+ } else if (input instanceof URL2) {
9237
+ input = urlToHttpOptions(input);
9316
9238
  } else {
9317
- input2 = { ...input2 };
9239
+ input = { ...input };
9318
9240
  }
9319
9241
  if (typeof options === "function" || options === undefined) {
9320
9242
  callback = options;
9321
- options = input2;
9243
+ options = input;
9322
9244
  } else {
9323
- options = Object.assign(input2, options);
9245
+ options = Object.assign(input, options);
9324
9246
  }
9325
9247
  if (options.h2session) {
9326
9248
  this[kSession] = options.h2session;
@@ -9815,19 +9737,19 @@ var require_auto = __commonJS((exports, module) => {
9815
9737
  };
9816
9738
  };
9817
9739
  var defaultResolveProtocol = createResolveProtocol(cache, queue);
9818
- module.exports = async (input2, options, callback) => {
9819
- if (typeof input2 === "string") {
9820
- input2 = urlToHttpOptions(new URL2(input2));
9821
- } else if (input2 instanceof URL2) {
9822
- input2 = urlToHttpOptions(input2);
9740
+ module.exports = async (input, options, callback) => {
9741
+ if (typeof input === "string") {
9742
+ input = urlToHttpOptions(new URL2(input));
9743
+ } else if (input instanceof URL2) {
9744
+ input = urlToHttpOptions(input);
9823
9745
  } else {
9824
- input2 = { ...input2 };
9746
+ input = { ...input };
9825
9747
  }
9826
9748
  if (typeof options === "function" || options === undefined) {
9827
9749
  callback = options;
9828
- options = input2;
9750
+ options = input;
9829
9751
  } else {
9830
- options = Object.assign(input2, options);
9752
+ options = Object.assign(input, options);
9831
9753
  }
9832
9754
  options.ALPNProtocols = options.ALPNProtocols || ["h2", "http/1.1"];
9833
9755
  if (!Array.isArray(options.ALPNProtocols) || options.ALPNProtocols.length === 0) {
@@ -10134,7 +10056,7 @@ var require_h2_over_h1 = __commonJS((exports, module) => {
10134
10056
  var https = __require("https");
10135
10057
  var Http2OverHttpX = require_h2_over_hx();
10136
10058
  var getAuthorizationHeaders = require_get_auth_headers();
10137
- var getStream3 = (request) => new Promise((resolve, reject) => {
10059
+ var getStream2 = (request) => new Promise((resolve, reject) => {
10138
10060
  const onConnect = (response, socket, head) => {
10139
10061
  socket.unshift(head);
10140
10062
  request.off("error", reject);
@@ -10161,7 +10083,7 @@ var require_h2_over_h1 = __commonJS((exports, module) => {
10161
10083
  },
10162
10084
  method: "CONNECT"
10163
10085
  }).end();
10164
- return getStream3(request);
10086
+ return getStream2(request);
10165
10087
  }
10166
10088
  }
10167
10089
  module.exports = {
@@ -10540,7 +10462,7 @@ var init_options = __esm(() => {
10540
10462
  enableUnixSockets: false
10541
10463
  };
10542
10464
  Options = class Options {
10543
- constructor(input2, options, defaults) {
10465
+ constructor(input, options, defaults) {
10544
10466
  Object.defineProperty(this, "_unixOptions", {
10545
10467
  enumerable: true,
10546
10468
  configurable: true,
@@ -10565,10 +10487,10 @@ var init_options = __esm(() => {
10565
10487
  writable: true,
10566
10488
  value: undefined
10567
10489
  });
10568
- assert.any([dist_default.string, dist_default.urlInstance, dist_default.object, dist_default.undefined], input2);
10490
+ assert.any([dist_default.string, dist_default.urlInstance, dist_default.object, dist_default.undefined], input);
10569
10491
  assert.any([dist_default.object, dist_default.undefined], options);
10570
10492
  assert.any([dist_default.object, dist_default.undefined], defaults);
10571
- if (input2 instanceof Options || options instanceof Options) {
10493
+ if (input instanceof Options || options instanceof Options) {
10572
10494
  throw new TypeError("The defaults must be passed as the third argument");
10573
10495
  }
10574
10496
  this._internals = cloneInternals(defaults?._internals ?? defaults ?? defaultInternals);
@@ -10576,25 +10498,25 @@ var init_options = __esm(() => {
10576
10498
  this._merging = false;
10577
10499
  this._unixOptions = undefined;
10578
10500
  try {
10579
- if (dist_default.plainObject(input2)) {
10501
+ if (dist_default.plainObject(input)) {
10580
10502
  try {
10581
- this.merge(input2);
10503
+ this.merge(input);
10582
10504
  this.merge(options);
10583
10505
  } finally {
10584
- this.url = input2.url;
10506
+ this.url = input.url;
10585
10507
  }
10586
10508
  } else {
10587
10509
  try {
10588
10510
  this.merge(options);
10589
10511
  } finally {
10590
10512
  if (options?.url !== undefined) {
10591
- if (input2 === undefined) {
10513
+ if (input === undefined) {
10592
10514
  this.url = options.url;
10593
10515
  } else {
10594
10516
  throw new TypeError("The `url` option is mutually exclusive with the `input` argument");
10595
10517
  }
10596
- } else if (input2 !== undefined) {
10597
- this.url = input2;
10518
+ } else if (input !== undefined) {
10519
+ this.url = input;
10598
10520
  }
10599
10521
  }
10600
10522
  }
@@ -13254,9 +13176,6 @@ async function startWorker(options2) {
13254
13176
  const rootDir = dirname2(dirname2(dirname2(dirname2(import.meta.dir))));
13255
13177
  const workerPath = resolve3(rootDir, "packages/worker/src/index.ts");
13256
13178
  await serviceManager.start(SERVICE_NAME2, ["bun", "run", "--watch", workerPath], {
13257
- env: {
13258
- WORKER_CONCURRENCY: String(options2.concurrency ?? 5)
13259
- },
13260
13179
  onStdout: options2.onLog,
13261
13180
  onStderr: options2.onLog
13262
13181
  });
@@ -13286,93 +13205,6 @@ var init_api2 = __esm(() => {
13286
13205
  init_manager();
13287
13206
  });
13288
13207
 
13289
- // src/services/receiver-server.ts
13290
- import { verifySignatureHeader } from "@secondlayer/shared/crypto";
13291
- function startReceiverServer(options2 = {}) {
13292
- const port = options2.port ?? 3900;
13293
- const responseCode = options2.responseCode ?? 200;
13294
- server = Bun.serve({
13295
- port,
13296
- fetch: async (req) => {
13297
- const url = new URL(req.url);
13298
- const method = req.method;
13299
- const path = url.pathname;
13300
- if (path === "/health" && method === "GET") {
13301
- return new Response("OK", { status: 200 });
13302
- }
13303
- if (method !== "POST") {
13304
- return new Response("Method not allowed", { status: 405 });
13305
- }
13306
- const headers = {};
13307
- req.headers.forEach((value, key) => {
13308
- headers[key] = value;
13309
- });
13310
- let body;
13311
- let signatureValid = null;
13312
- try {
13313
- const rawBody = await req.text();
13314
- body = JSON.parse(rawBody);
13315
- const signatureHeader = headers["x-streams-signature"];
13316
- if (options2.secret && signatureHeader) {
13317
- signatureValid = verifySignatureHeader(rawBody, signatureHeader, options2.secret);
13318
- }
13319
- } catch {
13320
- body = null;
13321
- }
13322
- const event = {
13323
- timestamp: new Date,
13324
- method,
13325
- path,
13326
- headers,
13327
- body,
13328
- signatureValid
13329
- };
13330
- if (options2.onDelivery) {
13331
- options2.onDelivery(event);
13332
- } else {
13333
- logDelivery(event);
13334
- }
13335
- return new Response("OK", { status: responseCode });
13336
- }
13337
- });
13338
- return port;
13339
- }
13340
- function stopReceiverServer() {
13341
- if (server) {
13342
- server.stop();
13343
- server = null;
13344
- }
13345
- }
13346
- function logDelivery(event) {
13347
- const time = event.timestamp.toISOString();
13348
- console.log("");
13349
- console.log(blue("━".repeat(60)));
13350
- console.log(green("⚡ Delivery received"));
13351
- console.log(dim(` ${time}`));
13352
- console.log(dim(` ${event.method} ${event.path}`));
13353
- if (event.signatureValid === true) {
13354
- console.log(green(" ✓ Signature valid"));
13355
- } else if (event.signatureValid === false) {
13356
- console.log(red(" ✗ Signature invalid"));
13357
- } else if (event.headers["x-streams-signature"]) {
13358
- console.log(yellow(" ⚠ Signature not verified (no secret configured)"));
13359
- }
13360
- if (event.body) {
13361
- console.log(dim(`
13362
- Payload:`));
13363
- const lines = JSON.stringify(event.body, null, 2).split(`
13364
- `);
13365
- for (const line of lines) {
13366
- console.log(` ${line}`);
13367
- }
13368
- }
13369
- console.log(blue("━".repeat(60)));
13370
- }
13371
- var server = null;
13372
- var init_receiver_server = __esm(() => {
13373
- init_output();
13374
- });
13375
-
13376
13208
  // src/services/subgraph-processor.ts
13377
13209
  import { dirname as dirname4, resolve as resolve5 } from "node:path";
13378
13210
  async function startSubgraphProcessor(options2) {
@@ -13397,7 +13229,6 @@ var init_services = __esm(() => {
13397
13229
  init_indexer();
13398
13230
  init_worker();
13399
13231
  init_api2();
13400
- init_receiver_server();
13401
13232
  init_subgraph_processor();
13402
13233
  });
13403
13234
 
@@ -13413,7 +13244,7 @@ __export(exports_dev_impl, {
13413
13244
  isDevAlreadyRunning: () => isDevAlreadyRunning
13414
13245
  });
13415
13246
  import { mkdirSync as mkdirSync2 } from "node:fs";
13416
- import { dirname as dirname5, join as join6, resolve as resolve6 } from "node:path";
13247
+ import { dirname as dirname5, join as join4, resolve as resolve6 } from "node:path";
13417
13248
  async function isDevAlreadyRunning() {
13418
13249
  if (await isDevRunning()) {
13419
13250
  const running = await getRunningServices();
@@ -13425,7 +13256,6 @@ async function isDevAlreadyRunning() {
13425
13256
  console.log(` ${green("sl local logs")} ${dim("View logs")}`);
13426
13257
  console.log(` ${green("sl local stop")} ${dim("Stop all services")}`);
13427
13258
  console.log(` ${green("sl local status")} ${dim("Show status")}`);
13428
- console.log(` ${green("sl streams set --all paused --wait")} ${dim("Pause stream processing")}`);
13429
13259
  return true;
13430
13260
  }
13431
13261
  return false;
@@ -13441,7 +13271,6 @@ async function runBackground(options2) {
13441
13271
  const dataDir = getDataDir(config);
13442
13272
  const indexerPort = options2.stacksNode ? 3701 : Number.parseInt(options2.indexerPort) || config.ports.indexer;
13443
13273
  const apiPort = Number.parseInt(options2.apiPort) || config.ports.api;
13444
- const receiverPort = Number.parseInt(options2.receiverPort) || config.ports.receiver;
13445
13274
  if (options2.stacksNode && config.node) {
13446
13275
  const validation = await validateNetworkConsistency(config);
13447
13276
  if (!validation.valid) {
@@ -13454,7 +13283,7 @@ async function runBackground(options2) {
13454
13283
  }
13455
13284
  await ensureDirs();
13456
13285
  await clearLogs();
13457
- printBanner2();
13286
+ printBanner();
13458
13287
  try {
13459
13288
  await requireDocker();
13460
13289
  } catch (err) {
@@ -13555,32 +13384,6 @@ async function runBackground(options2) {
13555
13384
  };
13556
13385
  console.log(green(" ✓ Subgraph processor"), dim("processing subgraphs"));
13557
13386
  }
13558
- if (options2.receiver) {
13559
- const receiverLogFile = getLogFile("receiver");
13560
- const receiverArgs = [
13561
- "bun",
13562
- "run",
13563
- resolve6(packagesDir, "packages/cli/src/services/receiver-standalone.ts")
13564
- ];
13565
- const receiverEnv = {
13566
- ...process.env,
13567
- PORT: String(receiverPort)
13568
- };
13569
- if (options2.secret)
13570
- receiverEnv.SIGNING_SECRET = options2.secret;
13571
- const receiverProc = Bun.spawn(receiverArgs, {
13572
- env: receiverEnv,
13573
- stdout: Bun.file(receiverLogFile),
13574
- stderr: Bun.file(receiverLogFile)
13575
- });
13576
- state.services.receiver = {
13577
- pid: receiverProc.pid,
13578
- port: receiverPort,
13579
- startedAt: new Date().toISOString(),
13580
- logFile: receiverLogFile
13581
- };
13582
- console.log(green(" ✓ Receiver server"), dim(`http://localhost:${receiverPort}`));
13583
- }
13584
13387
  await Bun.sleep(500);
13585
13388
  for (const [name, service] of Object.entries(state.services)) {
13586
13389
  if (!isProcessRunning(service.pid)) {
@@ -13589,7 +13392,7 @@ async function runBackground(options2) {
13589
13392
  }
13590
13393
  await saveDevState(state);
13591
13394
  console.log("");
13592
- printUrls(indexerPort, apiPort, receiverPort, options2.receiver);
13395
+ printUrls(indexerPort, apiPort);
13593
13396
  console.log("");
13594
13397
  success("Dev environment started in background");
13595
13398
  console.log("");
@@ -13597,7 +13400,6 @@ async function runBackground(options2) {
13597
13400
  console.log(` ${green("sl local logs -f")} ${dim("Follow logs")}`);
13598
13401
  console.log(` ${green("sl local stop")} ${dim("Stop all services")}`);
13599
13402
  console.log(` ${green("sl local status")} ${dim("Show status")}`);
13600
- console.log(` ${green("sl streams set --all paused --wait")} ${dim("Pause stream processing")}`);
13601
13403
  console.log("");
13602
13404
  process.exit(0);
13603
13405
  } catch (err) {
@@ -13627,20 +13429,16 @@ async function runForeground(options2) {
13627
13429
  const dataDir = getDataDir(config);
13628
13430
  const indexerPort = options2.stacksNode ? 3701 : Number.parseInt(options2.indexerPort) || config.ports.indexer;
13629
13431
  const apiPort = Number.parseInt(options2.apiPort) || config.ports.api;
13630
- const receiverPort = Number.parseInt(options2.receiverPort) || config.ports.receiver;
13631
13432
  let devPostgresStarted = false;
13632
13433
  const shutdown = async () => {
13633
13434
  console.log(`
13634
13435
  `);
13635
13436
  info("Shutting down services...");
13636
- if (options2.receiver) {
13637
- stopReceiverServer();
13638
- }
13639
13437
  await serviceManager.stopAll();
13640
13438
  if (devPostgresStarted) {
13641
13439
  info("Stopping PostgreSQL container...");
13642
- await Bun.$`docker stop streams-dev-postgres`.quiet().nothrow();
13643
- await Bun.$`docker rm streams-dev-postgres`.quiet().nothrow();
13440
+ await Bun.$`docker stop secondlayer-dev-postgres`.quiet().nothrow();
13441
+ await Bun.$`docker rm secondlayer-dev-postgres`.quiet().nothrow();
13644
13442
  }
13645
13443
  success("All services stopped");
13646
13444
  process.exit(0);
@@ -13648,7 +13446,7 @@ async function runForeground(options2) {
13648
13446
  process.on("SIGINT", shutdown);
13649
13447
  process.on("SIGTERM", shutdown);
13650
13448
  try {
13651
- printBanner2();
13449
+ printBanner();
13652
13450
  try {
13653
13451
  await requireDocker();
13654
13452
  } catch (err) {
@@ -13681,10 +13479,6 @@ async function runForeground(options2) {
13681
13479
  console.log("");
13682
13480
  }
13683
13481
  process.env.DEV_MODE = "true";
13684
- if (options2.receiver) {
13685
- startReceiverServer({ port: receiverPort, secret: options2.secret });
13686
- console.log(green(" ✓ Receiver server"), dim(`http://localhost:${receiverPort}`));
13687
- }
13688
13482
  await startApi({ port: apiPort, onLog: (line) => logService("api", line) });
13689
13483
  console.log(green(" ✓ API"), dim(`http://localhost:${apiPort}`));
13690
13484
  await startIndexer({
@@ -13701,7 +13495,7 @@ async function runForeground(options2) {
13701
13495
  });
13702
13496
  console.log(green(" ✓ Subgraph processor"), dim("processing subgraphs"));
13703
13497
  console.log("");
13704
- printUrls(indexerPort, apiPort, receiverPort, options2.receiver);
13498
+ printUrls(indexerPort, apiPort);
13705
13499
  console.log("");
13706
13500
  info("Press Ctrl+C to stop all services");
13707
13501
  console.log("");
@@ -13709,9 +13503,6 @@ async function runForeground(options2) {
13709
13503
  } catch (err) {
13710
13504
  error(`Failed to start services: ${err}`);
13711
13505
  await serviceManager.stopAll();
13712
- if (options2.receiver) {
13713
- stopReceiverServer();
13714
- }
13715
13506
  process.exit(1);
13716
13507
  }
13717
13508
  }
@@ -13734,30 +13525,13 @@ async function showLogs(options2) {
13734
13525
  return;
13735
13526
  }
13736
13527
  const lines = Number.parseInt(options2.lines);
13737
- const verbose = options2.verbose ?? false;
13738
13528
  if (options2.follow) {
13739
- await followLogs2(serviceEntries, lines, verbose);
13529
+ await followLogs(serviceEntries, lines);
13740
13530
  } else {
13741
- await showStaticLogs(serviceEntries, lines, verbose);
13742
- }
13743
- }
13744
- function formatDeliverySummary(jsonStr) {
13745
- try {
13746
- const data = JSON.parse(jsonStr);
13747
- if (data.type !== "delivery" || !data.body)
13748
- return null;
13749
- const { body, method, path, timestamp } = data;
13750
- const streamName = body.streamName ?? body.streamId?.slice(0, 8) ?? "unknown";
13751
- const height = body.block?.height ?? "?";
13752
- const txCount = body.matches?.transactions?.length ?? 0;
13753
- const eventCount = body.matches?.events?.length ?? 0;
13754
- const dimTimestamp = dim(`[${timestamp}]`);
13755
- return `${dimTimestamp} ${green("INFO:")} ${method} ${path} — ${streamName} block:${height} (${txCount} txs, ${eventCount} events)`;
13756
- } catch {
13757
- return null;
13531
+ await showStaticLogs(serviceEntries, lines);
13758
13532
  }
13759
13533
  }
13760
- function formatLogLine2(service, line, verbose) {
13534
+ function formatLogLine2(service, line) {
13761
13535
  const colorFn = serviceColors[service] ?? dim;
13762
13536
  const prefix = colorFn(`[${service}]`);
13763
13537
  const match = line.match(/^(\[\d{4}-\d{2}-\d{2}T[\d:.]+Z\])\s*(INFO|WARN|ERROR|DEBUG):?\s*(.*)$/);
@@ -13774,14 +13548,9 @@ function formatLogLine2(service, line, verbose) {
13774
13548
  return `${prefix} ${dimTimestamp} ${dim(level + ":")} ${dim(message)}`;
13775
13549
  }
13776
13550
  }
13777
- if (service === "receiver" && !verbose) {
13778
- const summary = formatDeliverySummary(line);
13779
- if (summary)
13780
- return `${prefix} ${summary}`;
13781
- }
13782
13551
  return `${prefix} ${line}`;
13783
13552
  }
13784
- async function showStaticLogs(services, lines, verbose) {
13553
+ async function showStaticLogs(services, lines) {
13785
13554
  const allLines = [];
13786
13555
  for (const [name, service] of services) {
13787
13556
  try {
@@ -13797,11 +13566,11 @@ async function showStaticLogs(services, lines, verbose) {
13797
13566
  }
13798
13567
  allLines.sort((a, b2) => a.timestamp.getTime() - b2.timestamp.getTime());
13799
13568
  for (const { service, line } of allLines.slice(-lines)) {
13800
- console.log(formatLogLine2(service, line, verbose));
13569
+ console.log(formatLogLine2(service, line));
13801
13570
  }
13802
13571
  }
13803
- async function followLogs2(services, initialLines, verbose) {
13804
- await showStaticLogs(services, initialLines, verbose);
13572
+ async function followLogs(services, initialLines) {
13573
+ await showStaticLogs(services, initialLines);
13805
13574
  const procs = [];
13806
13575
  for (const [name, service] of services) {
13807
13576
  const proc = Bun.spawn(["tail", "-f", "-n", "0", service.logFile], {
@@ -13823,7 +13592,7 @@ async function followLogs2(services, initialLines, verbose) {
13823
13592
  buffer2 = lines.pop() || "";
13824
13593
  for (const line of lines) {
13825
13594
  if (line.trim()) {
13826
- console.log(formatLogLine2(name, line, verbose));
13595
+ console.log(formatLogLine2(name, line));
13827
13596
  }
13828
13597
  }
13829
13598
  }
@@ -13853,14 +13622,14 @@ async function stopDev() {
13853
13622
  }
13854
13623
  if (state.dockerContainers.postgres) {
13855
13624
  info("Stopping PostgreSQL container...");
13856
- await Bun.$`docker stop streams-dev-postgres`.quiet().nothrow();
13857
- await Bun.$`docker rm streams-dev-postgres`.quiet().nothrow();
13625
+ await Bun.$`docker stop secondlayer-dev-postgres`.quiet().nothrow();
13626
+ await Bun.$`docker rm secondlayer-dev-postgres`.quiet().nothrow();
13858
13627
  }
13859
13628
  await clearDevState();
13860
13629
  success("Dev environment stopped");
13861
13630
  return;
13862
13631
  }
13863
- const pgOrphan = await isContainerRunning("streams-dev-postgres");
13632
+ const pgOrphan = await isContainerRunning("secondlayer-dev-postgres");
13864
13633
  if (!pgOrphan) {
13865
13634
  info("Dev environment is not running");
13866
13635
  return;
@@ -13868,8 +13637,8 @@ async function stopDev() {
13868
13637
  info("Cleaning up orphaned containers...");
13869
13638
  if (pgOrphan) {
13870
13639
  info("Stopping PostgreSQL container...");
13871
- await Bun.$`docker stop streams-dev-postgres`.quiet().nothrow();
13872
- await Bun.$`docker rm streams-dev-postgres`.quiet().nothrow();
13640
+ await Bun.$`docker stop secondlayer-dev-postgres`.quiet().nothrow();
13641
+ await Bun.$`docker rm secondlayer-dev-postgres`.quiet().nothrow();
13873
13642
  }
13874
13643
  success("Orphaned containers stopped");
13875
13644
  }
@@ -13951,29 +13720,6 @@ async function restartDev() {
13951
13720
  };
13952
13721
  console.log(green(" ✓ Worker"), dim("processing jobs"));
13953
13722
  }
13954
- if (state.services.receiver) {
13955
- const receiverPort = config.ports.receiver;
13956
- const receiverLogFile = getLogFile("receiver");
13957
- const receiverProc = Bun.spawn([
13958
- "bun",
13959
- "run",
13960
- resolve6(packagesDir, "packages/cli/src/services/receiver-standalone.ts")
13961
- ], {
13962
- env: {
13963
- ...process.env,
13964
- PORT: String(receiverPort)
13965
- },
13966
- stdout: Bun.file(receiverLogFile),
13967
- stderr: Bun.file(receiverLogFile)
13968
- });
13969
- newState.services.receiver = {
13970
- pid: receiverProc.pid,
13971
- port: receiverPort,
13972
- startedAt: new Date().toISOString(),
13973
- logFile: receiverLogFile
13974
- };
13975
- console.log(green(" ✓ Receiver server"), dim(`http://localhost:${receiverPort}`));
13976
- }
13977
13723
  if (state.services.subgraphs) {
13978
13724
  const subgraphsLogFile = getLogFile("subgraphs");
13979
13725
  const subgraphsProc = Bun.spawn(["bun", "run", resolve6(packagesDir, "packages/subgraphs/src/service.ts")], {
@@ -14021,8 +13767,8 @@ async function showDevStatus() {
14021
13767
  printRunningServices(running);
14022
13768
  console.log("");
14023
13769
  console.log(blue("Docker Containers"));
14024
- const pgRunning = await isContainerRunning("streams-dev-postgres");
14025
- console.log(` ${pgRunning ? green("✓") : red("✗")} PostgreSQL ${dim("streams-dev-postgres")}`);
13770
+ const pgRunning = await isContainerRunning("secondlayer-dev-postgres");
13771
+ console.log(` ${pgRunning ? green("✓") : red("✗")} PostgreSQL ${dim("secondlayer-dev-postgres")}`);
14026
13772
  console.log("");
14027
13773
  console.log(dim(`Started: ${state.startedAt}`));
14028
13774
  console.log(dim(`Logs: ${getLogsDir()}`));
@@ -14039,32 +13785,26 @@ async function isContainerRunning(name) {
14039
13785
  const result = await Bun.$`docker ps -q -f name=${name}`.quiet().nothrow();
14040
13786
  return result.stdout.toString().trim().length > 0;
14041
13787
  }
14042
- function printBanner2() {
13788
+ function printBanner() {
14043
13789
  console.log("");
14044
13790
  console.log(blue(" ╔═══════════════════════════════════════╗"));
14045
- console.log(blue(" ║") + " Stacks Streams Dev Server " + blue("║"));
13791
+ console.log(blue(" ║") + " Secondlayer Dev Server " + blue("║"));
14046
13792
  console.log(blue(" ╚═══════════════════════════════════════╝"));
14047
13793
  console.log("");
14048
13794
  console.log(dim(" Starting services..."));
14049
13795
  console.log("");
14050
13796
  }
14051
- function printUrls(indexerPort, apiPort, receiverPort, receiverEnabled) {
13797
+ function printUrls(indexerPort, apiPort) {
14052
13798
  console.log(dim(" ─────────────────────────────────────────"));
14053
13799
  console.log("");
14054
13800
  console.log(" " + blue("API:"));
14055
- console.log(` List streams: curl http://localhost:${apiPort}/streams`);
13801
+ console.log(` List subgraphs: curl http://localhost:${apiPort}/api/subgraphs`);
14056
13802
  console.log(` Health check: curl http://localhost:${apiPort}/health`);
14057
13803
  console.log("");
14058
13804
  console.log(" " + blue("Indexer:"));
14059
13805
  console.log(` Health check: curl http://localhost:${indexerPort}/health`);
14060
13806
  console.log(` Send block: curl -X POST http://localhost:${indexerPort}/new_block -d @block.json`);
14061
13807
  console.log("");
14062
- if (receiverEnabled) {
14063
- console.log(" " + blue("Test Receiver:"));
14064
- console.log(` Receives deliveries at http://localhost:${receiverPort}/`);
14065
- console.log(` Use this URL when creating streams for testing`);
14066
- console.log("");
14067
- }
14068
13808
  console.log(" " + blue("Stacks Node Config:"));
14069
13809
  console.log(dim(" Add to your Stacks node Config.toml:"));
14070
13810
  console.log("");
@@ -14106,19 +13846,19 @@ async function isDatabaseReachable(url) {
14106
13846
  }
14107
13847
  }
14108
13848
  async function ensureDevPostgres(dataDir) {
14109
- const check = await Bun.$`docker ps -q -f name=streams-dev-postgres`.quiet().nothrow();
13849
+ const check = await Bun.$`docker ps -q -f name=secondlayer-dev-postgres`.quiet().nothrow();
14110
13850
  if (check.stdout.toString().trim()) {
14111
13851
  return false;
14112
13852
  }
14113
- const pgDataDir = join6(dataDir, "postgres");
13853
+ const pgDataDir = join4(dataDir, "postgres");
14114
13854
  mkdirSync2(pgDataDir, { recursive: true });
14115
- const stopped = await Bun.$`docker ps -aq -f name=streams-dev-postgres`.quiet().nothrow();
13855
+ const stopped = await Bun.$`docker ps -aq -f name=secondlayer-dev-postgres`.quiet().nothrow();
14116
13856
  if (stopped.stdout.toString().trim()) {
14117
- await Bun.$`docker rm streams-dev-postgres`.quiet().nothrow();
13857
+ await Bun.$`docker rm secondlayer-dev-postgres`.quiet().nothrow();
14118
13858
  }
14119
- await Bun.$`docker run -d --name streams-dev-postgres -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=streams_dev -v ${pgDataDir}:/var/lib/postgresql/data -p 5432:5432 postgres:16-alpine`.quiet();
13859
+ await Bun.$`docker run -d --name secondlayer-dev-postgres -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=secondlayer_dev -v ${pgDataDir}:/var/lib/postgresql/data -p 5432:5432 postgres:16-alpine`.quiet();
14120
13860
  for (let i = 0;i < 30; i++) {
14121
- const ready = await Bun.$`docker exec streams-dev-postgres pg_isready -U postgres`.quiet().nothrow();
13861
+ const ready = await Bun.$`docker exec secondlayer-dev-postgres pg_isready -U postgres`.quiet().nothrow();
14122
13862
  if (ready.exitCode === 0)
14123
13863
  return true;
14124
13864
  await Bun.sleep(500);
@@ -14133,7 +13873,7 @@ async function runMigrations(databaseUrl) {
14133
13873
  throw new Error(`Migration failed: ${result.stderr.toString()}`);
14134
13874
  }
14135
13875
  }
14136
- var DEV_DATABASE_URL3 = "postgres://postgres:postgres@localhost:5432/streams_dev", serviceColors;
13876
+ var DEV_DATABASE_URL3 = "postgres://postgres:postgres@localhost:5432/secondlayer_dev", serviceColors;
14137
13877
  var init_dev_impl = __esm(() => {
14138
13878
  init_config();
14139
13879
  init_dev_state();
@@ -14145,8 +13885,7 @@ var init_dev_impl = __esm(() => {
14145
13885
  api: blue,
14146
13886
  indexer: cyan,
14147
13887
  worker: yellow,
14148
- subgraphs: magenta,
14149
- receiver: green
13888
+ subgraphs: magenta
14150
13889
  };
14151
13890
  });
14152
13891
 
@@ -14161,7 +13900,7 @@ __export(exports_node_impl, {
14161
13900
  runSetupWizard: () => runSetupWizard,
14162
13901
  restartNode: () => restartNode
14163
13902
  });
14164
- import { confirm as confirm7, input as input3, select as select3 } from "@inquirer/prompts";
13903
+ import { confirm as confirm4, input as input2, select as select2 } from "@inquirer/prompts";
14165
13904
  async function runSetupWizard() {
14166
13905
  console.log("");
14167
13906
  console.log(blue("Stacks Node Setup Wizard"));
@@ -14179,7 +13918,7 @@ async function runSetupWizard() {
14179
13918
  }
14180
13919
  success("Docker is running");
14181
13920
  console.log("");
14182
- const installPath = await input3({
13921
+ const installPath = await input2({
14183
13922
  message: "Where is stacks-blockchain-docker installed?",
14184
13923
  validate: async (value) => {
14185
13924
  if (!value.trim())
@@ -14190,7 +13929,7 @@ async function runSetupWizard() {
14190
13929
  return true;
14191
13930
  }
14192
13931
  });
14193
- const network = await select3({
13932
+ const network = await select2({
14194
13933
  message: "Which network?",
14195
13934
  choices: [
14196
13935
  { name: "mainnet", value: "mainnet" },
@@ -14198,18 +13937,18 @@ async function runSetupWizard() {
14198
13937
  ],
14199
13938
  default: "mainnet"
14200
13939
  });
14201
- const autoStartIndexer = await confirm7({
14202
- message: "Auto-start streams indexer when node starts?",
13940
+ const autoStartIndexer = await confirm4({
13941
+ message: "Auto-start indexer when node starts?",
14203
13942
  default: true
14204
13943
  });
14205
13944
  let indexerPort = 3700;
14206
13945
  if (autoStartIndexer) {
14207
- const customPort = await confirm7({
13946
+ const customPort = await confirm4({
14208
13947
  message: "Use default indexer port (3700)?",
14209
13948
  default: true
14210
13949
  });
14211
13950
  if (!customPort) {
14212
- const portInput = await input3({
13951
+ const portInput = await input2({
14213
13952
  message: "Enter custom indexer port:",
14214
13953
  default: "3700",
14215
13954
  validate: (value) => {
@@ -14304,13 +14043,13 @@ async function startNode(pathOverride, withIndexer) {
14304
14043
  console.log(" " + green("sl local node logs -f") + dim(" - Follow logs"));
14305
14044
  console.log("");
14306
14045
  }
14307
- async function stopNode(_pathOverride, force, wait) {
14046
+ async function stopNode(_pathOverride, force, _wait) {
14308
14047
  if (!await isNodeRunning()) {
14309
14048
  info("Node is not running");
14310
14049
  return;
14311
14050
  }
14312
14051
  if (!force) {
14313
- const proceed = await confirm7({
14052
+ const proceed = await confirm4({
14314
14053
  message: "Stop the Stacks node?",
14315
14054
  default: false
14316
14055
  });
@@ -14320,9 +14059,6 @@ async function stopNode(_pathOverride, force, wait) {
14320
14059
  }
14321
14060
  }
14322
14061
  console.log("");
14323
- if (wait) {
14324
- await pauseAndWait();
14325
- }
14326
14062
  info("Stopping Stacks node...");
14327
14063
  const stopped = await stopNodeContainers();
14328
14064
  if (stopped.length === 0) {
@@ -14331,7 +14067,7 @@ async function stopNode(_pathOverride, force, wait) {
14331
14067
  }
14332
14068
  success(`Stopped: ${stopped.join(", ")}`);
14333
14069
  }
14334
- async function restartNode(pathOverride, force, wait) {
14070
+ async function restartNode(pathOverride, force, _wait) {
14335
14071
  const config = await loadConfig();
14336
14072
  const nodePath = pathOverride || config.node?.installPath;
14337
14073
  const network = config.node?.network || "mainnet";
@@ -14343,7 +14079,7 @@ async function restartNode(pathOverride, force, wait) {
14343
14079
  const wasRunning = await isNodeRunning();
14344
14080
  if (wasRunning) {
14345
14081
  if (!force) {
14346
- const proceed = await confirm7({
14082
+ const proceed = await confirm4({
14347
14083
  message: "Restart the Stacks node?",
14348
14084
  default: false
14349
14085
  });
@@ -14353,9 +14089,6 @@ async function restartNode(pathOverride, force, wait) {
14353
14089
  }
14354
14090
  }
14355
14091
  console.log("");
14356
- if (wait) {
14357
- await pauseAndWait();
14358
- }
14359
14092
  info("Stopping Stacks node...");
14360
14093
  const stopped = await stopNodeContainers();
14361
14094
  if (stopped.length > 0) {
@@ -14383,33 +14116,6 @@ async function restartNode(pathOverride, force, wait) {
14383
14116
  console.log(" " + green("sl local node logs -f") + dim(" - Follow logs"));
14384
14117
  console.log("");
14385
14118
  }
14386
- async function pauseAndWait() {
14387
- const POLL_INTERVAL_MS = 1000;
14388
- try {
14389
- info("Pausing streams...");
14390
- const result = await pauseAllStreams();
14391
- if (result.paused > 0) {
14392
- success(`Paused ${result.paused} stream${result.paused === 1 ? "" : "s"}`);
14393
- }
14394
- process.stdout.write(dim("Waiting for jobs to complete..."));
14395
- while (true) {
14396
- const stats = await getQueueStats();
14397
- const active = stats.pending + stats.processing;
14398
- if (active === 0) {
14399
- process.stdout.write(`
14400
- `);
14401
- success("All jobs completed");
14402
- console.log("");
14403
- return;
14404
- }
14405
- process.stdout.write(`\r${dim(`Waiting for jobs to complete... ${active} remaining`)}`);
14406
- await Bun.sleep(POLL_INTERVAL_MS);
14407
- }
14408
- } catch {
14409
- warn("Could not pause streams (API may not be running)");
14410
- console.log("");
14411
- }
14412
- }
14413
14119
  async function showStatus(pathOverride, jsonOutput) {
14414
14120
  const config = await loadConfig();
14415
14121
  const nodePath = pathOverride || config.node?.installPath;
@@ -14505,13 +14211,13 @@ async function showStatus(pathOverride, jsonOutput) {
14505
14211
  signal: AbortSignal.timeout(2000)
14506
14212
  });
14507
14213
  if (indexerRes.ok) {
14508
- console.log(blue("Streams Indexer"));
14214
+ console.log(blue("Indexer"));
14509
14215
  console.log(` ${green("+")} Running on port ${indexerPort}`);
14510
14216
  console.log("");
14511
14217
  }
14512
14218
  } catch {
14513
14219
  if (config.node) {
14514
- console.log(blue("Streams Indexer"));
14220
+ console.log(blue("Indexer"));
14515
14221
  console.log(` ${dim("-")} ${dim(`Not running (expected on port ${indexerPort})`)}`);
14516
14222
  console.log(dim(` Start with: sl local start`));
14517
14223
  console.log("");
@@ -14570,7 +14276,6 @@ async function showConfigCheck(indexerPort) {
14570
14276
  }
14571
14277
  var DEFAULT_RPC_PORT = 20443;
14572
14278
  var init_node_impl = __esm(() => {
14573
- init_api_client();
14574
14279
  init_config();
14575
14280
  init_network();
14576
14281
  init_node_manager();
@@ -15724,8 +15429,8 @@ var require_fill_range = __commonJS((exports, module) => {
15724
15429
  return typeof value === "number" || typeof value === "string" && value !== "";
15725
15430
  };
15726
15431
  var isNumber = (num) => Number.isInteger(+num);
15727
- var zeros = (input4) => {
15728
- let value = `${input4}`;
15432
+ var zeros = (input3) => {
15433
+ let value = `${input3}`;
15729
15434
  let index = -1;
15730
15435
  if (value[0] === "-")
15731
15436
  value = value.slice(1);
@@ -15741,27 +15446,27 @@ var require_fill_range = __commonJS((exports, module) => {
15741
15446
  }
15742
15447
  return options2.stringify === true;
15743
15448
  };
15744
- var pad = (input4, maxLength, toNumber) => {
15449
+ var pad = (input3, maxLength, toNumber) => {
15745
15450
  if (maxLength > 0) {
15746
- let dash = input4[0] === "-" ? "-" : "";
15451
+ let dash = input3[0] === "-" ? "-" : "";
15747
15452
  if (dash)
15748
- input4 = input4.slice(1);
15749
- input4 = dash + input4.padStart(dash ? maxLength - 1 : maxLength, "0");
15453
+ input3 = input3.slice(1);
15454
+ input3 = dash + input3.padStart(dash ? maxLength - 1 : maxLength, "0");
15750
15455
  }
15751
15456
  if (toNumber === false) {
15752
- return String(input4);
15457
+ return String(input3);
15753
15458
  }
15754
- return input4;
15459
+ return input3;
15755
15460
  };
15756
- var toMaxLen = (input4, maxLength) => {
15757
- let negative = input4[0] === "-" ? "-" : "";
15461
+ var toMaxLen = (input3, maxLength) => {
15462
+ let negative = input3[0] === "-" ? "-" : "";
15758
15463
  if (negative) {
15759
- input4 = input4.slice(1);
15464
+ input3 = input3.slice(1);
15760
15465
  maxLength--;
15761
15466
  }
15762
- while (input4.length < maxLength)
15763
- input4 = "0" + input4;
15764
- return negative ? "-" + input4 : input4;
15467
+ while (input3.length < maxLength)
15468
+ input3 = "0" + input3;
15469
+ return negative ? "-" + input3 : input3;
15765
15470
  };
15766
15471
  var toSequence = (parts, options2, maxLen) => {
15767
15472
  parts.negatives.sort((a, b2) => a < b2 ? -1 : a > b2 ? 1 : 0);
@@ -16130,25 +15835,25 @@ var require_parse = __commonJS((exports, module) => {
16130
15835
  CHAR_NO_BREAK_SPACE,
16131
15836
  CHAR_ZERO_WIDTH_NOBREAK_SPACE
16132
15837
  } = require_constants();
16133
- var parse2 = (input4, options2 = {}) => {
16134
- if (typeof input4 !== "string") {
15838
+ var parse2 = (input3, options2 = {}) => {
15839
+ if (typeof input3 !== "string") {
16135
15840
  throw new TypeError("Expected a string");
16136
15841
  }
16137
15842
  const opts = options2 || {};
16138
15843
  const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
16139
- if (input4.length > max) {
16140
- throw new SyntaxError(`Input length (${input4.length}), exceeds max characters (${max})`);
15844
+ if (input3.length > max) {
15845
+ throw new SyntaxError(`Input length (${input3.length}), exceeds max characters (${max})`);
16141
15846
  }
16142
- const ast = { type: "root", input: input4, nodes: [] };
15847
+ const ast = { type: "root", input: input3, nodes: [] };
16143
15848
  const stack = [ast];
16144
15849
  let block = ast;
16145
15850
  let prev = ast;
16146
15851
  let brackets = 0;
16147
- const length = input4.length;
15852
+ const length = input3.length;
16148
15853
  let index = 0;
16149
15854
  let depth = 0;
16150
15855
  let value;
16151
- const advance = () => input4[index++];
15856
+ const advance = () => input3[index++];
16152
15857
  const push = (node) => {
16153
15858
  if (node.type === "text" && prev.type === "dot") {
16154
15859
  prev.type = "text";
@@ -16343,10 +16048,10 @@ var require_braces = __commonJS((exports, module) => {
16343
16048
  var compile = require_compile();
16344
16049
  var expand = require_expand();
16345
16050
  var parse2 = require_parse();
16346
- var braces = (input4, options2 = {}) => {
16051
+ var braces = (input3, options2 = {}) => {
16347
16052
  let output = [];
16348
- if (Array.isArray(input4)) {
16349
- for (const pattern of input4) {
16053
+ if (Array.isArray(input3)) {
16054
+ for (const pattern of input3) {
16350
16055
  const result = braces.create(pattern, options2);
16351
16056
  if (Array.isArray(result)) {
16352
16057
  output.push(...result);
@@ -16355,31 +16060,31 @@ var require_braces = __commonJS((exports, module) => {
16355
16060
  }
16356
16061
  }
16357
16062
  } else {
16358
- output = [].concat(braces.create(input4, options2));
16063
+ output = [].concat(braces.create(input3, options2));
16359
16064
  }
16360
16065
  if (options2 && options2.expand === true && options2.nodupes === true) {
16361
16066
  output = [...new Set(output)];
16362
16067
  }
16363
16068
  return output;
16364
16069
  };
16365
- braces.parse = (input4, options2 = {}) => parse2(input4, options2);
16366
- braces.stringify = (input4, options2 = {}) => {
16367
- if (typeof input4 === "string") {
16368
- return stringify2(braces.parse(input4, options2), options2);
16070
+ braces.parse = (input3, options2 = {}) => parse2(input3, options2);
16071
+ braces.stringify = (input3, options2 = {}) => {
16072
+ if (typeof input3 === "string") {
16073
+ return stringify2(braces.parse(input3, options2), options2);
16369
16074
  }
16370
- return stringify2(input4, options2);
16075
+ return stringify2(input3, options2);
16371
16076
  };
16372
- braces.compile = (input4, options2 = {}) => {
16373
- if (typeof input4 === "string") {
16374
- input4 = braces.parse(input4, options2);
16077
+ braces.compile = (input3, options2 = {}) => {
16078
+ if (typeof input3 === "string") {
16079
+ input3 = braces.parse(input3, options2);
16375
16080
  }
16376
- return compile(input4, options2);
16081
+ return compile(input3, options2);
16377
16082
  };
16378
- braces.expand = (input4, options2 = {}) => {
16379
- if (typeof input4 === "string") {
16380
- input4 = braces.parse(input4, options2);
16083
+ braces.expand = (input3, options2 = {}) => {
16084
+ if (typeof input3 === "string") {
16085
+ input3 = braces.parse(input3, options2);
16381
16086
  }
16382
- let result = expand(input4, options2);
16087
+ let result = expand(input3, options2);
16383
16088
  if (options2.noempty === true) {
16384
16089
  result = result.filter(Boolean);
16385
16090
  }
@@ -16388,11 +16093,11 @@ var require_braces = __commonJS((exports, module) => {
16388
16093
  }
16389
16094
  return result;
16390
16095
  };
16391
- braces.create = (input4, options2 = {}) => {
16392
- if (input4 === "" || input4.length < 3) {
16393
- return [input4];
16096
+ braces.create = (input3, options2 = {}) => {
16097
+ if (input3 === "" || input3.length < 3) {
16098
+ return [input3];
16394
16099
  }
16395
- return options2.expand !== true ? braces.compile(input4, options2) : braces.expand(input4, options2);
16100
+ return options2.expand !== true ? braces.compile(input3, options2) : braces.expand(input3, options2);
16396
16101
  };
16397
16102
  module.exports = braces;
16398
16103
  });
@@ -16570,26 +16275,26 @@ var require_utils2 = __commonJS((exports) => {
16570
16275
  }
16571
16276
  return win32 === true || path.sep === "\\";
16572
16277
  };
16573
- exports.escapeLast = (input4, char, lastIdx) => {
16574
- const idx = input4.lastIndexOf(char, lastIdx);
16278
+ exports.escapeLast = (input3, char, lastIdx) => {
16279
+ const idx = input3.lastIndexOf(char, lastIdx);
16575
16280
  if (idx === -1)
16576
- return input4;
16577
- if (input4[idx - 1] === "\\")
16578
- return exports.escapeLast(input4, char, idx - 1);
16579
- return `${input4.slice(0, idx)}\\${input4.slice(idx)}`;
16281
+ return input3;
16282
+ if (input3[idx - 1] === "\\")
16283
+ return exports.escapeLast(input3, char, idx - 1);
16284
+ return `${input3.slice(0, idx)}\\${input3.slice(idx)}`;
16580
16285
  };
16581
- exports.removePrefix = (input4, state = {}) => {
16582
- let output = input4;
16286
+ exports.removePrefix = (input3, state = {}) => {
16287
+ let output = input3;
16583
16288
  if (output.startsWith("./")) {
16584
16289
  output = output.slice(2);
16585
16290
  state.prefix = "./";
16586
16291
  }
16587
16292
  return output;
16588
16293
  };
16589
- exports.wrapOutput = (input4, state = {}, options2 = {}) => {
16294
+ exports.wrapOutput = (input3, state = {}, options2 = {}) => {
16590
16295
  const prepend = options2.contains ? "" : "^";
16591
16296
  const append = options2.contains ? "" : "$";
16592
- let output = `${prepend}(?:${input4})${append}`;
16297
+ let output = `${prepend}(?:${input3})${append}`;
16593
16298
  if (state.negated === true) {
16594
16299
  output = `(?:^(?!${output}).*$)`;
16595
16300
  }
@@ -16625,14 +16330,14 @@ var require_scan = __commonJS((exports, module) => {
16625
16330
  token.depth = token.isGlobstar ? Infinity : 1;
16626
16331
  }
16627
16332
  };
16628
- var scan = (input4, options2) => {
16333
+ var scan = (input3, options2) => {
16629
16334
  const opts = options2 || {};
16630
- const length = input4.length - 1;
16335
+ const length = input3.length - 1;
16631
16336
  const scanToEnd = opts.parts === true || opts.scanToEnd === true;
16632
16337
  const slashes = [];
16633
16338
  const tokens = [];
16634
16339
  const parts = [];
16635
- let str = input4;
16340
+ let str = input3;
16636
16341
  let index = -1;
16637
16342
  let start = 0;
16638
16343
  let lastIndex = 0;
@@ -16855,7 +16560,7 @@ var require_scan = __commonJS((exports, module) => {
16855
16560
  }
16856
16561
  const state = {
16857
16562
  prefix,
16858
- input: input4,
16563
+ input: input3,
16859
16564
  start,
16860
16565
  base,
16861
16566
  glob,
@@ -16879,7 +16584,7 @@ var require_scan = __commonJS((exports, module) => {
16879
16584
  for (let idx = 0;idx < slashes.length; idx++) {
16880
16585
  const n = prevIndex ? prevIndex + 1 : start;
16881
16586
  const i = slashes[idx];
16882
- const value = input4.slice(n, i);
16587
+ const value = input3.slice(n, i);
16883
16588
  if (opts.tokens) {
16884
16589
  if (idx === 0 && start !== 0) {
16885
16590
  tokens[idx].isPrefix = true;
@@ -16895,8 +16600,8 @@ var require_scan = __commonJS((exports, module) => {
16895
16600
  }
16896
16601
  prevIndex = i;
16897
16602
  }
16898
- if (prevIndex && prevIndex + 1 < input4.length) {
16899
- const value = input4.slice(prevIndex + 1);
16603
+ if (prevIndex && prevIndex + 1 < input3.length) {
16604
+ const value = input3.slice(prevIndex + 1);
16900
16605
  parts.push(value);
16901
16606
  if (opts.tokens) {
16902
16607
  tokens[tokens.length - 1].value = value;
@@ -16939,14 +16644,14 @@ var require_parse2 = __commonJS((exports, module) => {
16939
16644
  var syntaxError = (type, char) => {
16940
16645
  return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
16941
16646
  };
16942
- var parse2 = (input4, options2) => {
16943
- if (typeof input4 !== "string") {
16647
+ var parse2 = (input3, options2) => {
16648
+ if (typeof input3 !== "string") {
16944
16649
  throw new TypeError("Expected a string");
16945
16650
  }
16946
- input4 = REPLACEMENTS[input4] || input4;
16651
+ input3 = REPLACEMENTS[input3] || input3;
16947
16652
  const opts = { ...options2 };
16948
16653
  const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
16949
- let len = input4.length;
16654
+ let len = input3.length;
16950
16655
  if (len > max) {
16951
16656
  throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
16952
16657
  }
@@ -16983,7 +16688,7 @@ var require_parse2 = __commonJS((exports, module) => {
16983
16688
  opts.noextglob = opts.noext;
16984
16689
  }
16985
16690
  const state = {
16986
- input: input4,
16691
+ input: input3,
16987
16692
  index: -1,
16988
16693
  start: 0,
16989
16694
  dot: opts.dot === true,
@@ -16999,17 +16704,17 @@ var require_parse2 = __commonJS((exports, module) => {
16999
16704
  globstar: false,
17000
16705
  tokens
17001
16706
  };
17002
- input4 = utils.removePrefix(input4, state);
17003
- len = input4.length;
16707
+ input3 = utils.removePrefix(input3, state);
16708
+ len = input3.length;
17004
16709
  const extglobs = [];
17005
16710
  const braces = [];
17006
16711
  const stack = [];
17007
16712
  let prev = bos;
17008
16713
  let value;
17009
16714
  const eos = () => state.index === len - 1;
17010
- const peek = state.peek = (n = 1) => input4[state.index + n];
17011
- const advance = state.advance = () => input4[++state.index] || "";
17012
- const remaining = () => input4.slice(state.index + 1);
16715
+ const peek = state.peek = (n = 1) => input3[state.index + n];
16716
+ const advance = state.advance = () => input3[++state.index] || "";
16717
+ const remaining = () => input3.slice(state.index + 1);
17013
16718
  const consume = (value2 = "", num = 0) => {
17014
16719
  state.consumed += value2;
17015
16720
  state.index += num;
@@ -17099,9 +16804,9 @@ var require_parse2 = __commonJS((exports, module) => {
17099
16804
  push({ type: "paren", extglob: true, value, output });
17100
16805
  decrement("parens");
17101
16806
  };
17102
- if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input4)) {
16807
+ if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input3)) {
17103
16808
  let backslashes = false;
17104
- let output = input4.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
16809
+ let output = input3.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
17105
16810
  if (first === "\\") {
17106
16811
  backslashes = true;
17107
16812
  return m;
@@ -17135,8 +16840,8 @@ var require_parse2 = __commonJS((exports, module) => {
17135
16840
  });
17136
16841
  }
17137
16842
  }
17138
- if (output === input4 && opts.contains === true) {
17139
- state.output = input4;
16843
+ if (output === input3 && opts.contains === true) {
16844
+ state.output = input3;
17140
16845
  return state;
17141
16846
  }
17142
16847
  state.output = utils.wrapOutput(output, state, options2);
@@ -17495,7 +17200,7 @@ var require_parse2 = __commonJS((exports, module) => {
17495
17200
  continue;
17496
17201
  }
17497
17202
  while (rest.slice(0, 3) === "/**") {
17498
- const after = input4[state.index + 4];
17203
+ const after = input3[state.index + 4];
17499
17204
  if (after && after !== "/") {
17500
17205
  break;
17501
17206
  }
@@ -17618,14 +17323,14 @@ var require_parse2 = __commonJS((exports, module) => {
17618
17323
  }
17619
17324
  return state;
17620
17325
  };
17621
- parse2.fastpaths = (input4, options2) => {
17326
+ parse2.fastpaths = (input3, options2) => {
17622
17327
  const opts = { ...options2 };
17623
17328
  const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
17624
- const len = input4.length;
17329
+ const len = input3.length;
17625
17330
  if (len > max) {
17626
17331
  throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
17627
17332
  }
17628
- input4 = REPLACEMENTS[input4] || input4;
17333
+ input3 = REPLACEMENTS[input3] || input3;
17629
17334
  const win32 = utils.isWindows(options2);
17630
17335
  const {
17631
17336
  DOT_LITERAL,
@@ -17680,7 +17385,7 @@ var require_parse2 = __commonJS((exports, module) => {
17680
17385
  }
17681
17386
  }
17682
17387
  };
17683
- const output = utils.removePrefix(input4, state);
17388
+ const output = utils.removePrefix(input3, state);
17684
17389
  let source = create2(output);
17685
17390
  if (source && opts.strictSlashes !== true) {
17686
17391
  source += `${SLASH_LITERAL}?`;
@@ -17700,7 +17405,7 @@ var require_picomatch = __commonJS((exports, module) => {
17700
17405
  var isObject = (val) => val && typeof val === "object" && !Array.isArray(val);
17701
17406
  var picomatch = (glob, options2, returnState = false) => {
17702
17407
  if (Array.isArray(glob)) {
17703
- const fns = glob.map((input4) => picomatch(input4, options2, returnState));
17408
+ const fns = glob.map((input3) => picomatch(input3, options2, returnState));
17704
17409
  const arrayMatcher = (str) => {
17705
17410
  for (const isMatch of fns) {
17706
17411
  const state2 = isMatch(str);
@@ -17725,9 +17430,9 @@ var require_picomatch = __commonJS((exports, module) => {
17725
17430
  const ignoreOpts = { ...options2, ignore: null, onMatch: null, onResult: null };
17726
17431
  isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
17727
17432
  }
17728
- const matcher = (input4, returnObject = false) => {
17729
- const { isMatch, match, output } = picomatch.test(input4, regex, options2, { glob, posix });
17730
- const result = { glob, state, regex, posix, input: input4, output, match, isMatch };
17433
+ const matcher = (input3, returnObject = false) => {
17434
+ const { isMatch, match, output } = picomatch.test(input3, regex, options2, { glob, posix });
17435
+ const result = { glob, state, regex, posix, input: input3, output, match, isMatch };
17731
17436
  if (typeof opts.onResult === "function") {
17732
17437
  opts.onResult(result);
17733
17438
  }
@@ -17735,7 +17440,7 @@ var require_picomatch = __commonJS((exports, module) => {
17735
17440
  result.isMatch = false;
17736
17441
  return returnObject ? result : false;
17737
17442
  }
17738
- if (isIgnored(input4)) {
17443
+ if (isIgnored(input3)) {
17739
17444
  if (typeof opts.onIgnore === "function") {
17740
17445
  opts.onIgnore(result);
17741
17446
  }
@@ -17752,33 +17457,33 @@ var require_picomatch = __commonJS((exports, module) => {
17752
17457
  }
17753
17458
  return matcher;
17754
17459
  };
17755
- picomatch.test = (input4, regex, options2, { glob, posix } = {}) => {
17756
- if (typeof input4 !== "string") {
17460
+ picomatch.test = (input3, regex, options2, { glob, posix } = {}) => {
17461
+ if (typeof input3 !== "string") {
17757
17462
  throw new TypeError("Expected input to be a string");
17758
17463
  }
17759
- if (input4 === "") {
17464
+ if (input3 === "") {
17760
17465
  return { isMatch: false, output: "" };
17761
17466
  }
17762
17467
  const opts = options2 || {};
17763
17468
  const format = opts.format || (posix ? utils.toPosixSlashes : null);
17764
- let match = input4 === glob;
17765
- let output = match && format ? format(input4) : input4;
17469
+ let match = input3 === glob;
17470
+ let output = match && format ? format(input3) : input3;
17766
17471
  if (match === false) {
17767
- output = format ? format(input4) : input4;
17472
+ output = format ? format(input3) : input3;
17768
17473
  match = output === glob;
17769
17474
  }
17770
17475
  if (match === false || opts.capture === true) {
17771
17476
  if (opts.matchBase === true || opts.basename === true) {
17772
- match = picomatch.matchBase(input4, regex, options2, posix);
17477
+ match = picomatch.matchBase(input3, regex, options2, posix);
17773
17478
  } else {
17774
17479
  match = regex.exec(output);
17775
17480
  }
17776
17481
  }
17777
17482
  return { isMatch: Boolean(match), match, output };
17778
17483
  };
17779
- picomatch.matchBase = (input4, glob, options2, posix = utils.isWindows(options2)) => {
17484
+ picomatch.matchBase = (input3, glob, options2, posix = utils.isWindows(options2)) => {
17780
17485
  const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options2);
17781
- return regex.test(path.basename(input4));
17486
+ return regex.test(path.basename(input3));
17782
17487
  };
17783
17488
  picomatch.isMatch = (str, patterns, options2) => picomatch(patterns, options2)(str);
17784
17489
  picomatch.parse = (pattern, options2) => {
@@ -17786,7 +17491,7 @@ var require_picomatch = __commonJS((exports, module) => {
17786
17491
  return pattern.map((p) => picomatch.parse(p, options2));
17787
17492
  return parse2(pattern, { ...options2, fastpaths: false });
17788
17493
  };
17789
- picomatch.scan = (input4, options2) => scan(input4, options2);
17494
+ picomatch.scan = (input3, options2) => scan(input3, options2);
17790
17495
  picomatch.compileRe = (state, options2, returnOutput = false, returnState = false) => {
17791
17496
  if (returnOutput === true) {
17792
17497
  return state.output;
@@ -17804,16 +17509,16 @@ var require_picomatch = __commonJS((exports, module) => {
17804
17509
  }
17805
17510
  return regex;
17806
17511
  };
17807
- picomatch.makeRe = (input4, options2 = {}, returnOutput = false, returnState = false) => {
17808
- if (!input4 || typeof input4 !== "string") {
17512
+ picomatch.makeRe = (input3, options2 = {}, returnOutput = false, returnState = false) => {
17513
+ if (!input3 || typeof input3 !== "string") {
17809
17514
  throw new TypeError("Expected a non-empty string");
17810
17515
  }
17811
17516
  let parsed = { negated: false, fastpaths: true };
17812
- if (options2.fastpaths !== false && (input4[0] === "." || input4[0] === "*")) {
17813
- parsed.output = parse2.fastpaths(input4, options2);
17517
+ if (options2.fastpaths !== false && (input3[0] === "." || input3[0] === "*")) {
17518
+ parsed.output = parse2.fastpaths(input3, options2);
17814
17519
  }
17815
17520
  if (!parsed.output) {
17816
- parsed = parse2(input4, options2);
17521
+ parsed = parse2(input3, options2);
17817
17522
  }
17818
17523
  return picomatch.compileRe(parsed, options2, returnOutput, returnState);
17819
17524
  };
@@ -17959,10 +17664,10 @@ var require_micromatch = __commonJS((exports, module) => {
17959
17664
  }
17960
17665
  return [].concat(patterns).every((p) => picomatch(p, options2)(str));
17961
17666
  };
17962
- micromatch.capture = (glob, input4, options2) => {
17667
+ micromatch.capture = (glob, input3, options2) => {
17963
17668
  let posix = utils.isWindows(options2);
17964
17669
  let regex = picomatch.makeRe(String(glob), { ...options2, capture: true });
17965
- let match = regex.exec(posix ? utils.toPosixSlashes(input4) : input4);
17670
+ let match = regex.exec(posix ? utils.toPosixSlashes(input3) : input3);
17966
17671
  if (match) {
17967
17672
  return match.slice(1).map((v) => v === undefined ? "" : v);
17968
17673
  }
@@ -18297,12 +18002,12 @@ var require_stream = __commonJS((exports) => {
18297
18002
  var require_string = __commonJS((exports) => {
18298
18003
  Object.defineProperty(exports, "__esModule", { value: true });
18299
18004
  exports.isEmpty = exports.isString = undefined;
18300
- function isString(input4) {
18301
- return typeof input4 === "string";
18005
+ function isString(input3) {
18006
+ return typeof input3 === "string";
18302
18007
  }
18303
18008
  exports.isString = isString;
18304
- function isEmpty(input4) {
18305
- return input4 === "";
18009
+ function isEmpty(input3) {
18010
+ return input3 === "";
18306
18011
  }
18307
18012
  exports.isEmpty = isEmpty;
18308
18013
  });
@@ -18332,8 +18037,8 @@ var require_tasks = __commonJS((exports) => {
18332
18037
  Object.defineProperty(exports, "__esModule", { value: true });
18333
18038
  exports.convertPatternGroupToTask = exports.convertPatternGroupsToTasks = exports.groupPatternsByBaseDirectory = exports.getNegativePatternsAsPositive = exports.getPositivePatterns = exports.convertPatternsToTasks = exports.generate = undefined;
18334
18039
  var utils = require_utils3();
18335
- function generate(input4, settings) {
18336
- const patterns = processPatterns(input4, settings);
18040
+ function generate(input3, settings) {
18041
+ const patterns = processPatterns(input3, settings);
18337
18042
  const ignore = processPatterns(settings.ignore, settings);
18338
18043
  const positivePatterns = getPositivePatterns(patterns);
18339
18044
  const negativePatterns = getNegativePatternsAsPositive(patterns, ignore);
@@ -18344,8 +18049,8 @@ var require_tasks = __commonJS((exports) => {
18344
18049
  return staticTasks.concat(dynamicTasks);
18345
18050
  }
18346
18051
  exports.generate = generate;
18347
- function processPatterns(input4, settings) {
18348
- let patterns = input4;
18052
+ function processPatterns(input3, settings) {
18053
+ let patterns = input3;
18349
18054
  if (settings.braceExpansion) {
18350
18055
  patterns = utils.pattern.expandPatternsWithBraceExpansion(patterns);
18351
18056
  }
@@ -20301,8 +20006,8 @@ var require_out4 = __commonJS((exports, module) => {
20301
20006
  const provider = new _Provider(settings);
20302
20007
  return tasks.map(provider.read, provider);
20303
20008
  }
20304
- function assertPatternsInput(input4) {
20305
- const source = [].concat(input4);
20009
+ function assertPatternsInput(input3) {
20010
+ const source = [].concat(input3);
20306
20011
  const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item));
20307
20012
  if (!isValidSource) {
20308
20013
  throw new TypeError("Patterns must be a string (non empty) or an array of strings");
@@ -22148,7 +21853,7 @@ var init_commands = __esm(() => {
22148
21853
  });
22149
21854
 
22150
21855
  // ../../node_modules/@antfu/ni/dist/shared/ni.B5qNAuoI.mjs
22151
- import path3, { join as join7, dirname as dirname6, resolve as resolve8 } from "node:path";
21856
+ import path3, { join as join5, dirname as dirname6, resolve as resolve8 } from "node:path";
22152
21857
  import process$1 from "node:process";
22153
21858
  import require$$0 from "readline";
22154
21859
  import require$$2 from "events";
@@ -22670,10 +22375,10 @@ function requireStyle() {
22670
22375
  const c2 = requireKleur();
22671
22376
  const figures = requireFigures();
22672
22377
  const styles3 = Object.freeze({
22673
- password: { scale: 1, render: (input4) => "*".repeat(input4.length) },
22674
- emoji: { scale: 2, render: (input4) => "\uD83D\uDE03".repeat(input4.length) },
22675
- invisible: { scale: 0, render: (input4) => "" },
22676
- default: { scale: 1, render: (input4) => `${input4}` }
22378
+ password: { scale: 1, render: (input3) => "*".repeat(input3.length) },
22379
+ emoji: { scale: 2, render: (input3) => "\uD83D\uDE03".repeat(input3.length) },
22380
+ invisible: { scale: 0, render: (input3) => "" },
22381
+ default: { scale: 1, render: (input3) => `${input3}` }
22677
22382
  });
22678
22383
  const render = (type) => styles3[type] || styles3.default;
22679
22384
  const symbols = Object.freeze({
@@ -23013,7 +22718,7 @@ ${i2 ? " " : figures.pointerSmall} ${color.red().italic(l2)}`, ``);
23013
22718
  }
23014
22719
  function requireSelect() {
23015
22720
  if (hasRequiredSelect)
23016
- return select4;
22721
+ return select3;
23017
22722
  hasRequiredSelect = 1;
23018
22723
  const color = requireKleur();
23019
22724
  const Prompt = requirePrompt();
@@ -23159,8 +22864,8 @@ function requireSelect() {
23159
22864
  this.out.write(this.outputText);
23160
22865
  }
23161
22866
  }
23162
- select4 = SelectPrompt;
23163
- return select4;
22867
+ select3 = SelectPrompt;
22868
+ return select3;
23164
22869
  }
23165
22870
  function requireToggle() {
23166
22871
  if (hasRequiredToggle)
@@ -24532,7 +24237,7 @@ Filtered results for: ${this.inputValue ? this.inputValue : color.gray("Enter so
24532
24237
  }
24533
24238
  function requireConfirm() {
24534
24239
  if (hasRequiredConfirm)
24535
- return confirm8;
24240
+ return confirm5;
24536
24241
  hasRequiredConfirm = 1;
24537
24242
  const color = requireKleur();
24538
24243
  const Prompt = requirePrompt();
@@ -24605,8 +24310,8 @@ function requireConfirm() {
24605
24310
  this.out.write(erase.line + cursor.to(0) + this.outputText);
24606
24311
  }
24607
24312
  }
24608
- confirm8 = ConfirmPrompt;
24609
- return confirm8;
24313
+ confirm5 = ConfirmPrompt;
24314
+ return confirm5;
24610
24315
  }
24611
24316
  function requireElements() {
24612
24317
  if (hasRequiredElements)
@@ -24681,7 +24386,7 @@ function requirePrompts$1() {
24681
24386
  onSubmit: toSelected
24682
24387
  });
24683
24388
  };
24684
- const byTitle = (input4, choices) => Promise.resolve(choices.filter((item) => item.title.slice(0, input4.length).toLowerCase() === input4.toLowerCase()));
24389
+ const byTitle = (input3, choices) => Promise.resolve(choices.filter((item) => item.title.slice(0, input3.length).toLowerCase() === input3.toLowerCase()));
24685
24390
  $.autocomplete = (args) => {
24686
24391
  args.suggest = args.suggest || byTitle;
24687
24392
  args.choices = [].concat(args.choices || []);
@@ -25163,7 +24868,7 @@ function requireLib() {
25163
24868
  return lib;
25164
24869
  hasRequiredLib = 1;
25165
24870
  const { isexe, sync: isexeSync } = requireCjs();
25166
- const { join: join8, delimiter, sep, posix: posix2 } = require$$1$2;
24871
+ const { join: join6, delimiter, sep, posix: posix2 } = require$$1$2;
25167
24872
  const isWindows = process.platform === "win32";
25168
24873
  const rSlash = new RegExp(`[${posix2.sep}${sep === posix2.sep ? "" : sep}]`.replace(/(\\)/g, "\\$1"));
25169
24874
  const rRel = new RegExp(`^\\.${rSlash.source}`);
@@ -25190,7 +24895,7 @@ function requireLib() {
25190
24895
  const getPathPart = (raw, cmd) => {
25191
24896
  const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
25192
24897
  const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
25193
- return prefix + join8(pathPart, cmd);
24898
+ return prefix + join6(pathPart, cmd);
25194
24899
  };
25195
24900
  const which = async (cmd, opt = {}) => {
25196
24901
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
@@ -25286,7 +24991,7 @@ async function detect2({ autoInstall, programmatic, cwd } = {}) {
25286
24991
  }
25287
24992
  return agent;
25288
24993
  }
25289
- 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, confirm8, hasRequiredConfirm, elements, hasRequiredElements, hasRequiredPrompts$1, lib$1, hasRequiredLib$1, prompts$1, hasRequiredPrompts, promptsExports, prompts, isBrowser, platform, OSC = "\x1B]", BEL = "\x07", SEP = ";", link = (text2, url) => [
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) => [
25290
24995
  OSC,
25291
24996
  "8",
25292
24997
  SEP,
@@ -25339,7 +25044,7 @@ var init_ni_B5qNAuoI = __esm(() => {
25339
25044
  options2 = {};
25340
25045
  libExports = requireLib();
25341
25046
  which = /* @__PURE__ */ getDefaultExportFromCjs(libExports);
25342
- CLI_TEMP_DIR = join7(os4.tmpdir(), "antfu-ni");
25047
+ CLI_TEMP_DIR = join5(os4.tmpdir(), "antfu-ni");
25343
25048
  customRcPath = process$1.env.NI_CONFIG_FILE;
25344
25049
  home = process$1.platform === "win32" ? process$1.env.USERPROFILE : process$1.env.HOME;
25345
25050
  defaultRcPath = path3.join(home || "~/", ".nirc");
@@ -25970,12 +25675,12 @@ var init_figures = __esm(() => {
25970
25675
  import tty2 from "node:tty";
25971
25676
  var hasColors, format = (open, close) => {
25972
25677
  if (!hasColors) {
25973
- return (input4) => input4;
25678
+ return (input3) => input3;
25974
25679
  }
25975
25680
  const openCode = `\x1B[${open}m`;
25976
25681
  const closeCode = `\x1B[${close}m`;
25977
- return (input4) => {
25978
- const string = input4 + "";
25682
+ return (input3) => {
25683
+ const string = input3 + "";
25979
25684
  let index = string.indexOf(closeCode);
25980
25685
  if (index === -1) {
25981
25686
  return openCode + string + closeCode;
@@ -28084,16 +27789,16 @@ var init_options2 = __esm(() => {
28084
27789
  var concatenateShell = (file, commandArguments, options3) => options3.shell && commandArguments.length > 0 ? [[file, ...commandArguments].join(" "), [], options3] : [file, commandArguments, options3];
28085
27790
 
28086
27791
  // ../../node_modules/strip-final-newline/index.js
28087
- function stripFinalNewline(input4) {
28088
- if (typeof input4 === "string") {
28089
- return stripFinalNewlineString(input4);
27792
+ function stripFinalNewline(input3) {
27793
+ if (typeof input3 === "string") {
27794
+ return stripFinalNewlineString(input3);
28090
27795
  }
28091
- if (!(ArrayBuffer.isView(input4) && input4.BYTES_PER_ELEMENT === 1)) {
27796
+ if (!(ArrayBuffer.isView(input3) && input3.BYTES_PER_ELEMENT === 1)) {
28092
27797
  throw new Error("Input must be a string or a Uint8Array");
28093
27798
  }
28094
- return stripFinalNewlineBinary(input4);
27799
+ return stripFinalNewlineBinary(input3);
28095
27800
  }
28096
- 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 = `
27801
+ var stripFinalNewlineString = (input3) => input3.at(-1) === LF ? input3.slice(0, input3.at(-2) === CR ? -2 : -1) : input3, stripFinalNewlineBinary = (input3) => input3.at(-1) === LF_BINARY ? input3.subarray(0, input3.at(-2) === CR_BINARY ? -2 : -1) : input3, LF = `
28097
27802
  `, LF_BINARY, CR = "\r", CR_BINARY;
28098
27803
  var init_strip_final_newline = __esm(() => {
28099
27804
  LF_BINARY = LF.codePointAt(0);
@@ -29132,21 +28837,21 @@ var init_native = __esm(() => {
29132
28837
  });
29133
28838
 
29134
28839
  // ../../node_modules/execa/lib/stdio/input-option.js
29135
- var handleInputOptions = ({ input: input4, inputFile }, fdNumber) => fdNumber === 0 ? [
29136
- ...handleInputOption(input4),
28840
+ var handleInputOptions = ({ input: input3, inputFile }, fdNumber) => fdNumber === 0 ? [
28841
+ ...handleInputOption(input3),
29137
28842
  ...handleInputFileOption(inputFile)
29138
- ] : [], handleInputOption = (input4) => input4 === undefined ? [] : [{
29139
- type: getInputType(input4),
29140
- value: input4,
28843
+ ] : [], handleInputOption = (input3) => input3 === undefined ? [] : [{
28844
+ type: getInputType(input3),
28845
+ value: input3,
29141
28846
  optionName: "input"
29142
- }], getInputType = (input4) => {
29143
- if (isReadableStream(input4, { checkOpen: false })) {
28847
+ }], getInputType = (input3) => {
28848
+ if (isReadableStream(input3, { checkOpen: false })) {
29144
28849
  return "nodeStream";
29145
28850
  }
29146
- if (typeof input4 === "string") {
28851
+ if (typeof input3 === "string") {
29147
28852
  return "string";
29148
28853
  }
29149
- if (isUint8Array(input4)) {
28854
+ if (isUint8Array(input3)) {
29150
28855
  return "uint8Array";
29151
28856
  }
29152
28857
  throw new Error("The `input` option must be a string, a Uint8Array or a Node.js Readable stream.");
@@ -32262,7 +31967,7 @@ var init_command2 = __esm(() => {
32262
31967
  var setScriptSync = (boundExeca, createNested, boundOptions) => {
32263
31968
  boundExeca.sync = createNested(mapScriptSync, boundOptions);
32264
31969
  boundExeca.s = boundExeca.sync;
32265
- }, 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;
31970
+ }, mapScriptAsync = ({ options: options3 }) => getScriptOptions(options3), mapScriptSync = ({ options: options3 }) => ({ ...getScriptOptions(options3), isSync: true }), getScriptOptions = (options3) => ({ options: { ...getScriptStdinOption(options3), ...options3 } }), getScriptStdinOption = ({ input: input3, inputFile, stdio }) => input3 === undefined && inputFile === undefined && stdio === undefined ? { stdin: "inherit" } : {}, deepScriptOptions;
32266
31971
  var init_script = __esm(() => {
32267
31972
  deepScriptOptions = { preferLocal: true };
32268
31973
  });
@@ -32373,20 +32078,20 @@ __export(exports_generate, {
32373
32078
  import path10 from "path";
32374
32079
  import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
32375
32080
  import { toCamelCase as toCamelCase8 } from "@secondlayer/stacks/clarity";
32376
- function isContractAddress(input4) {
32081
+ function isContractAddress(input3) {
32377
32082
  const contractIdPattern = /^(SP|ST|SM|SN)[A-Z0-9]{38,}\.[a-zA-Z][a-zA-Z0-9-]*$/;
32378
- return contractIdPattern.test(input4);
32083
+ return contractIdPattern.test(input3);
32379
32084
  }
32380
32085
  async function parseInputs(inputs) {
32381
32086
  const files = [];
32382
32087
  const contractIds = [];
32383
- for (const input4 of inputs) {
32384
- if (isContractAddress(input4)) {
32385
- contractIds.push(input4);
32088
+ for (const input3 of inputs) {
32089
+ if (isContractAddress(input3)) {
32090
+ contractIds.push(input3);
32386
32091
  continue;
32387
32092
  }
32388
- if (input4.includes("*") || input4.includes("?")) {
32389
- const matches = await import_fast_glob.default(input4, { cwd: process.cwd(), absolute: true });
32093
+ if (input3.includes("*") || input3.includes("?")) {
32094
+ const matches = await import_fast_glob.default(input3, { cwd: process.cwd(), absolute: true });
32390
32095
  for (const file of matches) {
32391
32096
  if (file.endsWith(".clar")) {
32392
32097
  files.push(file);
@@ -32394,8 +32099,8 @@ async function parseInputs(inputs) {
32394
32099
  }
32395
32100
  continue;
32396
32101
  }
32397
- if (input4.endsWith(".clar")) {
32398
- const absolutePath = path10.resolve(process.cwd(), input4);
32102
+ if (input3.endsWith(".clar")) {
32103
+ const absolutePath = path10.resolve(process.cwd(), input3);
32399
32104
  files.push(absolutePath);
32400
32105
  }
32401
32106
  }
@@ -32678,8 +32383,8 @@ var {
32678
32383
  // package.json
32679
32384
  var package_default = {
32680
32385
  name: "@secondlayer/cli",
32681
- version: "1.12.2",
32682
- description: "CLI for streams, subgraphs, and real-time blockchain indexing on Stacks",
32386
+ version: "2.1.0",
32387
+ description: "CLI for subgraphs and blockchain indexing on Stacks",
32683
32388
  type: "module",
32684
32389
  bin: {
32685
32390
  secondlayer: "./dist/cli.js",
@@ -32719,11 +32424,12 @@ var package_default = {
32719
32424
  license: "MIT",
32720
32425
  dependencies: {
32721
32426
  "@inquirer/prompts": "^8.2.0",
32722
- "@secondlayer/sdk": "^0.10.2",
32723
- "@secondlayer/shared": "^0.12.0",
32427
+ "@secondlayer/bundler": "^0.2.0",
32428
+ "@secondlayer/sdk": "^1.0.0",
32429
+ "@secondlayer/shared": "^1.0.0",
32724
32430
  "@secondlayer/stacks": "^0.2.2",
32725
- "@secondlayer/subgraphs": "^0.11.0",
32726
- "@secondlayer/workflows": "^0.0.3",
32431
+ "@secondlayer/subgraphs": "^0.11.6",
32432
+ "@secondlayer/workflows": "^1.0.1",
32727
32433
  "@biomejs/js-api": "^0.7.0",
32728
32434
  "@biomejs/wasm-nodejs": "^1.9.0",
32729
32435
  esbuild: "^0.19.0",
@@ -32749,46 +32455,42 @@ init_api_client();
32749
32455
  init_output();
32750
32456
  function registerAccountCommand(program2) {
32751
32457
  const account = program2.command("account").description("Manage your account profile");
32752
- account.command("profile").description("View or update your public profile").option("--name <name>", "Set display name").option("--bio <bio>", "Set bio").option("--slug <slug>", "Set public URL slug").option("--json", "Output as JSON").action(async (options) => {
32753
- try {
32754
- const hasUpdates = options.name || options.bio || options.slug;
32755
- if (hasUpdates) {
32756
- const data = {};
32757
- if (options.name)
32758
- data.display_name = options.name;
32759
- if (options.bio)
32760
- data.bio = options.bio;
32761
- if (options.slug)
32762
- data.slug = options.slug;
32763
- const updated = await updateAccountProfile(data);
32764
- if (options.json) {
32765
- console.log(JSON.stringify(updated, null, 2));
32766
- return;
32767
- }
32768
- success("Profile updated");
32769
- console.log(formatKeyValue([
32770
- ["Display Name", updated.displayName ?? dim("—")],
32771
- ["Bio", updated.bio ?? dim("—")],
32772
- ["Slug", updated.slug ?? dim("—")]
32773
- ]));
32774
- return;
32775
- }
32776
- const profile = await getAccountProfile();
32458
+ account.command("profile").description("View or update your public profile").option("--name <name>", "Set display name").option("--bio <bio>", "Set bio").option("--slug <slug>", "Set public URL slug").option("--json", "Output as JSON").action(withErrorHandling(async (options) => {
32459
+ const hasUpdates = options.name || options.bio || options.slug;
32460
+ if (hasUpdates) {
32461
+ const data = {};
32462
+ if (options.name)
32463
+ data.display_name = options.name;
32464
+ if (options.bio)
32465
+ data.bio = options.bio;
32466
+ if (options.slug)
32467
+ data.slug = options.slug;
32468
+ const updated = await updateAccountProfile(data);
32777
32469
  if (options.json) {
32778
- console.log(JSON.stringify(profile, null, 2));
32470
+ console.log(JSON.stringify(updated, null, 2));
32779
32471
  return;
32780
32472
  }
32473
+ success("Profile updated");
32781
32474
  console.log(formatKeyValue([
32782
- ["Email", profile.email],
32783
- ["Plan", profile.plan],
32784
- ["Display Name", profile.displayName ?? dim("—")],
32785
- ["Bio", profile.bio ?? dim("—")],
32786
- ["Slug", profile.slug ?? dim("—")]
32475
+ ["Display Name", updated.displayName ?? dim("—")],
32476
+ ["Bio", updated.bio ?? dim("—")],
32477
+ ["Slug", updated.slug ?? dim("—")]
32787
32478
  ]));
32788
- } catch (err) {
32789
- handleApiError(err, "manage profile");
32479
+ return;
32790
32480
  }
32791
- });
32481
+ const profile = await getAccountProfile();
32482
+ if (options.json) {
32483
+ console.log(JSON.stringify(profile, null, 2));
32484
+ return;
32485
+ }
32486
+ console.log(formatKeyValue([
32487
+ ["Email", profile.email],
32488
+ ["Plan", profile.plan],
32489
+ ["Display Name", profile.displayName ?? dim("—")],
32490
+ ["Bio", profile.bio ?? dim("—")],
32491
+ ["Slug", profile.slug ?? dim("—")]
32492
+ ]));
32493
+ }, { action: "manage profile" }));
32792
32494
  }
32793
32495
  // src/commands/config.ts
32794
32496
  init_config();
@@ -33117,7 +32819,6 @@ async function printConfigTree(cfg) {
33117
32819
  console.log(blue("ports:"));
33118
32820
  printValue(" api", cfg.ports.api, cfg.ports.api === defaults.ports.api, 2);
33119
32821
  printValue(" indexer", cfg.ports.indexer, cfg.ports.indexer === defaults.ports.indexer, 2);
33120
- printValue(" receiver", cfg.ports.receiver, cfg.ports.receiver === defaults.ports.receiver, 2);
33121
32822
  console.log("");
33122
32823
  console.log(blue("database:"));
33123
32824
  printValue(" type", cfg.database.type, cfg.database.type === "docker", 2);
@@ -33156,1113 +32857,6 @@ async function validateDatabaseConnection(url) {
33156
32857
  console.log(dim("The URL was saved but connection failed. Check your database settings."));
33157
32858
  }
33158
32859
  }
33159
- // src/commands/setup.ts
33160
- init_api_client();
33161
- init_config();
33162
- import { confirm, input, select as select2 } from "@inquirer/prompts";
33163
- init_output();
33164
- var STREAMS_DIR = "streams";
33165
- function registerSetupCommand(program2) {
33166
- program2.command("setup").description("Set up a streams project and configure settings").option("--detect-only", "Only detect existing Stacks nodes, don't initialize").option("-y, --yes", "Use defaults without prompts").option("--data-dir <path>", "Data directory path").option("--node-path <path>", "Path to Stacks node").option("--network <network>", "Network (local, testnet, or mainnet)").option("--endpoint-url <url>", "Default endpoint URL for new streams").action(async (options) => {
33167
- try {
33168
- if (options.detectOnly) {
33169
- await runDetection();
33170
- return;
33171
- }
33172
- const hasFlags = options.yes || options.dataDir || options.nodePath || options.network || options.endpointUrl;
33173
- if (hasFlags) {
33174
- await runNonInteractive(options);
33175
- return;
33176
- }
33177
- await runWizard();
33178
- } catch (err) {
33179
- if (err.name === "ExitPromptError") {
33180
- console.log(`
33181
- Setup cancelled.`);
33182
- process.exit(0);
33183
- }
33184
- error(`Failed to initialize: ${err}`);
33185
- process.exit(1);
33186
- }
33187
- });
33188
- }
33189
- async function runNonInteractive(options) {
33190
- const config = await loadConfig();
33191
- const network = options.network || config.network || "mainnet";
33192
- config.network = network;
33193
- if (network !== "local") {
33194
- await saveConfig(config);
33195
- const result = await hostedLogin(config);
33196
- if (!result)
33197
- process.exit(1);
33198
- return;
33199
- }
33200
- config.dataDir = options.dataDir || config.dataDir || "~/.secondlayer/data";
33201
- config.defaultEndpointUrl = options.endpointUrl || config.defaultEndpointUrl;
33202
- if (options.nodePath) {
33203
- config.node = {
33204
- installPath: options.nodePath,
33205
- network: options.network || "mainnet"
33206
- };
33207
- }
33208
- await saveConfig(config);
33209
- await Bun.$`mkdir -p ${STREAMS_DIR}`.quiet();
33210
- await Bun.write(`${STREAMS_DIR}/.gitkeep`, "");
33211
- printSummary(config);
33212
- }
33213
- function printBanner() {
33214
- console.log();
33215
- console.log(" ╔═══════════════════════════════════════╗");
33216
- console.log(" ║ SecondLayer CLI Setup ║");
33217
- console.log(" ╚═══════════════════════════════════════╝");
33218
- console.log();
33219
- }
33220
- async function runWizard() {
33221
- printBanner();
33222
- const config = await loadConfig();
33223
- const network = await select2({
33224
- message: "How do you want to use Stacks Streams?",
33225
- choices: [
33226
- {
33227
- name: "Hosted mainnet (recommended — zero setup)",
33228
- value: "mainnet"
33229
- },
33230
- { name: "Hosted testnet", value: "testnet" },
33231
- {
33232
- name: "Local development (run your own node + services)",
33233
- value: "local"
33234
- }
33235
- ]
33236
- });
33237
- config.network = network;
33238
- if (network !== "local") {
33239
- await saveConfig(config);
33240
- const result = await hostedLogin(config);
33241
- if (!result)
33242
- process.exit(1);
33243
- return;
33244
- }
33245
- const dataDir = await promptDataDir(config);
33246
- config.dataDir = dataDir;
33247
- const nodeConfig = await promptNodeSetup();
33248
- if (nodeConfig) {
33249
- config.node = nodeConfig;
33250
- }
33251
- const endpointUrl = await promptEndpointUrl(config);
33252
- config.defaultEndpointUrl = endpointUrl;
33253
- await saveConfig(config);
33254
- await Bun.$`mkdir -p ${STREAMS_DIR}`.quiet();
33255
- await Bun.write(`${STREAMS_DIR}/.gitkeep`, "");
33256
- printSummary(config);
33257
- }
33258
- async function promptDataDir(config) {
33259
- const defaultDir = "~/.secondlayer/data";
33260
- const choice = await select2({
33261
- message: "Where should streams store data?",
33262
- choices: [
33263
- { name: `Default (${defaultDir})`, value: "default" },
33264
- { name: "Custom path...", value: "custom" }
33265
- ]
33266
- });
33267
- if (choice === "default") {
33268
- return defaultDir;
33269
- }
33270
- const customPath = await input({
33271
- message: "Enter data directory path:",
33272
- default: config.dataDir !== defaultDir ? config.dataDir : undefined,
33273
- validate: (value) => {
33274
- if (!value.trim())
33275
- return "Path cannot be empty";
33276
- return true;
33277
- }
33278
- });
33279
- return customPath;
33280
- }
33281
- async function promptNodeSetup() {
33282
- const choice = await select2({
33283
- message: "Do you have an existing Stacks node?",
33284
- choices: [
33285
- { name: "Yes, auto-detect", value: "detect" },
33286
- { name: "Yes, specify path", value: "manual" },
33287
- { name: "No, skip for now", value: "skip" }
33288
- ]
33289
- });
33290
- if (choice === "skip") {
33291
- return null;
33292
- }
33293
- if (choice === "detect") {
33294
- return await handleAutoDetect();
33295
- }
33296
- const nodePath = await input({
33297
- message: "Enter path to Stacks node:",
33298
- validate: (value) => {
33299
- if (!value.trim())
33300
- return "Path cannot be empty";
33301
- return true;
33302
- }
33303
- });
33304
- const network = await promptNetwork();
33305
- return { installPath: nodePath, network };
33306
- }
33307
- async function handleAutoDetect() {
33308
- info(`Scanning for Stacks nodes...
33309
- `);
33310
- const nodes = await detectStacksNodes();
33311
- if (nodes.length === 0) {
33312
- console.log(` No Stacks nodes found.
33313
- `);
33314
- const retry = await select2({
33315
- message: "What would you like to do?",
33316
- choices: [
33317
- { name: "Enter path manually", value: "manual" },
33318
- { name: "Skip for now", value: "skip" }
33319
- ]
33320
- });
33321
- if (retry === "skip") {
33322
- return null;
33323
- }
33324
- const nodePath = await input({
33325
- message: "Enter path to Stacks node:",
33326
- validate: (value) => {
33327
- if (!value.trim())
33328
- return "Path cannot be empty";
33329
- return true;
33330
- }
33331
- });
33332
- const network = await promptNetwork();
33333
- return { installPath: nodePath, network };
33334
- }
33335
- console.log(`Found ${nodes.length} Stacks node${nodes.length > 1 ? "s" : ""}:
33336
- `);
33337
- for (const node of nodes) {
33338
- printNodeInfo(node);
33339
- }
33340
- if (nodes.length === 1) {
33341
- const useNode = await confirm({
33342
- message: `Use this node?`,
33343
- default: true
33344
- });
33345
- if (useNode) {
33346
- return { installPath: nodes[0].path, network: nodes[0].network };
33347
- }
33348
- return null;
33349
- }
33350
- const choices = [
33351
- ...nodes.map((node) => ({
33352
- name: `${node.path} (${node.network}${node.running ? ", running" : ""})`,
33353
- value: node.path
33354
- })),
33355
- { name: "None of these", value: "none" }
33356
- ];
33357
- const selectedPath = await select2({
33358
- message: "Which node should streams use?",
33359
- choices
33360
- });
33361
- if (selectedPath === "none") {
33362
- return null;
33363
- }
33364
- const selectedNode = nodes.find((n) => n.path === selectedPath);
33365
- if (!selectedNode)
33366
- return null;
33367
- return { installPath: selectedNode.path, network: selectedNode.network };
33368
- }
33369
- async function promptNetwork() {
33370
- const network = await select2({
33371
- message: "Which network?",
33372
- choices: [
33373
- { name: "mainnet", value: "mainnet" },
33374
- { name: "testnet", value: "testnet" }
33375
- ]
33376
- });
33377
- return network;
33378
- }
33379
- async function promptEndpointUrl(config) {
33380
- const internalUrl = "http://localhost:3900/receiver";
33381
- const choice = await select2({
33382
- message: "Default endpoint URL for new streams?",
33383
- choices: [
33384
- { name: `Internal test server (${internalUrl})`, value: "internal" },
33385
- { name: "Custom URL...", value: "custom" }
33386
- ]
33387
- });
33388
- if (choice === "internal") {
33389
- return internalUrl;
33390
- }
33391
- const customUrl = await input({
33392
- message: "Enter endpoint URL:",
33393
- default: config.defaultEndpointUrl !== internalUrl ? config.defaultEndpointUrl : undefined,
33394
- validate: (value) => {
33395
- if (!value.trim())
33396
- return "URL cannot be empty";
33397
- try {
33398
- new URL(value);
33399
- return true;
33400
- } catch {
33401
- return "Must be a valid URL";
33402
- }
33403
- }
33404
- });
33405
- return customUrl;
33406
- }
33407
- async function hostedLogin(config) {
33408
- const apiUrl = resolveApiUrl(config);
33409
- info(`Connecting to ${config.network} API...`);
33410
- console.log();
33411
- const email = await input({
33412
- message: "Email address:",
33413
- validate: (v) => v.includes("@") || "Enter a valid email"
33414
- });
33415
- const mlRes = await fetch(`${apiUrl}/api/auth/magic-link`, {
33416
- method: "POST",
33417
- headers: { "Content-Type": "application/json" },
33418
- body: JSON.stringify({ email })
33419
- });
33420
- try {
33421
- await assertOk(mlRes);
33422
- } catch (e) {
33423
- error(`Failed to send magic link: ${e instanceof Error ? e.message : e}`);
33424
- return false;
33425
- }
33426
- info("Check your email for a login token.");
33427
- const token = await input({
33428
- message: "Paste token from email:",
33429
- validate: (v) => v.trim().length > 0 || "Token is required"
33430
- });
33431
- const verifyRes = await fetch(`${apiUrl}/api/auth/verify`, {
33432
- method: "POST",
33433
- headers: { "Content-Type": "application/json" },
33434
- body: JSON.stringify({ token: token.trim() })
33435
- });
33436
- try {
33437
- await assertOk(verifyRes);
33438
- } catch (e) {
33439
- error(`Verification failed: ${e instanceof Error ? e.message : e}`);
33440
- return false;
33441
- }
33442
- const result = await verifyRes.json();
33443
- const { hostname } = await import("node:os");
33444
- const sessionHeaders = {
33445
- Authorization: `Bearer ${result.sessionToken}`,
33446
- "Content-Type": "application/json"
33447
- };
33448
- const keyName = `cli-${hostname().toLowerCase()}`;
33449
- const listRes = await fetch(`${apiUrl}/api/keys`, {
33450
- headers: sessionHeaders
33451
- });
33452
- if (listRes.ok) {
33453
- const { keys } = await listRes.json();
33454
- const existing = keys.find((k) => k.name === keyName && k.status === "active");
33455
- if (existing) {
33456
- await fetch(`${apiUrl}/api/keys/${existing.id}`, {
33457
- method: "DELETE",
33458
- headers: sessionHeaders
33459
- });
33460
- }
33461
- }
33462
- const createRes = await fetch(`${apiUrl}/api/keys`, {
33463
- method: "POST",
33464
- headers: sessionHeaders,
33465
- body: JSON.stringify({ name: keyName })
33466
- });
33467
- try {
33468
- await assertOk(createRes);
33469
- } catch (e) {
33470
- error(`Failed to create API key: ${e instanceof Error ? e.message : e}`);
33471
- return false;
33472
- }
33473
- const { key } = await createRes.json();
33474
- config.apiKey = key;
33475
- await saveConfig(config);
33476
- try {
33477
- await fetch(`${apiUrl}/api/auth/logout`, {
33478
- method: "POST",
33479
- headers: sessionHeaders
33480
- });
33481
- } catch {}
33482
- const account = result.account;
33483
- console.log();
33484
- success(`Authenticated as ${account.email}!`);
33485
- console.log();
33486
- console.log(` Plan: ${account.plan}`);
33487
- console.log(` API: ${apiUrl}`);
33488
- console.log();
33489
- console.log(" Next steps:");
33490
- console.log(" sl streams list # List streams");
33491
- console.log(" sl streams new <name> # Create a stream");
33492
- console.log(" sl auth status # Check auth status");
33493
- console.log();
33494
- return true;
33495
- }
33496
- function printSummary(config) {
33497
- console.log();
33498
- success("Configuration saved!");
33499
- console.log();
33500
- console.log(" Settings:");
33501
- console.log(` Data directory: ${config.dataDir}`);
33502
- if (config.defaultEndpointUrl) {
33503
- console.log(` Endpoint URL: ${config.defaultEndpointUrl}`);
33504
- }
33505
- if (config.node) {
33506
- console.log(` Node path: ${config.node.installPath}`);
33507
- console.log(` Network: ${config.node.network}`);
33508
- }
33509
- console.log();
33510
- console.log(" Next steps:");
33511
- console.log(" sl local start # Start dev services");
33512
- if (config.node) {
33513
- console.log(" sl stack start # Start your Stacks node");
33514
- }
33515
- console.log(" sl streams new <name> # Create a new stream config");
33516
- console.log();
33517
- }
33518
- async function runDetection() {
33519
- info(`Scanning for Stacks nodes...
33520
- `);
33521
- const nodes = await detectStacksNodes();
33522
- if (nodes.length === 0) {
33523
- console.log(` No Stacks nodes found.
33524
- `);
33525
- console.log("Checked locations:");
33526
- console.log(" - Running Docker containers");
33527
- console.log(" - /Volumes/*/stacks-blockchain-docker");
33528
- console.log(" - ~/stacks-blockchain-docker");
33529
- console.log(` - /opt/stacks-*
33530
- `);
33531
- console.log("To set up a node manually:");
33532
- console.log(" sl config set node.installPath /path/to/node");
33533
- return;
33534
- }
33535
- console.log(`Found ${nodes.length} Stacks node${nodes.length > 1 ? "s" : ""}:
33536
- `);
33537
- for (const node of nodes) {
33538
- printNodeInfo(node);
33539
- }
33540
- }
33541
- function printNodeInfo(node) {
33542
- const status = node.running ? "\x1B[32m●\x1B[0m running" : "\x1B[90m○\x1B[0m stopped";
33543
- const source = node.source === "container" ? "docker" : "filesystem";
33544
- console.log(` ${status} ${node.path}`);
33545
- console.log(` network: ${node.network}, source: ${source}
33546
- `);
33547
- }
33548
- // src/commands/delete.ts
33549
- init_api_client();
33550
- init_output();
33551
- import { confirm as confirm2 } from "@inquirer/prompts";
33552
- function registerDeleteCommand(program2) {
33553
- program2.command("delete <id>").alias("rm").description("Delete a stream").option("-f, --force", "Skip confirmation prompt").action(async (id, options) => {
33554
- try {
33555
- const stream = await getStream(id);
33556
- if (!options.force) {
33557
- const confirmed = await confirm2({
33558
- message: `Delete stream "${stream.name}" (${stream.id})?`,
33559
- default: false
33560
- });
33561
- if (!confirmed) {
33562
- warn("Aborted");
33563
- return;
33564
- }
33565
- }
33566
- await deleteStream(id);
33567
- success(`Deleted stream: ${stream.name}`);
33568
- } catch (err) {
33569
- handleApiError(err, "delete stream");
33570
- }
33571
- });
33572
- }
33573
-
33574
- // src/commands/get.ts
33575
- init_api_client();
33576
- init_output();
33577
- function registerGetCommand(program2) {
33578
- program2.command("get <id>").description("Get details of a stream").option("--json", "Output as JSON").action(async (id, options) => {
33579
- try {
33580
- const stream = await getStream(id);
33581
- if (options.json) {
33582
- console.log(JSON.stringify(stream, null, 2));
33583
- return;
33584
- }
33585
- const statusColor = stream.status === "active" ? green : stream.status === "failed" ? red : stream.status === "paused" ? yellow : dim;
33586
- console.log(formatKeyValue([
33587
- ["ID", stream.id],
33588
- ["Name", stream.name],
33589
- ["Status", statusColor(stream.status)],
33590
- ["Endpoint URL", stream.endpointUrl],
33591
- ["Total Deliveries", stream.totalDeliveries.toString()],
33592
- ["Failed Deliveries", stream.failedDeliveries.toString()],
33593
- ["Last Triggered", stream.lastTriggeredAt || dim("never")],
33594
- ["Last Block", stream.lastTriggeredBlock?.toString() || dim("n/a")],
33595
- ["Created", stream.createdAt],
33596
- ["Updated", stream.updatedAt]
33597
- ]));
33598
- if (stream.errorMessage) {
33599
- console.log(`
33600
- ${red("Error:")} ${stream.errorMessage}`);
33601
- }
33602
- console.log(`
33603
- ${dim("Filters:")}`);
33604
- console.log(JSON.stringify(stream.filters, null, 2));
33605
- console.log(`
33606
- ${dim("Options:")}`);
33607
- console.log(JSON.stringify(stream.options, null, 2));
33608
- } catch (err) {
33609
- handleApiError(err, "get stream");
33610
- }
33611
- });
33612
- }
33613
-
33614
- // src/commands/list.ts
33615
- init_api_client();
33616
- init_output();
33617
- function registerListCommand(program2) {
33618
- program2.command("list").alias("ls").description("List all streams").option("-s, --status <status>", "Filter by status (inactive/active/paused/failed)").option("--json", "Output as JSON").action(async (options) => {
33619
- try {
33620
- const { streams, total } = await listStreams({
33621
- status: options.status
33622
- });
33623
- if (options.json) {
33624
- console.log(JSON.stringify(streams, null, 2));
33625
- return;
33626
- }
33627
- if (streams.length === 0) {
33628
- console.log("No streams found");
33629
- return;
33630
- }
33631
- const rows = streams.map((s) => {
33632
- const statusColor = s.status === "active" ? green : s.status === "failed" ? red : s.status === "paused" ? yellow : dim;
33633
- return [
33634
- s.id.slice(0, 8),
33635
- s.name,
33636
- statusColor(s.status),
33637
- s.totalDeliveries.toString()
33638
- ];
33639
- });
33640
- console.log(formatTable(["ID", "Name", "Status", "Deliveries"], rows));
33641
- console.log(dim(`
33642
- ${total} stream(s) total`));
33643
- } catch (err) {
33644
- handleApiError(err, "list streams");
33645
- }
33646
- });
33647
- }
33648
-
33649
- // src/commands/logs.ts
33650
- init_api_client();
33651
- init_config();
33652
- init_output();
33653
- function registerLogsCommand(program2) {
33654
- program2.command("logs <stream-id>").description("View delivery logs for a stream").option("-f, --follow", "Follow logs in real-time").option("-n, --limit <count>", "Number of logs to show", "20").option("-s, --status <status>", "Filter by status (success|failed)").action(async (streamId, options) => {
33655
- const config = await loadConfig();
33656
- try {
33657
- const fullId = await resolveStreamId(streamId);
33658
- if (options.follow) {
33659
- await followLogs(resolveApiUrl(config), fullId, config, options.status);
33660
- } else {
33661
- await showRecentLogs(resolveApiUrl(config), fullId, Number.parseInt(options.limit), config, options.status);
33662
- }
33663
- } catch (err) {
33664
- handleApiError(err, "get logs");
33665
- }
33666
- });
33667
- }
33668
- async function showRecentLogs(apiUrl, streamId, limit, config, status) {
33669
- const params = new URLSearchParams({ limit: limit.toString() });
33670
- if (status)
33671
- params.set("status", status);
33672
- const response = await fetch(`${apiUrl}/api/streams/${streamId}/deliveries?${params}`, {
33673
- headers: authHeaders(config)
33674
- });
33675
- if (!response.ok) {
33676
- const body = await response.text();
33677
- let message = `HTTP ${response.status}`;
33678
- try {
33679
- const json = JSON.parse(body);
33680
- message = json.error || json.message || message;
33681
- } catch {
33682
- if (body)
33683
- message = body;
33684
- }
33685
- throw new Error(message);
33686
- }
33687
- const data = await response.json();
33688
- const { deliveries } = data;
33689
- if (deliveries.length === 0) {
33690
- console.log(dim("No deliveries yet"));
33691
- return;
33692
- }
33693
- const rows = deliveries.map((d) => {
33694
- const statusColor = d.status === "success" ? green : red;
33695
- const time = new Date(d.createdAt).toLocaleTimeString();
33696
- return [
33697
- dim(d.id.slice(0, 8)),
33698
- d.blockHeight.toString(),
33699
- statusColor(d.status),
33700
- d.statusCode?.toString() || "-",
33701
- d.responseTimeMs ? `${d.responseTimeMs}ms` : "-",
33702
- d.attempts.toString(),
33703
- dim(time)
33704
- ];
33705
- });
33706
- console.log(formatTable(["ID", "Block", "Status", "Code", "Time", "Attempts", "Timestamp"], rows));
33707
- }
33708
- async function followLogs(apiUrl, streamId, config, status) {
33709
- console.log(dim(`Following logs for stream ${streamId}...`));
33710
- console.log(dim(`Press Ctrl+C to stop
33711
- `));
33712
- const response = await fetch(`${apiUrl}/api/logs/${streamId}/stream`, {
33713
- headers: authHeaders(config)
33714
- });
33715
- if (!response.ok) {
33716
- const body = await response.text();
33717
- let message = `HTTP ${response.status}`;
33718
- try {
33719
- const json = JSON.parse(body);
33720
- message = json.error || json.message || message;
33721
- } catch {
33722
- if (body)
33723
- message = body;
33724
- }
33725
- throw new Error(message);
33726
- }
33727
- const reader = response.body?.getReader();
33728
- if (!reader) {
33729
- throw new Error("No response body");
33730
- }
33731
- const decoder = new TextDecoder;
33732
- let buffer2 = "";
33733
- while (true) {
33734
- const { done, value } = await reader.read();
33735
- if (done)
33736
- break;
33737
- buffer2 += decoder.decode(value, { stream: true });
33738
- const lines = buffer2.split(`
33739
- `);
33740
- buffer2 = lines.pop() || "";
33741
- let eventType = "";
33742
- let eventData = "";
33743
- for (const line of lines) {
33744
- if (line.startsWith("event:")) {
33745
- eventType = line.slice(6).trim();
33746
- } else if (line.startsWith("data:")) {
33747
- eventData = line.slice(5).trim();
33748
- } else if (line === "" && eventType && eventData) {
33749
- if (eventType === "delivery") {
33750
- try {
33751
- const delivery = JSON.parse(eventData);
33752
- if (!status || delivery.status === status) {
33753
- printDelivery(delivery);
33754
- }
33755
- } catch {}
33756
- }
33757
- eventType = "";
33758
- eventData = "";
33759
- }
33760
- }
33761
- }
33762
- }
33763
- function printDelivery(d) {
33764
- const statusColor = d.status === "success" ? green : red;
33765
- const time = new Date(d.createdAt).toLocaleTimeString();
33766
- console.log(`${dim(time)} ` + `${statusColor(d.status.padEnd(7))} ` + `block=${d.blockHeight} ` + `code=${d.statusCode || "-"} ` + `time=${d.responseTimeMs ? `${d.responseTimeMs}ms` : "-"} ` + `attempts=${d.attempts}`);
33767
- if (d.error) {
33768
- console.log(red(` Error: ${d.error}`));
33769
- }
33770
- }
33771
-
33772
- // src/commands/new.ts
33773
- init_config();
33774
- init_fs();
33775
- init_output();
33776
- import { join as join3 } from "node:path";
33777
-
33778
- // src/templates/stream.ts
33779
- function generateStreamTemplate(name, endpointUrl) {
33780
- return {
33781
- name,
33782
- endpointUrl: endpointUrl || "https://example.com/endpoint",
33783
- filters: [
33784
- {
33785
- type: "contract_call",
33786
- contractId: "SP000000000000000000002Q6VF78.pox-4"
33787
- }
33788
- ],
33789
- options: {
33790
- decodeClarityValues: true,
33791
- includeRawTx: false,
33792
- includeBlockMetadata: true,
33793
- rateLimit: 10,
33794
- timeoutMs: 1e4,
33795
- maxRetries: 3
33796
- }
33797
- };
33798
- }
33799
-
33800
- // src/commands/new.ts
33801
- var STREAMS_DIR2 = "streams";
33802
- function registerNewCommand(program2) {
33803
- program2.command("new <name>").description("Generate a new stream configuration file").option("-o, --output <path>", "Output path (default: streams/<name>.json)").action(async (name, options) => {
33804
- try {
33805
- const config = await loadConfig();
33806
- const outputPath = options.output || join3(STREAMS_DIR2, `${name}.json`);
33807
- if (await fileExists(outputPath)) {
33808
- warn(`File already exists: ${outputPath}`);
33809
- process.exit(1);
33810
- }
33811
- const dir = outputPath.substring(0, outputPath.lastIndexOf("/"));
33812
- if (dir) {
33813
- await ensureDir(dir);
33814
- }
33815
- const template = generateStreamTemplate(name, config.defaultEndpointUrl);
33816
- await writeTextFile(outputPath, JSON.stringify(template, null, 2) + `
33817
- `);
33818
- success(`Created ${outputPath}`);
33819
- if (!config.defaultEndpointUrl) {
33820
- warn("Edit the endpointUrl before registering — it must be a reachable HTTPS endpoint");
33821
- }
33822
- console.log(`
33823
- Edit the file to configure your stream, then run:`);
33824
- console.log(` sl streams register ${outputPath}`);
33825
- } catch (err) {
33826
- error(`Failed to create stream: ${err}`);
33827
- process.exit(1);
33828
- }
33829
- });
33830
- }
33831
-
33832
- // src/commands/register.ts
33833
- init_api_client();
33834
- init_fs();
33835
- init_output();
33836
- import { CreateStreamSchema } from "@secondlayer/shared/schemas";
33837
- function registerRegisterCommand(program2) {
33838
- program2.command("register <file>").description("Register a stream from a JSON configuration file").option("-u, --update", "Update existing stream if name matches").action(async (filePath, options) => {
33839
- try {
33840
- if (!await fileExists(filePath)) {
33841
- error(`File not found: ${filePath}`);
33842
- process.exit(1);
33843
- }
33844
- const content = await readJsonFile(filePath);
33845
- const parsed = CreateStreamSchema.safeParse(content);
33846
- if (!parsed.success) {
33847
- error("Invalid stream configuration:");
33848
- for (const issue of parsed.error.issues) {
33849
- console.log(` - ${issue.path.join(".")}: ${issue.message}`);
33850
- }
33851
- process.exit(1);
33852
- }
33853
- const streamData = parsed.data;
33854
- if (options.update) {
33855
- try {
33856
- const updated = await updateStreamByName(streamData.name, streamData);
33857
- success(`Updated stream: ${updated.name}`);
33858
- console.log(formatKeyValue([
33859
- ["ID", updated.id],
33860
- ["Name", updated.name]
33861
- ]));
33862
- return;
33863
- } catch (err) {
33864
- if (err instanceof ApiError && err.status === 404) {
33865
- warn("Stream not found, creating new...");
33866
- } else {
33867
- throw err;
33868
- }
33869
- }
33870
- }
33871
- const result = await createStream(streamData);
33872
- success(`Registered stream: ${result.stream.name}`);
33873
- console.log(formatKeyValue([
33874
- ["ID", result.stream.id],
33875
- ["Name", result.stream.name],
33876
- ["Signing Secret", result.signingSecret]
33877
- ]));
33878
- console.log(dim(`
33879
- Save the signing secret - it won't be shown again!`));
33880
- } catch (err) {
33881
- handleApiError(err, "register stream");
33882
- }
33883
- });
33884
- }
33885
-
33886
- // src/commands/replay.ts
33887
- init_api_client();
33888
- init_config();
33889
- init_output();
33890
- function registerReplayCommand(program2) {
33891
- program2.command("replay <stream-id>").description("Replay blocks through a stream (re-evaluate and re-deliver)").option("--from <block>", "Start block height").option("--to <block>", "End block height").option("--last <count>", "Replay last N blocks").option("--block <height>", "Trigger evaluation for a single block").option("--fixture <path>", "Load block from fixture file (only with --block)").action(async (rawStreamId, options) => {
33892
- const config = await loadConfig();
33893
- try {
33894
- const streamId = await resolveStreamId(rawStreamId);
33895
- if (options.block) {
33896
- await triggerBlock(config, streamId, options.block, options.fixture);
33897
- return;
33898
- }
33899
- if (options.fixture) {
33900
- error("--fixture can only be used with --block");
33901
- process.exit(1);
33902
- }
33903
- let fromBlock;
33904
- let toBlock;
33905
- if (options.last) {
33906
- const lastCount = Number.parseInt(options.last);
33907
- if (isNaN(lastCount) || lastCount <= 0) {
33908
- error("--last must be a positive number");
33909
- process.exit(1);
33910
- }
33911
- const statusRes = await fetch(`${resolveApiUrl(config)}/status`, {
33912
- headers: authHeaders(config)
33913
- });
33914
- if (!statusRes.ok) {
33915
- throw new Error("Failed to get index progress");
33916
- }
33917
- const status = await statusRes.json();
33918
- const progress = status.indexProgress[0];
33919
- if (!progress) {
33920
- error("No index progress found");
33921
- process.exit(1);
33922
- }
33923
- toBlock = Number(progress.lastIndexedBlock);
33924
- fromBlock = Math.max(0, toBlock - lastCount + 1);
33925
- info(`Replaying last ${lastCount} blocks (${fromBlock} to ${toBlock})`);
33926
- } else if (options.from && options.to) {
33927
- fromBlock = Number.parseInt(options.from);
33928
- toBlock = Number.parseInt(options.to);
33929
- if (isNaN(fromBlock) || fromBlock < 0) {
33930
- error("--from must be a non-negative number");
33931
- process.exit(1);
33932
- }
33933
- if (isNaN(toBlock) || toBlock < 0) {
33934
- error("--to must be a non-negative number");
33935
- process.exit(1);
33936
- }
33937
- if (fromBlock > toBlock) {
33938
- error("--from must be less than or equal to --to");
33939
- process.exit(1);
33940
- }
33941
- } else {
33942
- error("Must specify --from/--to, --last, or --block");
33943
- console.log(dim(`
33944
- Examples:`));
33945
- console.log(dim(" sl streams replay <id> --from 100000 --to 100500"));
33946
- console.log(dim(" sl streams replay <id> --last 1000"));
33947
- console.log(dim(" sl streams replay <id> --block 100000"));
33948
- console.log(dim(" sl streams replay <id> --block 100000 --fixture block.json"));
33949
- process.exit(1);
33950
- }
33951
- const response = await fetch(`${resolveApiUrl(config)}/api/streams/${streamId}/replay`, {
33952
- method: "POST",
33953
- headers: authHeaders(config),
33954
- body: JSON.stringify({ fromBlock, toBlock })
33955
- });
33956
- if (!response.ok) {
33957
- const body = await response.text();
33958
- throw new Error(parseError2(response.status, body));
33959
- }
33960
- const result = await response.json();
33961
- success("Replay started");
33962
- console.log(formatKeyValue([
33963
- ["Stream ID", result.streamId],
33964
- ["From Block", result.fromBlock.toString()],
33965
- ["To Block", result.toBlock.toString()],
33966
- ["Jobs Created", result.jobCount.toString()]
33967
- ]));
33968
- console.log(dim(`
33969
- Jobs will be processed by the worker in block order.`));
33970
- console.log(dim("Use 'sl streams logs <id> -f' to monitor progress."));
33971
- } catch (err) {
33972
- handleApiError(err, "start replay");
33973
- }
33974
- });
33975
- }
33976
- async function triggerBlock(config, streamId, blockStr, fixturePath) {
33977
- const blockHeight = Number.parseInt(blockStr);
33978
- if (isNaN(blockHeight) || blockHeight < 0) {
33979
- error("Block height must be a non-negative number");
33980
- process.exit(1);
33981
- }
33982
- if (fixturePath) {
33983
- const file = Bun.file(fixturePath);
33984
- if (!await file.exists()) {
33985
- error(`Fixture file not found: ${fixturePath}`);
33986
- process.exit(1);
33987
- }
33988
- const fixture = await file.json();
33989
- const indexerUrl = process.env.INDEXER_URL || "http://localhost:3700";
33990
- const indexerRes = await fetch(`${indexerUrl}/new_block`, {
33991
- method: "POST",
33992
- headers: { "Content-Type": "application/json" },
33993
- body: JSON.stringify(fixture)
33994
- });
33995
- if (!indexerRes.ok) {
33996
- error(`Failed to send fixture to indexer: ${await indexerRes.text()}`);
33997
- process.exit(1);
33998
- }
33999
- console.log(dim(`Sent fixture to indexer at block ${blockHeight}`));
34000
- }
34001
- const response = await fetch(`${resolveApiUrl(config)}/api/streams/${streamId}/trigger`, {
34002
- method: "POST",
34003
- headers: authHeaders(config),
34004
- body: JSON.stringify({ blockHeight })
34005
- });
34006
- if (!response.ok) {
34007
- const body = await response.text();
34008
- throw new Error(parseError2(response.status, body));
34009
- }
34010
- const result = await response.json();
34011
- success(`Triggered evaluation for block ${blockHeight}`);
34012
- console.log(formatKeyValue([
34013
- ["Job ID", result.jobId],
34014
- ["Stream ID", result.streamId],
34015
- ["Block", result.blockHeight.toString()]
34016
- ]));
34017
- }
34018
- function parseError2(status, body) {
34019
- let message = `HTTP ${status}`;
34020
- try {
34021
- const json = JSON.parse(body);
34022
- message = json.error || json.message || message;
34023
- } catch {
34024
- if (body)
34025
- message = body;
34026
- }
34027
- return message;
34028
- }
34029
-
34030
- // src/commands/rotate-secret.ts
34031
- init_api_client();
34032
- init_output();
34033
- import { confirm as confirm3 } from "@inquirer/prompts";
34034
- function registerRotateSecretCommand(program2) {
34035
- program2.command("rotate-secret <id>").description("Generate a new signing secret for a stream").option("-y, --yes", "Skip confirmation prompt").action(async (id, options) => {
34036
- try {
34037
- const stream = await getStream(id);
34038
- if (!options.yes) {
34039
- const confirmed = await confirm3({
34040
- message: `Rotate signing secret for "${stream.name}"? The current secret will be invalidated.`,
34041
- default: false
34042
- });
34043
- if (!confirmed) {
34044
- warn("Cancelled");
34045
- return;
34046
- }
34047
- }
34048
- const result = await rotateSecret(stream.id);
34049
- success(`Rotated signing secret for: ${stream.name}`);
34050
- console.log(formatKeyValue([
34051
- ["Stream", stream.name],
34052
- ["Signing Secret", result.secret]
34053
- ]));
34054
- console.log(dim(`
34055
- Save the signing secret - it won't be shown again!`));
34056
- } catch (err) {
34057
- handleApiError(err, "rotate secret");
34058
- }
34059
- });
34060
- }
34061
-
34062
- // src/commands/set.ts
34063
- init_api_client();
34064
- init_config();
34065
- init_output();
34066
- function registerSetCommand(program2) {
34067
- program2.command("set [id] [state]").description("Set stream state (active, disabled, paused)").option("--all", "Apply to all streams").option("--wait", "Wait for pending jobs to complete (with paused)").option("--retry", "Re-enable an errored stream").option("--replay-failed", "Also replay failed deliveries (with --retry)").option("-o, --option <kv...>", "Set stream option (key=value, e.g. maxRetries=5)").action(async (id, state, options) => {
34068
- try {
34069
- if (options.retry) {
34070
- if (!id) {
34071
- error("Stream ID is required with --retry");
34072
- process.exit(1);
34073
- }
34074
- await retryStream(id, options.replayFailed);
34075
- return;
34076
- }
34077
- if (options.all) {
34078
- if (!state) {
34079
- error("State is required: sl streams set --all <active|paused>");
34080
- process.exit(1);
34081
- }
34082
- await setAllStreams(state, options.wait);
34083
- return;
34084
- }
34085
- if (options.option?.length) {
34086
- if (!id) {
34087
- error("Stream ID is required with --option");
34088
- process.exit(1);
34089
- }
34090
- const parsedOptions = parseOptions2(options.option);
34091
- await updateStream(id, { options: parsedOptions });
34092
- success(`Updated stream options: ${Object.entries(parsedOptions).map(([k, v]) => `${k}=${v}`).join(", ")}`);
34093
- if (!state)
34094
- return;
34095
- }
34096
- if (!id || !state) {
34097
- error("Usage: sl streams set <id> <active|disabled>");
34098
- console.log(dim(`
34099
- Examples:`));
34100
- console.log(dim(" sl streams set <id> active"));
34101
- console.log(dim(" sl streams set <id> disabled"));
34102
- console.log(dim(" sl streams set --all paused --wait"));
34103
- console.log(dim(" sl streams set <id> --retry --replay-failed"));
34104
- console.log(dim(" sl streams set <id> --option maxRetries=5"));
34105
- process.exit(1);
34106
- }
34107
- await setSingleStream(id, state);
34108
- } catch (err) {
34109
- handleApiError(err, "set stream state");
34110
- }
34111
- });
34112
- }
34113
- async function setSingleStream(id, state) {
34114
- switch (state) {
34115
- case "active": {
34116
- const stream = await enableStream(id);
34117
- success(`Enabled stream: ${stream.name} (status: active)`);
34118
- break;
34119
- }
34120
- case "disabled": {
34121
- const stream = await disableStream(id);
34122
- success(`Disabled stream: ${stream.name} (status: inactive)`);
34123
- break;
34124
- }
34125
- default:
34126
- error(`Unknown state: ${state}. Use active, disabled, or paused (with --all)`);
34127
- process.exit(1);
34128
- }
34129
- }
34130
- async function setAllStreams(state, wait) {
34131
- switch (state) {
34132
- case "paused": {
34133
- const result = await pauseAllStreams();
34134
- if (result.paused === 0) {
34135
- info("No active streams to pause");
34136
- return;
34137
- }
34138
- success(`Paused ${result.paused} stream${result.paused === 1 ? "" : "s"}`);
34139
- if (wait) {
34140
- await waitForQueueDrain();
34141
- }
34142
- break;
34143
- }
34144
- case "active": {
34145
- const result = await resumeAllStreams();
34146
- if (result.resumed === 0) {
34147
- info("No paused streams to resume");
34148
- return;
34149
- }
34150
- success(`Resumed ${result.resumed} stream${result.resumed === 1 ? "" : "s"}`);
34151
- break;
34152
- }
34153
- default:
34154
- error(`Unknown state for --all: ${state}. Use active or paused`);
34155
- process.exit(1);
34156
- }
34157
- }
34158
- async function retryStream(id, replayFailed) {
34159
- const config = await loadConfig();
34160
- const apiUrl = resolveApiUrl(config);
34161
- const getRes = await fetch(`${apiUrl}/api/streams/${id}`, {
34162
- headers: authHeaders(config)
34163
- });
34164
- if (!getRes.ok) {
34165
- const body = await getRes.text();
34166
- throw new Error(parseError3(getRes.status, body));
34167
- }
34168
- const stream = await getRes.json();
34169
- if (stream.status !== "failed") {
34170
- warn(`Stream is not in failed status (current status: ${stream.status})`);
34171
- console.log(dim(`
34172
- Use 'sl streams set <id> active' to enable an inactive stream.`));
34173
- process.exit(1);
34174
- }
34175
- if (stream.errorMessage) {
34176
- console.log(red(`Previous error: ${stream.errorMessage}`));
34177
- console.log("");
34178
- }
34179
- const enableRes = await fetch(`${apiUrl}/streams/${id}/enable`, {
34180
- method: "POST",
34181
- headers: authHeaders(config)
34182
- });
34183
- if (!enableRes.ok) {
34184
- const body = await enableRes.text();
34185
- throw new Error(parseError3(enableRes.status, body));
34186
- }
34187
- success(`Re-enabled stream: ${stream.name}`);
34188
- if (replayFailed) {
34189
- info("Replaying failed deliveries...");
34190
- const replayRes = await fetch(`${apiUrl}/streams/${id}/replay-failed`, {
34191
- method: "POST",
34192
- headers: authHeaders(config)
34193
- });
34194
- if (!replayRes.ok) {
34195
- const body = await replayRes.text();
34196
- warn(`Failed to replay: ${parseError3(replayRes.status, body)}`);
34197
- } else {
34198
- const result = await replayRes.json();
34199
- success(`Enqueued ${result.jobCount} replay jobs`);
34200
- }
34201
- }
34202
- console.log(dim(`
34203
- Monitor with: sl streams logs ` + id + " -f"));
34204
- }
34205
- async function waitForQueueDrain() {
34206
- const POLL_INTERVAL_MS = 1000;
34207
- process.stdout.write(dim("Waiting for jobs to complete..."));
34208
- while (true) {
34209
- const stats = await getQueueStats();
34210
- const active = stats.pending + stats.processing;
34211
- if (active === 0) {
34212
- process.stdout.write(`
34213
- `);
34214
- success("All jobs completed");
34215
- return;
34216
- }
34217
- process.stdout.write(`\r${dim(`Waiting for jobs to complete... ${active} remaining`)}`);
34218
- await Bun.sleep(POLL_INTERVAL_MS);
34219
- }
34220
- }
34221
- function parseOptions2(kvPairs) {
34222
- const result = {};
34223
- for (const kv of kvPairs) {
34224
- const eqIndex = kv.indexOf("=");
34225
- if (eqIndex === -1) {
34226
- throw new Error(`Invalid option format: "${kv}". Use key=value.`);
34227
- }
34228
- const key = kv.slice(0, eqIndex);
34229
- const raw = kv.slice(eqIndex + 1);
34230
- if (raw === "true")
34231
- result[key] = true;
34232
- else if (raw === "false")
34233
- result[key] = false;
34234
- else if (raw !== "" && !isNaN(Number(raw)))
34235
- result[key] = Number(raw);
34236
- else
34237
- result[key] = raw;
34238
- }
34239
- return result;
34240
- }
34241
- function parseError3(status, body) {
34242
- let message = `HTTP ${status}`;
34243
- try {
34244
- const json = JSON.parse(body);
34245
- message = json.error || json.message || message;
34246
- } catch {
34247
- if (body)
34248
- message = body;
34249
- }
34250
- return message;
34251
- }
34252
-
34253
- // src/commands/streams.ts
34254
- function registerStreamsCommand(program2) {
34255
- const streams = program2.command("streams").description("Manage event streams");
34256
- registerNewCommand(streams);
34257
- registerListCommand(streams);
34258
- registerGetCommand(streams);
34259
- registerRegisterCommand(streams);
34260
- registerDeleteCommand(streams);
34261
- registerSetCommand(streams);
34262
- registerLogsCommand(streams);
34263
- registerReplayCommand(streams);
34264
- registerRotateSecretCommand(streams);
34265
- }
34266
32860
  // src/commands/status.ts
34267
32861
  init_api_client();
34268
32862
  init_config();
@@ -34314,14 +32908,6 @@ function printStatus(status) {
34314
32908
  const dbColor = status.database.status === "ok" ? green : red;
34315
32909
  console.log(` Status: ${dbColor(status.database.status)}`);
34316
32910
  console.log("");
34317
- console.log(blue("Job Queue"));
34318
- console.log(formatKeyValue([
34319
- [" Pending", status.queue.pending.toString()],
34320
- [" Processing", status.queue.processing.toString()],
34321
- [" Completed", status.queue.completed.toString()],
34322
- [" Failed", status.queue.failed.toString()]
34323
- ]));
34324
- console.log("");
34325
32911
  console.log(blue("Index Progress"));
34326
32912
  if (status.indexProgress.length === 0) {
34327
32913
  console.log(dim(" No data indexed yet"));
@@ -34357,25 +32943,11 @@ function printStatus(status) {
34357
32943
  }
34358
32944
  }
34359
32945
  console.log("");
34360
- console.log(blue("Streams"));
34361
- console.log(formatKeyValue([
34362
- [" Total", status.streams.total.toString()],
34363
- [" Active", green(status.streams.active.toString())],
34364
- [" Paused", yellow(status.streams.paused.toString())],
34365
- [
34366
- " Error",
34367
- status.streams.error > 0 ? red(status.streams.error.toString()) : "0"
34368
- ]
34369
- ]));
34370
- console.log("");
34371
- if (status.activeSubgraphs !== undefined || status.recentDeliveries !== undefined) {
32946
+ if (status.activeSubgraphs !== undefined) {
34372
32947
  console.log(blue("Activity"));
34373
- const pairs = [];
34374
- if (status.activeSubgraphs !== undefined)
34375
- pairs.push([" Active Subgraphs", status.activeSubgraphs.toString()]);
34376
- if (status.recentDeliveries !== undefined)
34377
- pairs.push([" Deliveries (24h)", status.recentDeliveries.toString()]);
34378
- console.log(formatKeyValue(pairs));
32948
+ console.log(formatKeyValue([
32949
+ [" Active Subgraphs", status.activeSubgraphs.toString()]
32950
+ ]));
34379
32951
  console.log("");
34380
32952
  }
34381
32953
  console.log(dim(`Last updated: ${status.timestamp}`));
@@ -34383,7 +32955,7 @@ function printStatus(status) {
34383
32955
  // src/commands/sync.ts
34384
32956
  init_config();
34385
32957
  init_output();
34386
- import { confirm as confirm4 } from "@inquirer/prompts";
32958
+ import { confirm } from "@inquirer/prompts";
34387
32959
  import { getDb } from "@secondlayer/shared/db";
34388
32960
  import {
34389
32961
  countMissingBlocks,
@@ -34392,7 +32964,7 @@ import {
34392
32964
  import { StacksNodeClient } from "@secondlayer/shared/node";
34393
32965
  import { HiroClient } from "@secondlayer/shared/node/hiro-client";
34394
32966
  import { LocalClient } from "@secondlayer/shared/node/local-client";
34395
- var DEV_DATABASE_URL = "postgres://postgres:postgres@localhost:5432/streams_dev";
32967
+ var DEV_DATABASE_URL = "postgres://postgres:postgres@localhost:5432/secondlayer_dev";
34396
32968
  function registerSyncCommand(program2) {
34397
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() {
34398
32970
  const opts = this.opts();
@@ -34503,7 +33075,7 @@ Examples:`));
34503
33075
  if (useHiro) {
34504
33076
  console.log(dim("Note: Hiro API fetches are slower due to per-tx event lookups."));
34505
33077
  }
34506
- const confirmed = await confirm4({
33078
+ const confirmed = await confirm({
34507
33079
  message: "Continue?",
34508
33080
  default: true
34509
33081
  });
@@ -34600,14 +33172,14 @@ Examples:`));
34600
33172
  init_config();
34601
33173
  init_dev_state();
34602
33174
  init_output();
34603
- import { confirm as confirm5 } from "@inquirer/prompts";
33175
+ import { confirm as confirm2 } from "@inquirer/prompts";
34604
33176
  import { getDb as getDb2, sql } from "@secondlayer/shared/db";
34605
33177
  import {
34606
33178
  countMissingBlocks as countMissingBlocks2,
34607
33179
  findGaps as findGaps2
34608
33180
  } from "@secondlayer/shared/db/queries/integrity";
34609
33181
  import { StacksNodeClient as StacksNodeClient2 } from "@secondlayer/shared/node";
34610
- var DEV_DATABASE_URL2 = "postgres://postgres:postgres@localhost:5432/streams_dev";
33182
+ var DEV_DATABASE_URL2 = "postgres://postgres:postgres@localhost:5432/secondlayer_dev";
34611
33183
  function registerDbCommand(program2) {
34612
33184
  const dbCmd = program2.command("db").description("Inspect indexer database tables").hook("preAction", async () => {
34613
33185
  await requireLocalNetwork();
@@ -34630,7 +33202,7 @@ function registerDbCommand(program2) {
34630
33202
  const opts = this.opts();
34631
33203
  await showGaps(Number.parseInt(opts.limit), opts.json);
34632
33204
  });
34633
- dbCmd.command("reset").description("Truncate all indexed data (blocks, txs, events, jobs, deliveries)").option("-y, --yes", "Skip confirmation prompt").action(async function() {
33205
+ dbCmd.command("reset").description("Truncate all indexed data (blocks, txs, events)").option("-y, --yes", "Skip confirmation prompt").action(async function() {
34634
33206
  const opts = this.opts();
34635
33207
  await resetDatabase(opts.yes);
34636
33208
  });
@@ -34806,12 +33378,12 @@ async function resetDatabase(skipConfirm) {
34806
33378
  console.log(` ${red(blockCount.toString())} blocks`);
34807
33379
  console.log(` ${red(txCount.toString())} transactions`);
34808
33380
  console.log(` ${red(eventCount.toString())} events`);
34809
- console.log(` ${dim("+ jobs, deliveries, index_progress")}`);
33381
+ console.log(` ${dim("+ index_progress")}`);
34810
33382
  console.log("");
34811
- console.log(dim("Note: Stream configurations will be preserved."));
33383
+ console.log(dim("Note: Subgraph configurations will be preserved."));
34812
33384
  console.log("");
34813
33385
  if (!skipConfirm) {
34814
- const confirmed = await confirm5({
33386
+ const confirmed = await confirm2({
34815
33387
  message: "Are you sure you want to reset the database?",
34816
33388
  default: false
34817
33389
  });
@@ -34821,7 +33393,7 @@ async function resetDatabase(skipConfirm) {
34821
33393
  }
34822
33394
  }
34823
33395
  info("Truncating tables...");
34824
- await sql`TRUNCATE TABLE deliveries, jobs, events, transactions, blocks, index_progress RESTART IDENTITY CASCADE`.execute(db);
33396
+ await sql`TRUNCATE TABLE events, transactions, blocks, index_progress RESTART IDENTITY CASCADE`.execute(db);
34825
33397
  console.log("");
34826
33398
  success("Database reset complete");
34827
33399
  console.log("");
@@ -34845,10 +33417,10 @@ async function resyncDatabase(skipConfirm, backfill) {
34845
33417
  console.log(" 3. Fetch all blocks from node (backfill)");
34846
33418
  }
34847
33419
  console.log("");
34848
- console.log(dim("Note: Stream configurations will be preserved."));
33420
+ console.log(dim("Note: Subgraph configurations will be preserved."));
34849
33421
  console.log("");
34850
33422
  if (!skipConfirm) {
34851
- const confirmed = await confirm5({
33423
+ const confirmed = await confirm2({
34852
33424
  message: "Are you sure you want to resync?",
34853
33425
  default: false
34854
33426
  });
@@ -34858,7 +33430,7 @@ async function resyncDatabase(skipConfirm, backfill) {
34858
33430
  }
34859
33431
  }
34860
33432
  info("Truncating tables...");
34861
- await sql`TRUNCATE TABLE deliveries, jobs, events, transactions, blocks, index_progress RESTART IDENTITY CASCADE`.execute(db);
33433
+ await sql`TRUNCATE TABLE events, transactions, blocks, index_progress RESTART IDENTITY CASCADE`.execute(db);
34862
33434
  console.log(green(" ✓ Database reset"));
34863
33435
  const state = await loadDevState();
34864
33436
  if (state?.services?.indexer && isProcessRunning(state.services.indexer.pid)) {
@@ -34949,336 +33521,10 @@ async function resyncDatabase(skipConfirm, backfill) {
34949
33521
  process.exit(1);
34950
33522
  }
34951
33523
  }
34952
- // src/commands/receiver.ts
34953
- init_config();
34954
- init_output();
34955
- import { join as join5 } from "node:path";
34956
- function registerReceiverCommand(program2) {
34957
- const receiver = program2.command("receiver").description("Receiver development tools").hook("preAction", async () => {
34958
- await requireLocalNetwork();
34959
- });
34960
- receiver.command("init <directory>").description("Scaffold a receiver handler with types and signature verification").option("-n, --name <name>", "Stream name", "my-stream").option("--network <network>", "Network (mainnet/testnet)", "mainnet").option("-p, --port <port>", "Server port", "4000").action(async (directory, options) => {
34961
- try {
34962
- const config = await loadConfig();
34963
- const port = Number.parseInt(options.port);
34964
- const network = options.network;
34965
- const dir = join5(process.cwd(), directory);
34966
- const dirExists = await Bun.file(join5(dir, "package.json")).exists();
34967
- if (dirExists) {
34968
- error(`Directory ${directory} already contains a project`);
34969
- process.exit(1);
34970
- }
34971
- await Bun.$`mkdir -p ${dir}`.quiet();
34972
- await generateServerFile(dir, port);
34973
- await generateTypesFile(dir);
34974
- await generateStreamJson(dir, options.name, network, port, config.defaultEndpointUrl);
34975
- await generateEnvFile(dir);
34976
- await generatePackageJson(dir, options.name);
34977
- success(`Created receiver handler in ${directory}/`);
34978
- console.log("");
34979
- console.log(" Files created:");
34980
- console.log(` ${dim("server.ts")} Receiver server with HMAC verification`);
34981
- console.log(` ${dim("types.ts")} Payload type definitions`);
34982
- console.log(` ${dim("stream.json")} Stream configuration`);
34983
- console.log(` ${dim(".env")} Environment variables`);
34984
- console.log(` ${dim("package.json")} Dependencies`);
34985
- console.log("");
34986
- console.log(" Next steps:");
34987
- console.log(` cd ${directory}`);
34988
- console.log(" bun install");
34989
- console.log(" bun server.ts");
34990
- console.log("");
34991
- console.log(" Then register your stream:");
34992
- console.log(` sl streams register ${directory}/stream.json`);
34993
- console.log("");
34994
- } catch (err) {
34995
- error(`Failed to scaffold receiver: ${err}`);
34996
- process.exit(1);
34997
- }
34998
- });
34999
- }
35000
- async function generateServerFile(dir, port) {
35001
- const content = `import type { DeliveryPayload } from "./types.ts";
35002
-
35003
- const SIGNING_SECRET = process.env.STREAMS_SIGNING_SECRET;
35004
-
35005
- /**
35006
- * Verify HMAC signature from Stacks Streams
35007
- */
35008
- async function verifySignature(body: string, signature: string | null): Promise<boolean> {
35009
- if (!SIGNING_SECRET || !signature) return false;
35010
-
35011
- const encoder = new TextEncoder();
35012
- const key = await crypto.subtle.importKey(
35013
- "raw",
35014
- encoder.encode(SIGNING_SECRET),
35015
- { name: "HMAC", hash: "SHA-256" },
35016
- false,
35017
- ["sign"]
35018
- );
35019
-
35020
- const sig = await crypto.subtle.sign("HMAC", key, encoder.encode(body));
35021
- const expected = Buffer.from(sig).toString("hex");
35022
-
35023
- return signature === expected;
35024
- }
35025
-
35026
- /**
35027
- * Handle incoming delivery payload
35028
- */
35029
- async function handlePayload(payload: DeliveryPayload): Promise<void> {
35030
- console.log(\`Block \${payload.block.height}: \${payload.matches.events.length} events\`);
35031
-
35032
- for (const event of payload.matches.events) {
35033
- switch (event.type) {
35034
- case "stx_transfer_event":
35035
- console.log(\` STX transfer: \${event.data.amount} from \${event.data.sender}\`);
35036
- // TODO: Insert into your database
35037
- break;
35038
-
35039
- case "ft_transfer_event":
35040
- console.log(\` FT transfer: \${event.data.amount} of \${event.data.asset_identifier}\`);
35041
- break;
35042
-
35043
- case "nft_transfer_event":
35044
- console.log(\` NFT transfer: \${event.data.asset_identifier}\`);
35045
- break;
35046
-
35047
- case "contract_call":
35048
- console.log(\` Contract call: \${event.data.contract_id}.\${event.data.function_name}\`);
35049
- break;
35050
-
35051
- default:
35052
- console.log(\` Event: \${event.type}\`);
35053
- }
35054
- }
35055
- }
35056
-
35057
- Bun.serve({
35058
- port: ${port},
35059
-
35060
- async fetch(req) {
35061
- const url = new URL(req.url);
35062
-
35063
- // Health check
35064
- if (req.method === "GET" && url.pathname === "/health") {
35065
- return new Response("ok");
35066
- }
35067
-
35068
- // Receiver endpoint
35069
- if (req.method === "POST" && url.pathname === "/payload") {
35070
- const body = await req.text();
35071
- const signature = req.headers.get("x-streams-signature");
35072
-
35073
- // Verify signature
35074
- if (SIGNING_SECRET) {
35075
- const valid = await verifySignature(body, signature);
35076
- if (!valid) {
35077
- console.error("Invalid signature");
35078
- return new Response("Invalid signature", { status: 401 });
35079
- }
35080
- }
35081
-
35082
- try {
35083
- const payload: DeliveryPayload = JSON.parse(body);
35084
- await handlePayload(payload);
35085
- return new Response("ok");
35086
- } catch (err) {
35087
- console.error("Failed to process payload:", err);
35088
- return new Response("Internal error", { status: 500 });
35089
- }
35090
- }
35091
-
35092
- return new Response("Not found", { status: 404 });
35093
- },
35094
- });
35095
-
35096
- console.log(\`Receiver server listening on http://localhost:${port}/payload\`);
35097
- `;
35098
- await Bun.write(join5(dir, "server.ts"), content);
35099
- }
35100
- async function generateTypesFile(dir) {
35101
- const content = `/**
35102
- * Stacks Streams Delivery Payload Types
35103
- *
35104
- * These types match the payload structure sent by Stacks Streams.
35105
- */
35106
-
35107
- export interface DeliveryPayload {
35108
- streamId: string;
35109
- streamName: string;
35110
- network: "mainnet" | "testnet";
35111
- block: BlockMetadata;
35112
- matches: {
35113
- transactions: TransactionMatch[];
35114
- events: EventMatch[];
35115
- };
35116
- isBackfill: boolean;
35117
- deliveredAt: string;
35118
- }
35119
-
35120
- export interface BlockMetadata {
35121
- height: number;
35122
- hash: string;
35123
- parentHash: string;
35124
- burnBlockHeight: number;
35125
- timestamp: number;
35126
- }
35127
-
35128
- export interface TransactionMatch {
35129
- txId: string;
35130
- type: string;
35131
- sender: string;
35132
- status: "success" | "abort_by_response" | "abort_by_post_condition";
35133
- contractId: string | null;
35134
- functionName: string | null;
35135
- rawTx?: string;
35136
- }
35137
-
35138
- export type EventMatch =
35139
- | StxTransferEvent
35140
- | FtTransferEvent
35141
- | NftTransferEvent
35142
- | ContractCallEvent
35143
- | PrintEvent
35144
- | GenericEvent;
35145
-
35146
- interface BaseEvent {
35147
- txId: string;
35148
- eventIndex: number;
35149
- }
35150
-
35151
- export interface StxTransferEvent extends BaseEvent {
35152
- type: "stx_transfer_event";
35153
- data: {
35154
- sender: string;
35155
- recipient: string;
35156
- amount: string;
35157
- memo: string;
35158
- };
35159
- }
35160
-
35161
- export interface FtTransferEvent extends BaseEvent {
35162
- type: "ft_transfer_event";
35163
- data: {
35164
- sender: string;
35165
- recipient: string;
35166
- amount: string;
35167
- asset_identifier: string;
35168
- };
35169
- }
35170
-
35171
- export interface NftTransferEvent extends BaseEvent {
35172
- type: "nft_transfer_event";
35173
- data: {
35174
- sender: string;
35175
- recipient: string;
35176
- asset_identifier: string;
35177
- value: unknown;
35178
- };
35179
- }
35180
-
35181
- export interface ContractCallEvent extends BaseEvent {
35182
- type: "contract_call";
35183
- data: {
35184
- contract_id: string;
35185
- function_name: string;
35186
- function_args: unknown[];
35187
- };
35188
- }
35189
-
35190
- export interface PrintEvent extends BaseEvent {
35191
- type: "print_event";
35192
- data: {
35193
- contract_id: string;
35194
- topic: string;
35195
- value: unknown;
35196
- };
35197
- }
35198
-
35199
- export interface GenericEvent extends BaseEvent {
35200
- type: string;
35201
- data: unknown;
35202
- }
35203
-
35204
- /**
35205
- * Type guard to narrow event types
35206
- */
35207
- export function isStxTransfer(event: EventMatch): event is StxTransferEvent {
35208
- return event.type === "stx_transfer_event";
35209
- }
35210
-
35211
- export function isFtTransfer(event: EventMatch): event is FtTransferEvent {
35212
- return event.type === "ft_transfer_event";
35213
- }
35214
-
35215
- export function isNftTransfer(event: EventMatch): event is NftTransferEvent {
35216
- return event.type === "nft_transfer_event";
35217
- }
35218
-
35219
- export function isContractCall(event: EventMatch): event is ContractCallEvent {
35220
- return event.type === "contract_call";
35221
- }
35222
-
35223
- export function isPrintEvent(event: EventMatch): event is PrintEvent {
35224
- return event.type === "print_event";
35225
- }
35226
- `;
35227
- await Bun.write(join5(dir, "types.ts"), content);
35228
- }
35229
- async function generateStreamJson(dir, name, network, port, _defaultEndpointUrl) {
35230
- const content = {
35231
- name,
35232
- network,
35233
- endpointUrl: `http://localhost:${port}/payload`,
35234
- filters: [
35235
- {
35236
- type: "stx_transfer",
35237
- minAmount: 1e6
35238
- }
35239
- ],
35240
- options: {
35241
- decodeClarityValues: true,
35242
- includeRawTx: false,
35243
- includeBlockMetadata: true,
35244
- rateLimit: 10,
35245
- timeoutMs: 1e4,
35246
- maxRetries: 3
35247
- }
35248
- };
35249
- await Bun.write(join5(dir, "stream.json"), JSON.stringify(content, null, 2) + `
35250
- `);
35251
- }
35252
- async function generateEnvFile(dir) {
35253
- const content = `# Stacks Streams Signing Secret
35254
- # Get this from: sl streams register stream.json
35255
- STREAMS_SIGNING_SECRET=
35256
-
35257
- # Add your database connection, etc.
35258
- # DATABASE_URL=postgres://...
35259
- `;
35260
- await Bun.write(join5(dir, ".env"), content);
35261
- }
35262
- async function generatePackageJson(dir, name) {
35263
- const content = {
35264
- name: `${name}-receiver`,
35265
- version: "0.1.0",
35266
- type: "module",
35267
- scripts: {
35268
- start: "bun server.ts",
35269
- dev: "bun --watch server.ts"
35270
- },
35271
- dependencies: {},
35272
- devDependencies: {
35273
- "@types/bun": "latest"
35274
- }
35275
- };
35276
- await Bun.write(join5(dir, "package.json"), JSON.stringify(content, null, 2) + `
35277
- `);
35278
- }
35279
33524
  // src/commands/subgraphs.ts
35280
33525
  import { existsSync, mkdirSync, watch } from "node:fs";
35281
33526
  import { resolve } from "node:path";
33527
+ import { confirm as confirm3 } from "@inquirer/prompts";
35282
33528
 
35283
33529
  // src/generators/subgraph-scaffold.ts
35284
33530
  init_format();
@@ -35334,11 +33580,11 @@ function mapType(abiType, nullable) {
35334
33580
  function toCamelCase(str) {
35335
33581
  return str.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
35336
33582
  }
35337
- async function generateSubgraphScaffold(input2) {
35338
- const { contractId, functions } = input2;
33583
+ async function generateSubgraphScaffold(input) {
33584
+ const { contractId, functions } = input;
35339
33585
  const contractParts = contractId.split(".");
35340
33586
  const contractName = contractParts[contractParts.length - 1] ?? contractId;
35341
- const subgraphName = input2.subgraphName ?? contractName;
33587
+ const subgraphName = input.subgraphName ?? contractName;
35342
33588
  const publicFunctions = functions.filter((f) => f.access === "public");
35343
33589
  if (publicFunctions.length === 0) {
35344
33590
  throw new Error(`No public functions found in ${contractId}`);
@@ -35484,7 +33730,6 @@ init_config();
35484
33730
  init_fs();
35485
33731
  init_output();
35486
33732
  init_clarity();
35487
- import { confirm as confirm6 } from "@inquirer/prompts";
35488
33733
 
35489
33734
  // src/templates/subgraph.ts
35490
33735
  function generateSubgraphTemplate(name) {
@@ -35630,16 +33875,11 @@ Stopped watching.`);
35630
33875
  validateSubgraphDefinition(def);
35631
33876
  if (config.network !== "local") {
35632
33877
  info(`Bundling for remote deploy (${config.network})...`);
35633
- const esbuild = await import("esbuild");
35634
- const buildResult = await esbuild.build({
35635
- entryPoints: [absPath],
35636
- bundle: true,
35637
- platform: "node",
35638
- format: "esm",
35639
- external: ["@secondlayer/subgraphs"],
35640
- write: false
35641
- });
35642
- const handlerCode = new TextDecoder().decode(buildResult.outputFiles[0].contents);
33878
+ const { readFile: readFile2 } = await import("node:fs/promises");
33879
+ const source = await readFile2(absPath, "utf8");
33880
+ const { bundleSubgraphCode } = await import("@secondlayer/bundler");
33881
+ const bundled = await bundleSubgraphCode(source);
33882
+ const handlerCode = bundled.handlerCode;
35643
33883
  const result = await deploySubgraphApi({
35644
33884
  name: def.name,
35645
33885
  version: options2.version,
@@ -35656,7 +33896,7 @@ Stopped watching.`);
35656
33896
  if (result.diff) {
35657
33897
  const { addedTables, addedColumns, breakingChanges } = result.diff;
35658
33898
  if (breakingChanges.length > 0) {
35659
- warn(`Breaking changes detected:`);
33899
+ warn("Breaking changes detected:");
35660
33900
  for (const r of breakingChanges)
35661
33901
  warn(` ✗ ${r}`);
35662
33902
  }
@@ -35666,8 +33906,8 @@ Stopped watching.`);
35666
33906
  info(` + columns: ${t}.${cols.join(", ")}`);
35667
33907
  }
35668
33908
  }
35669
- const confirmed = options2.force || await confirm6({
35670
- message: `⚠ This will drop all data and reindex from scratch. Continue?`
33909
+ const confirmed = options2.force || await confirm3({
33910
+ message: "⚠ This will drop all data and reindex from scratch. Continue?"
35671
33911
  });
35672
33912
  if (!confirmed) {
35673
33913
  info("Aborted.");
@@ -35797,7 +34037,7 @@ Table endpoints:`));
35797
34037
  try {
35798
34038
  const fromBlock = Number.parseInt(options2.from, 10);
35799
34039
  const toBlock = Number.parseInt(options2.to, 10);
35800
- if (isNaN(fromBlock) || isNaN(toBlock)) {
34040
+ if (Number.isNaN(fromBlock) || Number.isNaN(toBlock)) {
35801
34041
  error("--from and --to must be valid block numbers");
35802
34042
  process.exit(1);
35803
34043
  }
@@ -35886,7 +34126,10 @@ ${result.meta.total} gap(s), ${result.meta.totalMissingBlocks} total missing blo
35886
34126
  console.log(dim("No rows found"));
35887
34127
  return;
35888
34128
  }
35889
- const columns = Object.keys(rows[0]);
34129
+ const firstRow = rows[0];
34130
+ if (!firstRow)
34131
+ return;
34132
+ const columns = Object.keys(firstRow);
35890
34133
  const tableRows = rows.map((row) => columns.map((col) => {
35891
34134
  const val = row[col];
35892
34135
  if (val === null || val === undefined)
@@ -35905,8 +34148,8 @@ ${rows.length} row(s)`));
35905
34148
  subgraphs.command("delete <name>").description("Delete a subgraph and its data").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
35906
34149
  try {
35907
34150
  if (!options2.yes) {
35908
- const { confirm: confirm7 } = await import("@inquirer/prompts");
35909
- const ok = await confirm7({
34151
+ const { confirm: confirm4 } = await import("@inquirer/prompts");
34152
+ const ok = await confirm4({
35910
34153
  message: `Delete subgraph "${name}" and all its data? This cannot be undone.`
35911
34154
  });
35912
34155
  if (!ok) {
@@ -35964,7 +34207,7 @@ ${rows.length} row(s)`));
35964
34207
  const client = new StacksApiClient(network, apiKey);
35965
34208
  const contractInfo = await client.getContractInfo(contractAddress);
35966
34209
  const abi = parseApiResponse(contractInfo);
35967
- info(`Generating scaffold...`);
34210
+ info("Generating scaffold...");
35968
34211
  const content = await generateSubgraphScaffold({
35969
34212
  contractId: contractAddress,
35970
34213
  functions: abi.functions
@@ -35989,7 +34232,7 @@ ${rows.length} row(s)`));
35989
34232
  const outPath = resolve(options2.output);
35990
34233
  info(`Fetching subgraph metadata for "${subgraphName}"...`);
35991
34234
  const subgraphDetail = await getSubgraphApi(subgraphName);
35992
- info(`Generating typed client...`);
34235
+ info("Generating typed client...");
35993
34236
  const content = await generateSubgraphConsumer(subgraphName, subgraphDetail);
35994
34237
  const dir = resolve(outPath, "..");
35995
34238
  if (!existsSync(dir))
@@ -36015,7 +34258,7 @@ function registerStackCommand(program2) {
36015
34258
  }).action(async (options2) => {
36016
34259
  await stackStart(options2);
36017
34260
  });
36018
- stack.command("stop").description("Stop the full stack").option("--no-node", "Skip stopping the Stacks node").option("--no-dev", "Skip stopping dev services").option("--wait", "Pause streams and drain queue before stopping").hook("preAction", async () => {
34261
+ stack.command("stop").description("Stop the full stack").option("--no-node", "Skip stopping the Stacks node").option("--no-dev", "Skip stopping dev services").option("--wait", "Wait for in-flight work to drain before stopping").hook("preAction", async () => {
36019
34262
  await requireLocalNetwork();
36020
34263
  }).action(async (options2) => {
36021
34264
  await stackStop(options2);
@@ -36050,13 +34293,13 @@ async function stackStart(options2) {
36050
34293
  process.exit(1);
36051
34294
  }
36052
34295
  console.log("");
36053
- console.log(blue("Starting Stacks Streams"));
34296
+ console.log(blue("Starting Secondlayer Stack"));
36054
34297
  console.log(dim(` Network: ${network}`));
36055
34298
  console.log("");
36056
34299
  if (options2.node) {
36057
34300
  const nodePath = config.node?.installPath;
36058
34301
  if (!nodePath) {
36059
- warn("No node configured, skipping. Run 'sl setup' to configure.");
34302
+ warn("No node configured, skipping. Run 'sl local node setup' to configure.");
36060
34303
  } else if (await isNodeRunning()) {
36061
34304
  info("Node already running");
36062
34305
  } else {
@@ -36126,30 +34369,7 @@ async function stackStart(options2) {
36126
34369
  }
36127
34370
  async function stackStop(options2) {
36128
34371
  console.log("");
36129
- info("Stopping Stacks Streams...");
36130
- if (options2.wait) {
36131
- try {
36132
- const { pauseAllStreams: pauseAllStreams2, getQueueStats: getQueueStats2 } = await Promise.resolve().then(() => (init_api_client(), exports_api_client));
36133
- info("Pausing streams...");
36134
- await pauseAllStreams2();
36135
- process.stdout.write(dim("Waiting for jobs to complete..."));
36136
- for (let i = 0;i < 300; i++) {
36137
- const stats = await getQueueStats2();
36138
- const active = stats.pending + stats.processing;
36139
- if (active === 0) {
36140
- process.stdout.write(`
36141
- `);
36142
- success("Queue drained");
36143
- break;
36144
- }
36145
- process.stdout.write(`\r${dim(`Waiting for jobs... ${active} remaining`)}`);
36146
- await Bun.sleep(1000);
36147
- }
36148
- } catch {
36149
- warn("Could not pause streams (API may not be running)");
36150
- }
36151
- console.log("");
36152
- }
34372
+ info("Stopping Secondlayer Stack...");
36153
34373
  if (options2.dev) {
36154
34374
  if (await isDevRunning()) {
36155
34375
  info("Stopping dev services...");
@@ -36177,7 +34397,7 @@ async function stackStop(options2) {
36177
34397
  }
36178
34398
  }
36179
34399
  try {
36180
- const result = await Bun.$`docker ps -a --format json --filter "name=streams-dev" --filter "name=stacks"`.quiet().nothrow();
34400
+ const result = await Bun.$`docker ps -a --format json --filter "name=secondlayer-dev" --filter "name=stacks"`.quiet().nothrow();
36181
34401
  if (result.exitCode === 0) {
36182
34402
  const lines = result.stdout.toString().trim().split(`
36183
34403
  `).filter(Boolean);
@@ -36257,7 +34477,7 @@ async function checkHealth() {
36257
34477
  }
36258
34478
  const containers = [];
36259
34479
  try {
36260
- const result = await Bun.$`docker ps -a --format json --filter "name=stacks" --filter "name=streams-dev"`.quiet().nothrow();
34480
+ const result = await Bun.$`docker ps -a --format json --filter "name=stacks" --filter "name=secondlayer-dev"`.quiet().nothrow();
36261
34481
  if (result.exitCode === 0) {
36262
34482
  const lines = result.stdout.toString().trim().split(`
36263
34483
  `).filter(Boolean);
@@ -36323,13 +34543,12 @@ async function checkHealth() {
36323
34543
  }
36324
34544
  const infrastructure = { postgres: false };
36325
34545
  try {
36326
- const pg = await Bun.$`docker ps -q -f name=streams-dev-postgres`.quiet().nothrow();
34546
+ const pg = await Bun.$`docker ps -q -f name=secondlayer-dev-postgres`.quiet().nothrow();
36327
34547
  infrastructure.postgres = pg.stdout.toString().trim().length > 0;
36328
34548
  } catch {}
36329
34549
  const portsToCheck = [
36330
34550
  { port: config.ports.api, name: "API" },
36331
34551
  { port: config.ports.indexer, name: "Indexer" },
36332
- { port: config.ports.receiver, name: "Receiver" },
36333
34552
  { port: 20443, name: "Node RPC" }
36334
34553
  ];
36335
34554
  for (const { port, name } of portsToCheck) {
@@ -36431,17 +34650,6 @@ async function runHostedDoctor(jsonOutput) {
36431
34650
  }
36432
34651
  console.log("");
36433
34652
  }
36434
- const streams = statusData.streams;
36435
- if (streams) {
36436
- console.log(blue("Streams"));
36437
- console.log(formatKeyValue([
36438
- [" Total", streams.total.toString()],
36439
- [" Active", green(streams.active.toString())],
36440
- [" Paused", yellow(streams.paused.toString())],
36441
- [" Error", streams.error > 0 ? red(streams.error.toString()) : "0"]
36442
- ]));
36443
- console.log("");
36444
- }
36445
34653
  }
36446
34654
  console.log(blue("Issues"));
36447
34655
  if (issues.length === 0) {
@@ -36574,7 +34782,7 @@ init_api_client();
36574
34782
  init_config();
36575
34783
  init_output();
36576
34784
  import { hostname } from "node:os";
36577
- import { input as input2 } from "@inquirer/prompts";
34785
+ import { input } from "@inquirer/prompts";
36578
34786
  function registerAuthCommand(program2) {
36579
34787
  const auth = program2.command("auth").description("Manage authentication and API keys");
36580
34788
  auth.command("login").description("Login with email via magic link").action(async () => {
@@ -36584,7 +34792,7 @@ function registerAuthCommand(program2) {
36584
34792
  error("No API URL configured. Set network with: sl config set network testnet");
36585
34793
  process.exit(1);
36586
34794
  }
36587
- const email = await input2({
34795
+ const email = await input({
36588
34796
  message: "Email:",
36589
34797
  validate: (v) => v.includes("@") || "Enter a valid email"
36590
34798
  });
@@ -36596,7 +34804,7 @@ function registerAuthCommand(program2) {
36596
34804
  });
36597
34805
  await assertOk(mlRes);
36598
34806
  console.log(dim("Check your email for a 6-digit login code."));
36599
- const code = await input2({
34807
+ const code = await input({
36600
34808
  message: "Code:",
36601
34809
  validate: (v) => /^\d{6}$/.test(v.trim()) || "Enter the 6-digit code from your email"
36602
34810
  });
@@ -36829,20 +35037,14 @@ init_config();
36829
35037
  init_dev_state();
36830
35038
  init_node_manager();
36831
35039
  init_output();
36832
- var DEV_SERVICES = [
36833
- "api",
36834
- "indexer",
36835
- "worker",
36836
- "receiver",
36837
- "subgraphs"
36838
- ];
35040
+ var DEV_SERVICES = ["api", "indexer", "worker", "subgraphs"];
36839
35041
  function registerLocalCommand(program2) {
36840
35042
  const local = program2.command("local").description("Manage local development environment and Stacks node").hook("preAction", async (_thisCommand, actionCommand) => {
36841
35043
  if (actionCommand.name() === "help")
36842
35044
  return;
36843
35045
  await requireLocalNetwork();
36844
35046
  });
36845
- local.command("start").description("Start all local dev services (API, indexer, worker, receiver)").option("--indexer-port <port>", "Indexer port", "3700").option("--api-port <port>", "API port", "3800").option("--receiver-port <port>", "Test receiver server port", "3900").option("--no-receiver", "Skip test receiver server").option("--no-worker", "Skip worker service").option("--secret <secret>", "Signing secret for signature verification").option("--stacks-node", "Use port 3701 for indexer (avoids conflict with stacks-blockchain-api)").option("-f, --foreground", "Run in foreground (blocking)").action(async (options2) => {
35047
+ local.command("start").description("Start all local dev services (API, indexer, worker)").option("--indexer-port <port>", "Indexer port", "3700").option("--api-port <port>", "API port", "3800").option("--no-worker", "Skip worker service").option("--stacks-node", "Use port 3701 for indexer (avoids conflict with stacks-blockchain-api)").option("-f, --foreground", "Run in foreground (blocking)").action(async (options2) => {
36846
35048
  const { runBackground: runBackground2, runForeground: runForeground2, isDevAlreadyRunning: isDevAlreadyRunning2 } = await Promise.resolve().then(() => (init_dev_impl(), exports_dev_impl));
36847
35049
  if (await isDevAlreadyRunning2()) {
36848
35050
  return;
@@ -36864,7 +35066,7 @@ function registerLocalCommand(program2) {
36864
35066
  local.command("status").description("Show local environment status").action(async () => {
36865
35067
  await showLocalStatus();
36866
35068
  });
36867
- local.command("logs").description("View local service logs (dev + node)").option("-s, --service <name>", "Filter by service (api, indexer, worker, receiver, subgraphs, node)").option("-f, --follow", "Follow log output").option("-n, --lines <n>", "Number of lines to show", "50").option("-q, --quiet", "Filter out common noise").option("-v, --verbose", "Show full payloads").action(async (options2) => {
35069
+ local.command("logs").description("View local service logs (dev + node)").option("-s, --service <name>", "Filter by service (api, indexer, worker, subgraphs, node)").option("-f, --follow", "Follow log output").option("-n, --lines <n>", "Number of lines to show", "50").option("-q, --quiet", "Filter out common noise").action(async (options2) => {
36868
35070
  await showLocalLogs(options2);
36869
35071
  });
36870
35072
  const node = local.command("node").description("Manage local Stacks node");
@@ -36872,15 +35074,15 @@ function registerLocalCommand(program2) {
36872
35074
  const { runSetupWizard: runSetupWizard2 } = await Promise.resolve().then(() => (init_node_impl(), exports_node_impl));
36873
35075
  await runSetupWizard2();
36874
35076
  });
36875
- node.command("start").description("Start the Stacks node").option("-p, --path <path>", "Path to stacks-blockchain-docker (overrides config)").option("--with-indexer", "Also start streams indexer").action(async (options2) => {
35077
+ node.command("start").description("Start the Stacks node").option("-p, --path <path>", "Path to stacks-blockchain-docker (overrides config)").option("--with-indexer", "Also start indexer").action(async (options2) => {
36876
35078
  const { startNode: startNode2 } = await Promise.resolve().then(() => (init_node_impl(), exports_node_impl));
36877
35079
  await startNode2(options2.path, options2.withIndexer);
36878
35080
  });
36879
- node.command("stop").description("Stop the Stacks node").option("-p, --path <path>", "Path to stacks-blockchain-docker (overrides config)").option("-f, --force", "Skip confirmation").option("--wait", "Pause streams and wait for jobs to complete first").action(async (options2) => {
35081
+ node.command("stop").description("Stop the Stacks node").option("-p, --path <path>", "Path to stacks-blockchain-docker (overrides config)").option("-f, --force", "Skip confirmation").option("--wait", "Wait for in-flight work to drain first").action(async (options2) => {
36880
35082
  const { stopNode: stopNode2 } = await Promise.resolve().then(() => (init_node_impl(), exports_node_impl));
36881
35083
  await stopNode2(options2.path, options2.force, options2.wait);
36882
35084
  });
36883
- node.command("restart").description("Restart the Stacks node (stop then start)").option("-p, --path <path>", "Path to stacks-blockchain-docker (overrides config)").option("-f, --force", "Skip confirmation").option("--wait", "Pause streams and wait for jobs to complete before stopping").action(async (options2) => {
35085
+ node.command("restart").description("Restart the Stacks node (stop then start)").option("-p, --path <path>", "Path to stacks-blockchain-docker (overrides config)").option("-f, --force", "Skip confirmation").option("--wait", "Wait for in-flight work to drain before stopping").action(async (options2) => {
36884
35086
  const { restartNode: restartNode2 } = await Promise.resolve().then(() => (init_node_impl(), exports_node_impl));
36885
35087
  await restartNode2(options2.path, options2.force, options2.wait);
36886
35088
  });
@@ -36941,7 +35143,6 @@ var serviceColors2 = {
36941
35143
  indexer: cyan,
36942
35144
  worker: yellow,
36943
35145
  subgraphs: magenta,
36944
- receiver: green,
36945
35146
  node: red
36946
35147
  };
36947
35148
  async function showLocalLogs(options2) {
@@ -36954,8 +35155,7 @@ async function showLocalLogs(options2) {
36954
35155
  await showLogs2({
36955
35156
  follow: options2.follow,
36956
35157
  service,
36957
- lines: options2.lines,
36958
- verbose: options2.verbose
35158
+ lines: options2.lines
36959
35159
  });
36960
35160
  return;
36961
35161
  }
@@ -36964,9 +35164,9 @@ async function showLocalLogs(options2) {
36964
35164
  return;
36965
35165
  }
36966
35166
  if (options2.follow) {
36967
- await followCombinedLogs(showDev, showNode, lines, options2.quiet ?? false, options2.verbose ?? false);
35167
+ await followCombinedLogs(showDev, showNode, lines, options2.quiet ?? false);
36968
35168
  } else {
36969
- await showStaticCombinedLogs(showDev, showNode, lines, options2.quiet ?? false, options2.verbose ?? false);
35169
+ await showStaticCombinedLogs(showDev, showNode, lines, options2.quiet ?? false);
36970
35170
  }
36971
35171
  }
36972
35172
  async function showNodeLogs(options2) {
@@ -36985,7 +35185,7 @@ async function showNodeLogs(options2) {
36985
35185
  console.log(line);
36986
35186
  }
36987
35187
  }
36988
- async function showStaticCombinedLogs(showDev, showNode, lines, quiet, verbose) {
35188
+ async function showStaticCombinedLogs(showDev, showNode, lines, quiet) {
36989
35189
  const allLines = [];
36990
35190
  if (showDev) {
36991
35191
  const state = await loadDevState();
@@ -37016,11 +35216,11 @@ async function showStaticCombinedLogs(showDev, showNode, lines, quiet, verbose)
37016
35216
  }
37017
35217
  allLines.sort((a, b2) => a.timestamp.getTime() - b2.timestamp.getTime());
37018
35218
  for (const { service, line } of allLines.slice(-lines)) {
37019
- console.log(formatLogLine3(service, line, verbose));
35219
+ console.log(formatLogLine3(service, line));
37020
35220
  }
37021
35221
  }
37022
- async function followCombinedLogs(showDev, showNode, initialLines, quiet, verbose) {
37023
- await showStaticCombinedLogs(showDev, showNode, initialLines, quiet, verbose);
35222
+ async function followCombinedLogs(showDev, showNode, initialLines, quiet) {
35223
+ await showStaticCombinedLogs(showDev, showNode, initialLines, quiet);
37024
35224
  const procs = [];
37025
35225
  if (showDev) {
37026
35226
  const state = await loadDevState();
@@ -37031,7 +35231,7 @@ async function followCombinedLogs(showDev, showNode, initialLines, quiet, verbos
37031
35231
  stderr: "pipe"
37032
35232
  });
37033
35233
  procs.push(proc);
37034
- streamLogs(proc, name, verbose);
35234
+ pipeProcLogs(proc, name);
37035
35235
  }
37036
35236
  }
37037
35237
  }
@@ -37041,7 +35241,7 @@ async function followCombinedLogs(showDev, showNode, initialLines, quiet, verbos
37041
35241
  stderr: "pipe"
37042
35242
  });
37043
35243
  procs.push(proc);
37044
- streamLogs(proc, "node", verbose);
35244
+ pipeProcLogs(proc, "node");
37045
35245
  }
37046
35246
  process.on("SIGINT", () => {
37047
35247
  for (const proc of procs) {
@@ -37053,7 +35253,7 @@ async function followCombinedLogs(showDev, showNode, initialLines, quiet, verbos
37053
35253
  });
37054
35254
  await new Promise(() => {});
37055
35255
  }
37056
- function streamLogs(proc, serviceName, verbose) {
35256
+ function pipeProcLogs(proc, serviceName) {
37057
35257
  const readStream2 = async (stream2) => {
37058
35258
  if (!stream2)
37059
35259
  return;
@@ -37070,7 +35270,7 @@ function streamLogs(proc, serviceName, verbose) {
37070
35270
  buffer2 = lines.pop() || "";
37071
35271
  for (const line of lines) {
37072
35272
  if (line.trim()) {
37073
- console.log(formatLogLine3(serviceName, line, verbose));
35273
+ console.log(formatLogLine3(serviceName, line));
37074
35274
  }
37075
35275
  }
37076
35276
  }
@@ -37078,7 +35278,7 @@ function streamLogs(proc, serviceName, verbose) {
37078
35278
  readStream2(proc.stdout);
37079
35279
  readStream2(proc.stderr);
37080
35280
  }
37081
- function formatLogLine3(service, line, verbose) {
35281
+ function formatLogLine3(service, line) {
37082
35282
  const colorFn = serviceColors2[service] ?? dim;
37083
35283
  const prefix = colorFn(`[${service}]`);
37084
35284
  if (service === "node" && line.startsWith("[")) {
@@ -37098,29 +35298,8 @@ function formatLogLine3(service, line, verbose) {
37098
35298
  return `${prefix} ${dimTimestamp} ${dim(level + ":")} ${dim(message)}`;
37099
35299
  }
37100
35300
  }
37101
- if (service === "receiver" && !verbose) {
37102
- const summary = formatDeliverySummary2(line);
37103
- if (summary)
37104
- return `${prefix} ${summary}`;
37105
- }
37106
35301
  return `${prefix} ${line}`;
37107
35302
  }
37108
- function formatDeliverySummary2(jsonStr) {
37109
- try {
37110
- const data = JSON.parse(jsonStr);
37111
- if (data.type !== "delivery" || !data.body)
37112
- return null;
37113
- const { body, method, path, timestamp } = data;
37114
- const streamName = body.streamName ?? body.streamId?.slice(0, 8) ?? "unknown";
37115
- const height = body.block?.height ?? "?";
37116
- const txCount = body.matches?.transactions?.length ?? 0;
37117
- const eventCount = body.matches?.events?.length ?? 0;
37118
- const dimTimestamp = dim(`[${timestamp}]`);
37119
- return `${dimTimestamp} ${green("INFO:")} ${method} ${path} — ${streamName} block:${height} (${txCount} txs, ${eventCount} events)`;
37120
- } catch {
37121
- return null;
37122
- }
37123
- }
37124
35303
  // src/commands/marketplace.ts
37125
35304
  init_api_client();
37126
35305
  init_output();
@@ -37280,28 +35459,19 @@ function registerWorkflowsCommand(program2) {
37280
35459
  const config = await loadConfig();
37281
35460
  if (config.network !== "local") {
37282
35461
  info(`Bundling for remote deploy (${config.network})...`);
37283
- const esbuild = await import("esbuild");
37284
- const buildResult = await esbuild.build({
37285
- entryPoints: [absPath],
37286
- bundle: true,
37287
- platform: "node",
37288
- format: "esm",
37289
- external: ["@secondlayer/workflows"],
37290
- write: false
37291
- });
37292
- const handlerCode = new TextDecoder().decode(buildResult.outputFiles?.[0]?.contents);
35462
+ const { readFile: readFile2 } = await import("node:fs/promises");
35463
+ const source = await readFile2(absPath, "utf8");
35464
+ const { bundleWorkflowCode } = await import("@secondlayer/bundler");
35465
+ const bundled = await bundleWorkflowCode(source);
37293
35466
  const deployResult = await getClient2().workflows.deploy({
37294
- name: def.name,
37295
- trigger: def.trigger,
37296
- handlerCode,
37297
- retries: def.retries,
37298
- timeout: def.timeout
35467
+ name: bundled.name,
35468
+ trigger: bundled.trigger,
35469
+ handlerCode: bundled.handlerCode,
35470
+ sourceCode: bundled.sourceCode,
35471
+ retries: bundled.retries,
35472
+ timeout: bundled.timeout
37299
35473
  });
37300
- if (deployResult.action === "unchanged") {
37301
- info(`Workflow "${def.name}" is up to date (no changes)`);
37302
- } else {
37303
- success(`Workflow "${def.name}" ${deployResult.action} (remote)`);
37304
- }
35474
+ success(`Workflow "${def.name}" ${deployResult.action} v${deployResult.version} (remote)`);
37305
35475
  } else {
37306
35476
  success(`Workflow "${result.name}" is valid`);
37307
35477
  info(`Trigger: ${result.trigger.type}`);
@@ -37388,8 +35558,8 @@ ${items.length} workflow(s) total`));
37388
35558
  });
37389
35559
  workflows.command("trigger <name>").description("Trigger a workflow run").option("--input <json>", "Input JSON string").action(async (name, options2) => {
37390
35560
  try {
37391
- const input4 = options2.input ? JSON.parse(options2.input) : undefined;
37392
- const result = await getClient2().workflows.trigger(name, input4);
35561
+ const input3 = options2.input ? JSON.parse(options2.input) : undefined;
35562
+ const result = await getClient2().workflows.trigger(name, input3);
37393
35563
  success(`Triggered workflow "${name}"`);
37394
35564
  info(`Run ID: ${result.runId}`);
37395
35565
  } catch (err) {
@@ -37447,11 +35617,37 @@ ${runs.length} run(s)`));
37447
35617
  process.exit(1);
37448
35618
  }
37449
35619
  });
35620
+ workflows.command("templates [id]").description("List workflow templates, or print a template's source to stdout").option("--json", "Output as JSON (list mode only)").action(async (id, options2) => {
35621
+ const { templates, getTemplateById } = await import("@secondlayer/workflows/templates");
35622
+ if (id) {
35623
+ const template = getTemplateById(id);
35624
+ if (!template) {
35625
+ error(`Template not found: ${id}`);
35626
+ info(`Available: ${templates.map((t) => t.id).join(", ")}`);
35627
+ process.exit(1);
35628
+ }
35629
+ process.stdout.write(template.code);
35630
+ return;
35631
+ }
35632
+ if (options2.json) {
35633
+ console.log(JSON.stringify(templates.map(({ code: _code, ...rest }) => rest), null, 2));
35634
+ return;
35635
+ }
35636
+ const rows = templates.map((t) => [
35637
+ t.id,
35638
+ t.category,
35639
+ t.trigger,
35640
+ t.description
35641
+ ]);
35642
+ console.log(formatTable(["Id", "Category", "Trigger", "Description"], rows));
35643
+ console.log(dim(`
35644
+ ${templates.length} template(s). Pipe source with: sl workflows templates <id> > workflows/<name>.ts`));
35645
+ });
37450
35646
  workflows.command("delete <name>").description("Delete a workflow").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
37451
35647
  try {
37452
35648
  if (!options2.yes) {
37453
- const { confirm: confirm8 } = await import("@inquirer/prompts");
37454
- const ok = await confirm8({
35649
+ const { confirm: confirm5 } = await import("@inquirer/prompts");
35650
+ const ok = await confirm5({
37455
35651
  message: `Delete workflow "${name}"? This cannot be undone.`
37456
35652
  });
37457
35653
  if (!ok) {
@@ -37469,7 +35665,7 @@ ${runs.length} run(s)`));
37469
35665
  }
37470
35666
  // src/cli.ts
37471
35667
  var { version } = package_default;
37472
- program.name("secondlayer").alias("sl").description("SecondLayer CLI — streams, subgraphs, workflows, and real-time indexing for Stacks").version(version).option("--network <network>", "Override network (local, testnet, mainnet)");
35668
+ program.name("secondlayer").alias("sl").description("SecondLayer CLI — subgraphs, workflows, and real-time indexing for Stacks").version(version).option("--network <network>", "Override network (local, testnet, mainnet)");
37473
35669
  program.hook("preAction", (thisCommand) => {
37474
35670
  const net3 = thisCommand.opts().network;
37475
35671
  if (net3)
@@ -37477,10 +35673,10 @@ program.hook("preAction", (thisCommand) => {
37477
35673
  });
37478
35674
  program.addHelpText("after", `
37479
35675
  Quickstart:
37480
- $ sl setup # Configure network + auth
37481
- $ sl streams new my-stream # Scaffold a stream config
37482
- $ sl streams register streams/my-stream.json
37483
- $ sl status # Check system health
35676
+ $ sl auth login # Authenticate
35677
+ $ sl subgraphs new my-subgraph # Scaffold a subgraph
35678
+ $ sl workflows new my-workflow # Scaffold a workflow
35679
+ $ sl status # Check system health
37484
35680
  `);
37485
35681
  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) => {
37486
35682
  const { generate: generate2 } = await Promise.resolve().then(() => (init_generate(), exports_generate));
@@ -37490,7 +35686,6 @@ program.command("init").description("Initialize a new secondlayer.config.ts file
37490
35686
  const { init: init3 } = await Promise.resolve().then(() => (init_init(), exports_init));
37491
35687
  await init3();
37492
35688
  });
37493
- registerStreamsCommand(program);
37494
35689
  registerSubgraphsCommand(program);
37495
35690
  registerWorkflowsCommand(program);
37496
35691
  registerMarketplaceCommand(program);
@@ -37501,12 +35696,10 @@ registerStackCommand(program);
37501
35696
  registerDbCommand(program);
37502
35697
  registerSyncCommand(program);
37503
35698
  registerDoctorCommand(program);
37504
- registerSetupCommand(program);
37505
35699
  registerConfigCommand(program);
37506
35700
  registerAuthCommand(program);
37507
35701
  registerWhoamiCommand(program);
37508
- registerReceiverCommand(program);
37509
35702
  program.parse();
37510
35703
 
37511
- //# debugId=AB1C48D57706E94764756E2164756E21
35704
+ //# debugId=68B9BDC7A5E4D6A864756E2164756E21
37512
35705
  //# sourceMappingURL=cli.js.map