@settlemint/dalp-cli 3.1.32-main.42884423762 → 3.1.32-main.42904215559

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@settlemint/dalp-cli",
3
- "version": "3.1.32-main.42884423762",
3
+ "version": "3.1.32-main.42904215559",
4
4
  "private": false,
5
5
  "description": "CLI for the Digital Asset Lifecycle Platform — manage tokens, identities, compliance, and more from the command line.",
6
6
  "homepage": "https://settlemint.com",
@@ -50,14 +50,14 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@modelcontextprotocol/server": "2.4.0",
53
- "@settlemint/dalp-sdk": "3.1.32-main.42884423762",
53
+ "@settlemint/dalp-sdk": "3.1.32-main.42904215559",
54
54
  "incur": "0.7.1",
55
55
  "zod": "4.6.7"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@arethetypeswrong/cli": "0.18.5",
59
- "@testkit/effect-bun-test": "3.1.32-main.42884423762",
60
- "@tools/typescript-config": "3.1.32-main.42884423762",
59
+ "@testkit/effect-bun-test": "3.1.32-main.42904215559",
60
+ "@tools/typescript-config": "3.1.32-main.42904215559",
61
61
  "@types/bun": "1.4.4",
62
62
  "publint": "0.3.25"
63
63
  },
@@ -259,6 +259,30 @@ export function buildErrorCta(input: {
259
259
  };
260
260
  }
261
261
 
