@secondlayer/cli 13.0.0 → 13.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -16502,7 +16502,7 @@ class StacksApiClient {
16502
16502
  const statusCode = typeof error2 === "object" && error2 !== null && "response" in error2 && typeof error2.response === "object" && error2.response !== null && "statusCode" in error2.response ? error2.response.statusCode : undefined;
16503
16503
  const message = error2 instanceof Error ? error2.message : String(error2);
16504
16504
  if (statusCode === 401) {
16505
- throw new Error("Authentication required. Run: secondlayer auth login");
16505
+ throw new Error(isOssMode() ? "Authentication required. Set INSTANCE_TOKEN from `secondlayer init` (SL_API_KEY is a legacy alias)." : "Authentication required. Run: secondlayer login");
16506
16506
  }
16507
16507
  if (statusCode === 404) {
16508
16508
  throw new Error(`${resourceType} not found: ${resourceId}`);
@@ -30031,8 +30031,7 @@ deployed definition's only copy is the row in the database. Pass
30031
30031
  await closeDb();
30032
30032
  }
30033
30033
  } catch (err) {
30034
- error(`Failed to deploy subgraph: ${err}`);
30035
- process.exit(1);
30034
+ handleApiError(err, "deploy subgraph");
30036
30035
  }
30037
30036
  });
30038
30037
  subgraphs.command("list").alias("ls").description("List all deployed subgraphs").option("--json", "Output as JSON").action(async (options3) => {
@@ -30682,7 +30681,7 @@ function emitOne(doc, label, json) {
30682
30681
  });
30683
30682
  }
