@secondlayer/cli 8.7.1 → 8.9.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
@@ -104,9 +104,8 @@ scoped reads and cannot mint (403). Minted keys inherit your plan's tier.
104
104
 
105
105
  | Command | What it does |
106
106
  |---|---|
107
- | `sl datasets list` / `query <dataset> [--filter k=v] [--cursor] [--limit] [--json]` | Foundation Datasets (sBTC, BNS, PoX-4, STX transfers). Public — no key |
108
- | `sl index ft-transfers` / `nft-transfers` / `events --event-type <t>` / `contract-calls` | Decoded L2 layer. Anonymous reads OK; free-tier keys rejected (Build+ for keyed) |
109
- | `sl streams tip` / `events` / `consume` / `reorgs` / `canonical <h>` / `pull` | Raw L1 event firehose. **Requires `SL_API_KEY`** |
107
+ | `sl index ft-transfers` / `nft-transfers` / `events --event-type <t>` / `contract-calls` | Decoded Index layer. Anonymous reads OK; free-tier keys rejected (Build+ for keyed) |
108
+ | `sl streams tip` / `events` / `consume` / `reorgs` / `canonical <h>` / `pull` | Raw chain event firehose. **Requires `SL_API_KEY`** |
110
109
 
111
110
  Reads emit JSON to stdout (`--json` accepted across all read commands); `-o/--output` is a file path, not a format.
112
111
 
@@ -136,16 +135,6 @@ trait — via the SDK, REST, or MCP with a `triggers` array. Every other
136
135
  `sl subscriptions` command (list/get/update/pause/resume/delete/doctor/test/
137
136
  deliveries/...) operates on both kinds.
138
137
 
139
- ### Local dev & OSS
140
-
141
- | Command | What it does |
142
- |---|---|
143
- | `sl local up [--devnet]` / `sl local down [--devnet]` | Start/stop the full local stack (Stacks node + dev services), or a Clarinet devnet |
144
- | `sl local start/stop/restart/status/logs` | Manage just the local dev services |
145
- | `sl local node setup/start/stop/...` | Manage the local Stacks node |
146
- | `sl local db blocks/txs/events/gaps/truncate/resync` | Inspect the local source DB |
147
- | `sl devnet connect/down/status/logs` | Clarinet devnet integration |
148
-
149
138
  ### Other
150
139
 
151
140
  | Command | What it does |
@@ -220,6 +209,17 @@ await token.write.transfer({ amount: 100n, recipient: "SP..." })
220
209
  const supply = await token.vars.totalSupply.get()
