@secondlayer/cli 10.1.0 → 10.2.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.
package/README.md CHANGED
@@ -69,6 +69,7 @@ No account. Writes `.env.local`, restores history, prints the Stacks observer st
69
69
  | Command | What it does |
70
70
  |---|---|
71
71
  | `sl init [--network mainnet\|testnet\|devnet] [--api-url <url>] [--force]` | Write `.env.local` (token, secrets key, webhook signing key). Idempotent |
72
+ | `sl start [--print]` | Validate one-box config and print `docker compose up` |
72
73
  | `sl bootstrap --against <manifest> [--to-block <n>] [--public-key <pem>] [-y] [--json]` | Restore chain history from a verified archive into an empty database. Exit `0` restored, `1` diverged, `2` refused |
73
74
  | `sl observer [--mode indexer\|signer-shared] [--endpoint host:port] [--recovery journal\|archive] [--network …]` | Print the `[[events_observer]]` stanza. Signer-shared requires `--recovery` |
74
75
  | `sl verify [all\|raw\|decode:<name>\|subgraph:<name>] --against <manifest> [--quick\|--deep\|--anchor]` | Compare local data to a signed archive. Default target `raw`. Exit `0` clean, `1` diverged, `2` unanchored |
package/dist/cli.js CHANGED
@@ -2551,7 +2551,7 @@ var init_session = __esm(() => {
2551
2551
 
2552
2552
  // src/lib/resolve-auth.ts
2553
2553
  function resolveApiUrl() {
2554
- return process.env.SL_API_URL ?? process.env.SL_PLATFORM_API_URL ?? DEFAULT_API_URL;
2554
+ return (process.env.SL_API_URL ?? process.env.SL_PLATFORM_API_URL ?? LOCAL_API_URL).replace(/\/+$/, "");
2555
2555
  }
2556
2556
  function resolveEnvKey() {
2557
2557
  return process.env.SL_API_KEY;
@@ -2574,9 +2574,13 @@ async function resolveAuth() {
2574
2574
  return { apiUrl, ephemeralKey: session.token, fromEnv: false };
2575
2575
  }
2576
2576
  function isOssMode() {
2577
- return !!process.env.SL_API_URL;
2577
+ try {
2578
+ return new URL(resolveApiUrl()).hostname !== "api.secondlayer.tools";
2579
+ } catch {
2580
+ return true;
2581
+ }
2578
2582
  }
2579
- var DEFAULT_API_URL = "https://api.secondlayer.tools";
2583
+ var LOCAL_API_URL = "http://127.0.0.1:3800";
2580
2584
  var init_resolve_auth = __esm(() => {
2581
2585
  init_session();
2582
2586
  });
@@ -30902,7 +30906,7 @@ import { resolve as resolve4 } from "node:path";
30902
30906
  import { Index as Index2 } from "@secondlayer/sdk";
30903
30907
  function client() {
30904
30908
  return new Index2({
30905
- baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL,
30909
+ baseUrl: resolveApiUrl(),
30906
30910
  apiKey: resolveEnvKey()
30907
30911
  });
30908
30912
  }
@@ -30910,7 +30914,7 @@ function fail(action2, err) {
30910
30914
  const message = err instanceof Error ? err.message : String(err);
30911
30915
  error(`Failed to ${action2}: ${message}`);
30912
30916
  if (/\b403\b/.test(message) || /forbidden/i.test(message)) {
30913
- note("The Index API requires a Build+ tier key (free-tier keys are rejected).");
30917
+ note("The local API refused this read. Check INSTANCE_TOKEN / SL_API_KEY.");
30914
30918
  }
30915
30919
  process.exit(1);
30916
30920
  }
@@ -31101,7 +31105,6 @@ async function runIndexCodegen(o3) {
31101
31105
  process.exit(1);
31102
31106
  }
31103
31107
  }
31104
- var DEFAULT_BASE_URL = "https://api.secondlayer.tools";
31105
31108
  var init_index_api = __esm(() => {
31106
31109
  init_fs();
31107
31110
  init_output();
@@ -34784,7 +34787,7 @@ init_esm();
34784
34787
  // package.json
34785
34788
  var package_default = {
34786
34789
  name: "@secondlayer/cli",
34787
- version: "10.1.0",
34790
+ version: "10.2.0",
34788
34791
  repository: {
34789
34792
  type: "git",
34790
34793
  url: "git+https://github.com/ryanwaits/secondlayer.git",
@@ -34827,8 +34830,8 @@ var package_default = {
34827
34830
  "@inquirer/prompts": "^8.2.0",
34828
34831
  "@secondlayer/bundler": "^0.5.0",
34829
34832
  "@secondlayer/scaffold": "^1.5.1",
34830
- "@secondlayer/sdk": "^6.51.0",
34831
- "@secondlayer/shared": "^7.10.0",
34833
+ "@secondlayer/sdk": "^6.54.0",
34834
+ "@secondlayer/shared": "^7.11.0",
34832
34835
  "@secondlayer/stacks": "^3.3.1",
34833
34836
  "@secondlayer/subgraphs": "^3.26.4",
34834
34837
  esbuild: "^0.27.4",
@@ -35383,12 +35386,11 @@ async function validateDatabaseConnection(url) {
35383
35386
  init_output();
35384
35387
  init_resolve_auth();
35385
35388
  import { SecondLayer as SecondLayer2 } from "@secondlayer/sdk";
35386
- var DEFAULT_BASE_URL2 = "https://api.secondlayer.tools";
35387
35389
  function registerContextCommand(program2) {
35388
35390
  program2.command("context").description("Print an agent orientation snapshot: account, live Streams/Index tips, your subgraphs/subscriptions, and in-flight reindex operations").option("--json", "Print as JSON (default)").action(async (o3) => {
35389
35391
  try {
35390
35392
  const sl = new SecondLayer2({
35391
- baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL2,
35393
+ baseUrl: resolveApiUrl(),
35392
35394
  apiKey: resolveEnvKey()
35393
35395
  });
35394
35396
  const snapshot = await sl.context();
@@ -35411,7 +35413,8 @@ function registerStatusCommand(program2) {
35411
35413
  program2.command("status").description("Show system status").option("--json", "Output as JSON").action(async (options3) => {
35412
35414
  const config = await loadConfig2();
35413
35415
  try {
35414
- const status = await httpPlatform("/status");
35416
+ const local = process.env.INSTANCE_MODE === "oss" || (process.env.SL_API_URL ?? "").includes("127.0.0.1") || (process.env.SL_API_URL ?? "").includes("localhost");
35417
+ const status = local ? await httpPlatform("/public/status") : await httpPlatform("/status");
35415
35418
  output({
35416
35419
  json: options3.json,
35417
35420
  data: status,
@@ -37065,20 +37068,11 @@ import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
37065
37068
  import { dirname as dirname9, join as join10 } from "node:path";
37066
37069
  import { createStreamsClient } from "@secondlayer/sdk";
37067
37070
  import { STREAMS_EVENT_TYPES } from "@secondlayer/shared";
37068
- var DEFAULT_BASE_URL3 = "https://api.secondlayer.tools";
37069
37071
  var VALID_TYPES = STREAMS_EVENT_TYPES;
37070
- function readApiKey() {
37071
- const key = resolveEnvKey();
37072
- if (!key) {
37073
- error("No API key set. Export SL_API_KEY (issue one at https://www.secondlayer.tools/platform/api-keys).");
37074
- process.exit(1);
37075
- }
37076
- return key;
37077
- }
37078
37072
  function client2() {
37079
37073
  return createStreamsClient({
37080
- baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL3,
37081
- apiKey: readApiKey()
37074
+ baseUrl: resolveApiUrl(),
37075
+ apiKey: resolveEnvKey() ?? ""
37082
37076
  });
37083
37077
  }
37084
37078
  function dumpsClient(dumpsUrl) {
@@ -37088,7 +37082,7 @@ function dumpsClient(dumpsUrl) {
37088
37082
  process.exit(1);
37089
37083
  }
37090
37084
  return createStreamsClient({
37091
- baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL3,
37085
+ baseUrl: resolveApiUrl(),
37092
37086
  apiKey: resolveEnvKey() ?? "",
37093
37087
  dumpsBaseUrl
37094
37088
  });
@@ -37131,7 +37125,7 @@ function parseHeight(value, name) {
37131
37125
  return n3;
37132
37126
  }
37133
37127
  function registerStreamsCommand(program2) {
37134
- const streams = program2.command("streams").description("Read raw chain events from Streams (requires SL_API_KEY)");
37128
+ const streams = program2.command("streams").description("Read raw chain events from Streams");
37135
37129
  streams.command("tip").description("Print current canonical tip").option("--json", "Output as JSON (streams always emits JSON)").action(async () => {
37136
37130
  try {
37137
37131
  const tip = await client2().tip();
@@ -37285,7 +37279,6 @@ init_index_api();
37285
37279
  init_output();
37286
37280
  init_resolve_auth();
37287
37281
  import { SecondLayer as SecondLayer4 } from "@secondlayer/sdk";
37288
- var DEFAULT_BASE_URL4 = "https://api.secondlayer.tools";
37289
37282
  function registerKeysCommand(program2) {
37290
37283
  const keys = program2.command("keys", { hidden: true }).description("Manage API keys");
37291
37284
  keys.command("create").description("Mint a scoped streams/index read key (requires an account-level key)").option("--product <product>", "Key scope: streams or index", "streams").option("--name <name>", "Optional label for the key").option("--json", "Print the full response as JSON").action(async (o3) => {
@@ -37300,7 +37293,7 @@ function registerKeysCommand(program2) {
37300
37293
  }
37301
37294
  try {
37302
37295
  const sl = new SecondLayer4({
37303
- baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL4,
37296
+ baseUrl: resolveApiUrl(),
37304
37297
  apiKey
37305
37298
  });
37306
37299
  const minted = await sl.apiKeys.create({
@@ -37481,7 +37474,7 @@ function registerDoctorCommand(program2) {
37481
37474
  }
37482
37475
  async function runHostedDoctor(jsonOutput) {
37483
37476
  const config = await loadConfig2();
37484
- const apiUrl = process.env.SL_PLATFORM_API_URL ?? "https://api.secondlayer.tools";
37477
+ const apiUrl = process.env.SL_PLATFORM_API_URL ?? process.env.SL_API_URL ?? "http://127.0.0.1:3800";
37485
37478
  const issues = [];
37486
37479
  const results = { network: config.network, apiUrl };
37487
37480
  let apiHealthy = false;
@@ -39801,6 +39794,39 @@ function registerObserverCommand(program2) {
39801
39794
  writeData(renderObserverStanza({ mode, endpoint, network, recovery }));
39802
39795
  });
39803
39796
  }
39797
+ // src/commands/start.ts
39798
+ init_output();
39799
+ import { parseRuntimeConfig } from "@secondlayer/shared/runtime";
39800
+ function registerStartCommand(program2) {
39801
+ program2.command("start").description("Validate one-box runtime config and print the compose command").option("--print", "print the compose invocation only").action((opts) => {
39802
+ const parsed = parseRuntimeConfig({
39803
+ NETWORK: process.env.NETWORK ?? process.env.STACKS_NETWORK,
39804
+ DATABASE_URL: process.env.DATABASE_URL,
39805
+ NODE_MODE: process.env.NODE_MODE ?? "external",
39806
+ DATA_DIR: process.env.DATA_DIR ?? "/data",
39807
+ API_PORT: process.env.API_PORT ?? "3800",
39808
+ INDEXER_PORT: process.env.INDEXER_PORT ?? "3700",
39809
+ STACKS_NODE_RPC_URL: process.env.STACKS_NODE_RPC_URL,
39810
+ LISTEN_HOST: process.env.LISTEN_HOST,
39811
+ LOG_LEVEL: process.env.LOG_LEVEL,
39812
+ BITCOIN_RPC_PASSWORD: process.env.BITCOIN_RPC_PASSWORD
39813
+ });
39814
+ if (!parsed.ok) {
39815
+ printError(parsed.errors.join("; "), {
39816
+ hint: "Set NETWORK, DATABASE_URL, and NODE_MODE (external | stacks | full)."
39817
+ });
39818
+ process.exit(1);
39819
+ }
39820
+ const extra = parsed.config.NODE_MODE === "full" ? " --profile full-node" : parsed.config.NODE_MODE === "stacks" ? " --profile stacks-node" : "";
39821
+ const cmd = `docker compose -f docker/oss/docker-compose.yml${extra} up -d`;
39822
+ if (opts.print) {
39823
+ console.log(cmd);
39824
+ return;
39825
+ }
39826
+ success(`config ok (${parsed.config.NETWORK}, ${parsed.config.NODE_MODE})`);
39827
+ console.log(cmd);
39828
+ });
39829
+ }
39804
39830
  // src/cli.ts
39805
39831
  var { version } = package_default;
39806
39832
  program.name("secondlayer").alias("sl").description("Secondlayer CLI — self-hosted Stacks data runtime").version(version).option("--network <network>", "Override network (local, testnet, mainnet)").option("--api-key <key>", "API credential (overrides SL_API_KEY)").option("--api-url <url>", "API endpoint (overrides SL_API_URL)").showSuggestionAfterError(true).showHelpAfterError("(run `sl --help` to see available commands)");
@@ -39824,6 +39850,7 @@ program.commandsGroup("Getting started:");
39824
39850
  registerInitCommand(program);
39825
39851
  registerBootstrapCommand(program);
39826
39852
  registerObserverCommand(program);
39853
+ registerStartCommand(program);
39827
39854
  registerLoginCommand(program);
39828
39855
  registerLogoutCommand(program);
39829
39856
  registerWhoamiCommand(program);
@@ -39863,5 +39890,5 @@ registerAccountCommand(program);
39863
39890
  registerKeysCommand(program);
39864
39891
  program.parse();
39865
39892
 
39866
- //# debugId=43937D51F562F20264756E2164756E21
39893
+ //# debugId=E414197C37677A7F64756E2164756E21
39867
39894
  //# sourceMappingURL=cli.js.map