262
+ function formatCtaCommand(cliName: string, entry: CliCtaCommand): { command: string; description?: string } {
263
+ if (typeof entry === "string") {
264
+ return { command: `${cliName} ${entry}` };
265
+ }
266
+ const prefixed = entry.command === cliName || entry.command.startsWith(`${cliName} `);
267
+ let command = prefixed ? entry.command : `${cliName} ${entry.command}`;
268
+ for (const [key, value] of Object.entries(entry.args ?? {})) {
269
+ command += value === true ? ` <${key}>` : ` ${String(value)}`;
270
+ }
271
+ for (const [key, value] of Object.entries(entry.options ?? {})) {
272
+ command += value === true ? ` --${key} <${key}>` : ` --${key} ${String(value)}`;
273
+ }
274
+ return entry.description === undefined ? { command } : { command, description: entry.description };
275
+ }
276
+
277
+ export function renderCtaText(cliName: string, block: CliCtaBlock): string {
278
+ const commands = block.commands.map((entry) => formatCtaCommand(cliName, entry));
279
+ const width = Math.max(0, ...commands.map((entry) => entry.command.length));
280
+ const lines = commands.map((entry) =>
281
+ entry.description === undefined ? ` ${entry.command}` : ` ${entry.command.padEnd(width)} # ${entry.description}`
282
+ );
283
+ return [block.description, ...lines].join("\n");
284
+ }
285
+
262
286
  export function buildSuccessCtaFromResult(result: unknown): CliCtaBlock | undefined {
263
287
  const links = extractResourceLinks(result);
264
288
  const commands = commandsFromLinks(links);
@@ -1,6 +1,6 @@
1
1
  import type { DalpClient } from "@settlemint/dalp-sdk";
2
2
  import { Cli, z } from "incur";
3
- import { buildErrorCta, buildSuccessCtaFromResult, type CliCtaBlock } from "./cli-cta.ts";
3
+ import { buildErrorCta, buildSuccessCtaFromResult, renderCtaText, type CliCtaBlock } from "./cli-cta.ts";
4
4
  import { createCliStatus } from "./cli-status.ts";
5
5
  import { renderSdkErrorForCli } from "./errors.ts";
6
6
  import { INDEX_COMMAND } from "@settlemint/dalp-sdk/routes";
@@ -40,6 +40,14 @@ function withSuccessCta<T extends object>(context: T, data: unknown): unknown {
40
40
 
41
41
  export type ApiBag = LooseBag;
42
42
 
43
+ interface CliRefusal {
44
+ readonly code: string;
45
+ readonly message: string;
46
+ readonly retryable?: boolean;
47
+ readonly exitCode?: number;
48
+ readonly cta?: CliCtaBlock;
49
+ }
50
+
43
51
  interface McpAnnotations {
44
52
  readonly readOnlyHint: boolean;
45
53
  readonly destructiveHint?: boolean;
@@ -55,13 +63,8 @@ export interface CommandTreeNode {
55
63
  operations: Array<OperationDescriptor>;
56
64
  }
57
65
 
58
- const isSseResult = (value: unknown): value is { readonly stream: AsyncIterable<unknown> } => {
59
- if (typeof value !== "object" || value === null || !("stream" in value)) {
60
- return false;
61
- }
62
- const stream = Reflect.get(value, "stream");
63
- return typeof stream === "object" && stream !== null && Symbol.asyncIterator in stream;
64
- };
66
+ const isSseResult = (value: unknown): value is AsyncIterable<unknown> =>
67
+ typeof value === "object" && value !== null && Symbol.asyncIterator in value;
65
68
 
66
69
  function pickPrimaryOp(ops: ReadonlyArray<OperationDescriptor>): OperationDescriptor {
67
70
  return [...ops].sort((left, right) => right.surface.pathParams.length - left.surface.pathParams.length)[0]!;
@@ -274,17 +277,18 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
274
277
  options?: unknown;
275
278
  request?: Request;
276
279
  agent?: boolean;
277
- error: (error: {
278
- code: string;
279
- message: string;
280
- retryable?: boolean;
281
- exitCode?: number;
282
- cta?: CliCtaBlock;
283
- }) => unknown;
280
+ displayName?: string;
281
+ error: (error: { code: string; message: string; retryable?: boolean; exitCode?: number }) => unknown;
284
282
  }) {
283
+ const refuseWithGuidanceInMessage = ({ cta, ...error }: CliRefusal) =>
284
+ c.error(
285
+ cta === undefined
286
+ ? error
287
+ : { ...error, message: `${error.message}\n\n${renderCtaText(c.displayName ?? "dalp", cta)}` }
288
+ );
285
289
  const { client } = c.var;
286
290
  if (client === undefined) {
287
- return c.error({
291
+ return refuseWithGuidanceInMessage({
288
292
  code: "NOT_AUTHENTICATED",
289
293
  message: "Not logged in. Run 'dalp login' to authenticate.",
290
294
  retryable: true,
@@ -325,7 +329,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
325
329
  if (failedEvent !== undefined) {
326
330
  yield failedEvent;
327
331
  }
328
- return c.error({
332
+ return refuseWithGuidanceInMessage({
329
333
  code: "kit.cli.MISSING_PATH",
330
334
  message: `Operation ${descriptor.name} requires path parameters.`,
331
335
  retryable: true,
@@ -347,7 +351,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
347
351
  yield failedEvent;
348
352
  }
349
353
  const message = error instanceof Error ? error.message : "Invalid path parameters";
350
- return c.error({
354
+ return refuseWithGuidanceInMessage({
351
355
  code: "kit.cli.INVALID_PATH",
352
356
  message,
353
357
  retryable: true,
@@ -375,7 +379,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
375
379
  yield failedEvent;
376
380
  }
377
381
  const message = error instanceof Error ? error.message : "Invalid query parameters";
378
- return c.error({
382
+ return refuseWithGuidanceInMessage({
379
383
  code: "kit.cli.INVALID_QUERY",
380
384
  message,
381
385
  retryable: true,
@@ -401,7 +405,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
401
405
  yield failedEvent;
402
406
  }
403
407
  const message = error instanceof Error ? error.message : "Invalid request body";
404
- return c.error({
408
+ return refuseWithGuidanceInMessage({
405
409
  code: "kit.cli.INVALID_BODY",
406
410
  message,
407
411
  retryable: true,
@@ -425,7 +429,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
425
429
  }
426
430
 
427
431
  const result = await runCommand(
428
- c,
432
+ { error: refuseWithGuidanceInMessage },
429
433
  invokeOperation(
430
434
  descriptor,
431
435
  client,
@@ -464,7 +468,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
464
468
  yield streamEvent;
465
469
  }
466
470
  try {
467
- for await (const chunk of result.stream) {
471
+ for await (const chunk of result) {
468
472
  yield chunk;
469
473
  }
470
474
  } catch (streamError) {
@@ -481,7 +485,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
481
485
  if (failed !== undefined) {
482
486
  yield failed;
483
487
  }
484
- return c.error({
488
+ return refuseWithGuidanceInMessage({
485
489
  ...rendered,
486
490
  exitCode: 1,
487
491
  });
@@ -518,7 +522,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
518
522
  if (failed !== undefined) {
519
523
  yield failed;
520
524
  }
521
- return c.error({
525
+ return refuseWithGuidanceInMessage({
522
526
  ...rendered,
523
527
  exitCode: 1,
524
528
  });