221
210
  ```
222
211
 
212
+ ## Frozen commands
213
+
214
+ Local-dev periphery: still functional, hidden from `sl --help`, no further
215
+ investment — may be removed in a future major. The hosted dev loop
216
+ (`sl subgraphs create/deploy`) is the supported path.
217
+
218
+ - `sl local up/down/start/stop/restart/status/logs` — local stack + dev services
219
+ - `sl local node ...` — local Stacks node management
220
+ - `sl local db ...` — local source DB inspection
221
+ - `sl devnet connect/down/status/logs` — Clarinet devnet integration
222
+
223
223
  ## Docs
224
224
 
225
225
  Full reference: https://secondlayer.tools/docs
package/dist/cli.js CHANGED
@@ -31811,7 +31811,7 @@ var {
31811
31811
  // package.json
31812
31812
  var package_default = {
31813
31813
  name: "@secondlayer/cli",
31814
- version: "8.7.1",
31814
+ version: "8.9.0",
31815
31815
  repository: {
31816
31816
  type: "git",
31817
31817
  url: "git+https://github.com/ryanwaits/secondlayer.git",
@@ -31861,10 +31861,10 @@ var package_default = {
31861
31861
  "@inquirer/prompts": "^8.2.0",
31862
31862
  "@secondlayer/bundler": "^0.3.7",
31863
31863
  "@secondlayer/scaffold": "^1.2.0",
31864
- "@secondlayer/sdk": "^6.21.0",
31865
- "@secondlayer/shared": "^6.30.0",
31866
- "@secondlayer/stacks": "^2.5.0",
31867
- "@secondlayer/subgraphs": "^3.11.0",
31864
+ "@secondlayer/sdk": "^6.21.2",
31865
+ "@secondlayer/shared": "^6.31.0",
31866
+ "@secondlayer/stacks": "^2.5.1",
31867
+ "@secondlayer/subgraphs": "^3.12.0",
31868
31868
  "@biomejs/js-api": "^0.7.0",
31869
31869
  "@biomejs/wasm-nodejs": "^1.9.0",
31870
31870
  esbuild: "^0.19.0",
@@ -33847,6 +33847,24 @@ stacks_node_events_observers = [${entry}]
33847
33847
  return { status: exists ? "added" : "created" };
33848
33848
  }
33849
33849
 
33850
+ // src/lib/frozen.ts
33851
+ function markFrozen(cmd) {
33852
+ let warned = false;
33853
+ const warn2 = () => {
33854
+ if (warned)
33855
+ return;
33856
+ warned = true;
33857
+ process.stderr.write(`⚠ \`sl ${cmd.name()}\` is frozen — no further investment; it may be removed in a future major. The hosted dev loop (sl subgraphs create/deploy) is the supported path.
33858
+ `);
33859
+ };
33860
+ cmd.hook("preAction", warn2);
33861
+ cmd.addHelpText("beforeAll", () => {
33862
+ warn2();
33863
+ return "";
33864
+ });
33865
+ return cmd;
33866
+ }
33867
+
33850
33868
  // src/commands/devnet.ts
33851
33869
  init_output();
33852
33870
  var COMPOSE_REL = join6(".secondlayer", "docker-compose.yml");
@@ -33877,7 +33895,7 @@ var SERVICES = [
33877
33895
  "migrate"
33878
33896
  ];