30684
30683
  function registerIndexCommand(program2) {
30685
- const index = program2.command("index").description("Query the decoded Index layer (events + contract calls)");
30684
+ const index = program2.command("index").description("Query decoded Index data (events + contract calls)");
30686
30685
  const rangeFlags = (cmd) => cmd.option("--contract-id <id>", "Filter by contract id").option("--from-height <n>", "Start block height (inclusive)").option("--to-height <n>", "End block height (inclusive)").option("--cursor <cursor>", "Resume token from a previous next_cursor").option("--limit <n>", "Rows per page").option("--json", "Print the full envelope as JSON");
30687
30686
  const heightFlags = (cmd) => cmd.option("--from-height <n>", "Start block height (inclusive)").option("--to-height <n>", "End block height (inclusive)").option("--cursor <cursor>", "Resume token from a previous next_cursor").option("--limit <n>", "Rows per page").option("--json", "Print the full envelope as JSON");
30688
30687
  rangeFlags(index.command("ft-transfers")).description("List decoded SIP-010 fungible-token transfers").option("--sender <principal>", "Filter by sender").option("--recipient <principal>", "Filter by recipient").action(async (o3) => {
@@ -34997,6 +34996,7 @@ import { spawn as spawn4, spawnSync as spawnSync5 } from "node:child_process";
34997
34996
  import { randomBytes as randomBytes4 } from "node:crypto";
34998
34997
  import { existsSync as existsSync11 } from "node:fs";
34999
34998
  import { writeFile as writeFile7 } from "node:fs/promises";
34999
+ import { createServer } from "node:net";
35000
35000
  import { join as join19, resolve as resolvePath2 } from "node:path";
35001
35001
  import { FLOORS, diskFloorGb } from "@secondlayer/shared/runtime";
35002
35002
  function parseSetupNodeMode(value) {
@@ -35024,6 +35024,7 @@ function resolveNonInteractiveConfig(flags) {
35024
35024
  nodeMode,
35025
35025
  apiPort: flags.apiPort ?? "127.0.0.1:3800",
35026
35026
  indexerPort: "127.0.0.1:3700",
35027
+ postgresPort: "127.0.0.1:5432",
35027
35028
  dir,
35028
35029
  against: flags.against,
35029
35030
  skipBootstrap: !!flags.skipBootstrap,
@@ -35047,6 +35048,44 @@ async function checkDocker() {
35047
35048
  const probe = spawnSync5("docker", ["info"], { stdio: "ignore" });
35048
35049
  return !probe.error && probe.status === 0;
35049
35050
  }
35051
+ function isPortFree(host, port) {
35052
+ return new Promise((resolvePromise) => {
35053
+ const srv = createServer();
35054
+ srv.once("error", () => resolvePromise(false));
35055
+ srv.once("listening", () => srv.close(() => resolvePromise(true)));
35056
+ srv.listen(port, host);
35057
+ });
35058
+ }
35059
+ function parsePublishSpec(spec) {
35060
+ const idx = spec.lastIndexOf(":");
35061
+ if (idx === -1)
35062
+ return { host: "127.0.0.1", port: Number(spec) };
35063
+ return { host: spec.slice(0, idx), port: Number(spec.slice(idx + 1)) };
35064
+ }
35065
+ function dockerPublishedHostPorts() {
35066
+ const probe = spawnSync5("docker", ["ps", "--format", "{{.Ports}}"], {
35067
+ encoding: "utf8"
35068
+ });
35069
+ const ports = new Set;
35070
+ if (probe.error || probe.status !== 0 || !probe.stdout)
35071
+ return ports;
35072
+ for (const match of probe.stdout.matchAll(/:(\d+)->/g)) {
35073
+ ports.add(Number(match[1]));
35074
+ }
35075
+ return ports;
35076
+ }
35077
+ async function resolveAvailablePublishSpec(spec, claimedByDocker = new Set, maxAttempts = 20) {
35078
+ const { host, port } = parsePublishSpec(spec);
35079
+ for (let attempt = 0;attempt < maxAttempts; attempt++) {
35080
+ const candidate = port + attempt;
35081
+ if (claimedByDocker.has(candidate))
35082
+ continue;
35083
+ if (await isPortFree(host, candidate)) {
35084
+ return { spec: `${host}:${candidate}`, remapped: attempt > 0 };
35085
+ }
35086
+ }
35087
+ return { spec, remapped: false };
35088
+ }
35050
35089
  function randomHex(bytes) {
35051
35090
  return randomBytes4(bytes).toString("hex");
35052
35091
  }
@@ -35095,7 +35134,7 @@ function renderSetupEnv(config, secrets) {
35095
35134
  "POSTGRES_USER=secondlayer",
35096
35135
  `POSTGRES_PASSWORD=${secrets.postgresPassword}`,
35097
35136
  "POSTGRES_DB=secondlayer",
35098
- "POSTGRES_PORT=127.0.0.1:5432",
35137
+ `POSTGRES_PORT=${config.postgresPort}`,
35099
35138
  "# The instance credential. The API validates bearer tokens against it,",
35100
35139
  "# and the CLI/SDK/MCP read it first when authenticating.",
35101
35140
  `INSTANCE_TOKEN=${i3.INSTANCE_TOKEN}`,
@@ -35255,7 +35294,8 @@ function buildSuccessSummary(config, secrets) {
35255
35294
  return lines2.join(`
35256
35295
  `);
35257
35296
  }
35258
- async function runSetup(config, emit2) {
35297
+ async function runSetup(initialConfig, emit2) {
35298
+ let config = initialConfig;
35259
35299
  emit2({ type: "step-start", step: "preflight" });
35260
35300
  if (!await checkDocker()) {
35261
35301
  emit2({
@@ -35265,6 +35305,31 @@ async function runSetup(config, emit2) {
35265
35305
  });
35266
35306
  return { ok: false, config };
35267
35307
  }
35308
+ const claimedByDocker = dockerPublishedHostPorts();
35309
+ const ports = {
35310
+ api: await resolveAvailablePublishSpec(config.apiPort, claimedByDocker),
35311
+ indexer: await resolveAvailablePublishSpec(config.indexerPort, claimedByDocker),
35312
+ postgres: await resolveAvailablePublishSpec(config.postgresPort, claimedByDocker)
35313
+ };
35314
+ config = {
35315
+ ...config,
35316
+ apiPort: ports.api.spec,
35317
+ indexerPort: ports.indexer.spec,
35318
+ postgresPort: ports.postgres.spec
35319
+ };
35320
+ for (const [label, result] of [
35321
+ ["api", ports.api],
35322
+ ["indexer", ports.indexer],
35323
+ ["postgres", ports.postgres]
35324
+ ]) {
35325
+ if (result.remapped) {
35326
+ emit2({
35327
+ type: "step-log",
35328
+ step: "preflight",
35329
+ line: `${label} port was already in use locally, using ${result.spec} instead`
35330
+ });
35331
+ }
35332
+ }
35268
35333
  const floors = guardrailPreview(config.nodeMode, config.network);
35269
35334
  emit2({
35270
35335
  type: "step-done",
@@ -35512,6 +35577,7 @@ function App({ flags }) {
35512
35577
  nodeMode,
35513
35578
  apiPort: flags.apiPort ?? "127.0.0.1:3800",
35514
35579
  indexerPort: "127.0.0.1:3700",
35580
+ postgresPort: "127.0.0.1:5432",
35515
35581
  dir: flags.dir ?? process.cwd(),
35516
35582
  against: skipBootstrap ? undefined : against,
35517
35583
  skipBootstrap,
@@ -36032,7 +36098,7 @@ var {
36032
36098
  // package.json
36033
36099
  var package_default = {
36034
36100
  name: "@secondlayer/cli",
36035
- version: "13.0.0",
36101
+ version: "13.0.2",
36036
36102
  description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
36037
36103
  repository: {
36038
36104
  type: "git",
@@ -36077,7 +36143,7 @@ var package_default = {
36077
36143
  "@opentui/react": "^0.5.3",
36078
36144
  "@secondlayer/bundler": "^0.5.1",
36079
36145
  "@secondlayer/scaffold": "^1.5.4",
36080
- "@secondlayer/sdk": "^9.0.0",
36146
+ "@secondlayer/sdk": "^9.0.1",
36081
36147
  "@secondlayer/shared": "^11.0.0",
36082
36148
  "@secondlayer/stacks": "^4.0.0",
36083
36149
  "@secondlayer/subgraphs": "^4.0.4",
@@ -41430,6 +41496,7 @@ async function promptSetupConfig(flags) {
41430
41496
  nodeMode,
41431
41497
  apiPort: flags.apiPort ?? "127.0.0.1:3800",
41432
41498
  indexerPort: "127.0.0.1:3700",
41499
+ postgresPort: "127.0.0.1:5432",
41433
41500
  dir: flags.dir ?? process.cwd(),
41434
41501
  against: skipBootstrap ? undefined : against,
41435
41502
  skipBootstrap,
@@ -41650,5 +41717,5 @@ program.commandsGroup("Archive:");
41650
41717
  registerCreditsCommand(program);
41651
41718
  program.parse();
41652
41719
 
41653
- //# debugId=9A62CC1B91BCEC2C64756E2164756E21
41720
+ //# debugId=BA4FE359F27252EE64756E2164756E21
41654
41721
  //# sourceMappingURL=cli.js.map