33879
33897
  function registerDevnetCommand(program2) {
33880
- const devnet = program2.command("devnet").description("Run Secondlayer services against a local Clarinet devnet");
33898
+ const devnet = markFrozen(program2.command("devnet", { hidden: true }).description("Run Secondlayer services against a local Clarinet devnet"));
33881
33899
  devnet.command("connect").description("Point your clarinet project's devnet at a local Secondlayer stack and start it").option("--project <dir>", "Clarinet project directory (defaults to the nearest Clarinet.toml)").option("--image-tag <tag>", "Published image tag to run", DEFAULT_IMAGE_TAG).option("--owner <owner>", "ghcr image owner (namespace) to pull from").option("--no-up", "Patch config + write compose without starting docker").action(async (options) => {
33882
33900
  await connect(options);
33883
33901
  });
@@ -34595,7 +34613,7 @@ function sip010Balances(name) {
34595
34613
 
34596
34614
  /**
34597
34615
  * Track SIP-010 token balances per (asset_identifier, holder).
34598
- * Mirrors the shape of the Foundation Datasets sBTC token-events
34616
+ * Mirrors the shape of the curated sBTC token-events view
34599
34617
  * surface — but works for ANY SIP-010 token. Constrain to a single
34600
34618
  * token by adding \`assetIdentifier: "SP...token::token-name"\` to each
34601
34619
  * source filter.
@@ -35157,11 +35175,37 @@ Grant (first deploy only):`);
35157
35175
  ${yellow("This DROPS all rows in that schema, then rebuilds it. Re-deploy after.")}`);
35158
35176
  console.log(dim("(--force destructive rebuild not yet supported — manual DROP required.)"));
35159
35177
  }
35178
+ function formatDuration(seconds) {
35179
+ if (seconds < 90)
35180
+ return `${Math.max(1, Math.round(seconds))}s`;
35181
+ if (seconds < 5400)
35182
+ return `${Math.round(seconds / 60)}m`;
35183
+ return `${(seconds / 3600).toFixed(1)}h`;
35184
+ }
35160
35185
  function formatSubgraphSync(sync) {
35161
35186
  const targetBlock = sync.targetBlock ?? sync.chainTip;
35162
35187
  const totalBlocks = sync.totalBlocks;
35163
35188
  const processedBlocks = sync.processedBlocks;
35164
35189
  const progress = `${(sync.progress * 100).toFixed(1)}%`;
35190
+ if (sync.queue) {
35191
+ const pos = sync.queue.position != null ? `position ~${sync.queue.position}` : "queued";
35192
+ const est = sync.queue.estimatedStartSeconds != null ? `, est. start ~${formatDuration(sync.queue.estimatedStartSeconds)}` : "";
35193
+ const denom = sync.queue.estimatedEvents != null ? ` · ~${sync.queue.estimatedEvents.toLocaleString()} events to sync` : "";
35194
+ return {
35195
+ line: `queued — ${pos}${est}${denom}`,
35196
+ remainingLabel: "Queue",
35197
+ remaining: sync.queue.position != null ? `~${sync.queue.position} ahead` : "N/A"
35198
+ };
35199
+ }
35200
+ if (sync.estimatedEvents != null && sync.estimatedEvents > 0 && sync.processedEvents != null) {
35201
+ const pct = `${(sync.processedEvents / sync.estimatedEvents * 100).toFixed(1)}%`;
35202
+ const eta = sync.etaSeconds != null ? ` · est ${formatDuration(sync.etaSeconds)}` : "";
35203
+ return {
35204
+ line: `${sync.status} — ${pct} of ~${sync.estimatedEvents.toLocaleString()} events${eta}`,
35205
+ remainingLabel: "Events Remaining",
35206
+ remaining: `${Math.max(0, sync.estimatedEvents - sync.processedEvents).toLocaleString()}`
35207
+ };
35208
+ }
35165
35209
  if (sync.status === "reindexing" || sync.mode === "reindex") {
35166
35210
  if (targetBlock <= 0) {
35167
35211
  return {
@@ -35185,7 +35229,7 @@ function formatSubgraphSync(sync) {
35185
35229
  }
35186
35230
  function registerSubgraphsCommand(program2) {
35187
35231
  const subgraphs = program2.command("subgraphs").description("Manage materialized subgraphs");
35188
- subgraphs.command("create <name>").description("Create a new subgraph definition file").option("--template <slug>", `Foundation Dataset starter (one of: ${SUBGRAPH_TEMPLATE_SLUGS.join(", ")})`).addHelpText("after", `
35232
+ subgraphs.command("create <name>").description("Create a new subgraph definition file").option("--template <slug>", `Starter template (one of: ${SUBGRAPH_TEMPLATE_SLUGS.join(", ")})`).addHelpText("after", `
35189
35233
  Examples:
35190
35234
  $ sl subgraphs create my-graph
35191
35235
  $ sl subgraphs create token-balances --template sip-010-balances`).action(async (name, opts) => {
@@ -35274,7 +35318,7 @@ Stopped watching.`);
35274
35318
  });
35275
35319
  await new Promise(() => {});
35276
35320
  });
35277
- subgraphs.command("deploy <file>").alias("update").description("Deploy a subgraph definition file (alias: update — deploy is create-or-update)").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").option("--database-url <url>", "BYO data plane: write the subgraph's schema/rows to your own Postgres. With --dry-run, prints the DDL + grant script and verifies the connection.").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").option("--visibility <visibility>", "Read visibility: public (anon /v1 reads, global name claim) or private (your key only). Defaults: managed → public, BYO → private.").action(async (file, options2) => {
35321
+ subgraphs.command("deploy <file>").alias("update").description("Deploy a subgraph definition file (alias: update — deploy is create-or-update)").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--tip-first", "Go live at chain tip immediately; history backfills in the background (requires order-tolerant handlers — commutative or insert-only writes)").option("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").option("--database-url <url>", "BYO data plane: write the subgraph's schema/rows to your own Postgres. With --dry-run, prints the DDL + grant script and verifies the connection.").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").option("--visibility <visibility>", "Read visibility: public (anon /v1 reads, global name claim) or private (your key only). Defaults: managed → public, BYO → private.").action(async (file, options2) => {
35278
35322
  try {
35279
35323
  const absPath = resolve2(file);
35280
35324
  const config = await loadConfig();
@@ -35303,7 +35347,10 @@ Stopped watching.`);
35303
35347
  info(`Loading subgraph from ${absPath}`);
35304
35348
  const mod = await loadSubgraphWithDepCheck(absPath);
35305
35349
  const def = mod.default ?? mod;
35306
- const effectiveDef = startBlock === undefined ? def : { ...def, startBlock };
35350
+ const effectiveDef = {
35351
+ ...startBlock === undefined ? def : { ...def, startBlock },
35352
+ ...options2.tipFirst ? { backfillMode: "concurrent" } : {}
35353
+ };
35307
35354
  const { validateSubgraphDefinition } = await import("@secondlayer/subgraphs/validate");
35308
35355
  const validated = validateSubgraphDefinition(effectiveDef);
35309
35356
  if (config.network !== "local") {
@@ -35360,6 +35407,9 @@ Stopped watching.`);
35360
35407
  info(` Publish: sl subgraphs publish ${effectiveDef.name} (open anon /v1 reads)`);
35361
35408
  }
35362
35409
  info(` Watch: sl subgraphs status ${effectiveDef.name}`);
35410
+ if (firstTable) {
35411
+ info(` Webhook: sl subscriptions create ${effectiveDef.name}-hook --subgraph ${effectiveDef.name} --table ${firstTable} --url <your-endpoint>`);
35412
+ }
35363
35413
  } catch {}
35364
35414
  };
35365
35415
  if (result.action === "unchanged") {
@@ -36207,7 +36257,7 @@ function emitOne(doc, label, json) {
36207
36257
  });
36208
36258
  }
36209
36259
  function registerIndexCommand(program2) {
36210
- const index = program2.command("index").description("Query the decoded Index layer (L2 events + contract calls)");
36260
+ const index = program2.command("index").description("Query the decoded Index layer (events + contract calls)");
36211
36261
  index.command("codegen").description("Generate a typed schema (Prisma, Kysely, Drizzle, or JSON-Schema) for the Index domain tables — point it at your BYO database mirror").option("--target <orm>", "prisma | kysely | drizzle | json-schema", "kysely").option("--schema <name>", "Postgres schema to qualify table names with").option("--tables <list>", "Comma-separated subset of Index tables (default: all)").option("--env <var>", "Prisma datasource url env var", "DATABASE_URL").option("-o, --output <path>", "Write to a file (defaults to stdout)").action(async (o) => {
36212
36262
  try {
36213
36263
  const target = o.target ?? "kysely";
@@ -37301,7 +37351,7 @@ async function stopStack(options2) {
37301
37351
  }
37302
37352
  }
37303
37353
  function registerLocalCommand(program2) {
37304
- const local = program2.command("local").description("Manage local development environment and Stacks node").hook("preAction", async (_thisCommand, actionCommand) => {
37354
+ const local = markFrozen(program2.command("local", { hidden: true }).description("Manage local development environment and Stacks node")).hook("preAction", async (_thisCommand, actionCommand) => {
37305
37355
  if (actionCommand.name() === "help")
37306
37356
  return;
37307
37357
  await requireLocalNetwork();
@@ -37913,5 +37963,5 @@ registerAccountCommand(program);
37913
37963
  registerKeysCommand(program);
37914
37964
  program.parse();
37915
37965
 
37916
- //# debugId=C4DF51841ACD727C64756E2164756E21
37966
+ //# debugId=C1F218ABB7E9AF8864756E2164756E21
37917
37967
  //# sourceMappingURL=cli.js.map