@stripe/link-cli 0.8.3 → 0.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.
Files changed (3) hide show
  1. package/README.md +13 -0
  2. package/dist/cli.js +1582 -886
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -8835,19 +8835,19 @@ var require_range = __commonJS({
8835
8835
  var replaceCaret = (comp, options) => {
8836
8836
  debug("caret", comp, options);
8837
8837
  const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET];
8838
- const z11 = options.includePrerelease ? "-0" : "";
8838
+ const z13 = options.includePrerelease ? "-0" : "";
8839
8839
  return comp.replace(r, (_, M, m, p, pr) => {
8840
8840
  debug("caret", comp, _, M, m, p, pr);
8841
8841
  let ret;
8842
8842
  if (isX(M)) {
8843
8843
  ret = "";
8844
8844
  } else if (isX(m)) {
8845
- ret = `>=${M}.0.0${z11} <${+M + 1}.0.0-0`;
8845
+ ret = `>=${M}.0.0${z13} <${+M + 1}.0.0-0`;
8846
8846
  } else if (isX(p)) {
8847
8847
  if (M === "0") {
8848
- ret = `>=${M}.${m}.0${z11} <${M}.${+m + 1}.0-0`;
8848
+ ret = `>=${M}.${m}.0${z13} <${M}.${+m + 1}.0-0`;
8849
8849
  } else {
8850
- ret = `>=${M}.${m}.0${z11} <${+M + 1}.0.0-0`;
8850
+ ret = `>=${M}.${m}.0${z13} <${+M + 1}.0.0-0`;
8851
8851
  }
8852
8852
  } else if (pr) {
8853
8853
  debug("replaceCaret pr", pr);
@@ -8864,9 +8864,9 @@ var require_range = __commonJS({
8864
8864
  debug("no pr");
8865
8865
  if (M === "0") {
8866
8866
  if (m === "0") {
8867
- ret = `>=${M}.${m}.${p}${z11} <${M}.${m}.${+p + 1}-0`;
8867
+ ret = `>=${M}.${m}.${p}${z13} <${M}.${m}.${+p + 1}-0`;
8868
8868
  } else {
8869
- ret = `>=${M}.${m}.${p}${z11} <${M}.${+m + 1}.0-0`;
8869
+ ret = `>=${M}.${m}.${p}${z13} <${M}.${+m + 1}.0-0`;
8870
8870
  }
8871
8871
  } else {
8872
8872
  ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`;
@@ -11148,6 +11148,173 @@ function requireFetchImplementation(config) {
11148
11148
  }
11149
11149
  return config.fetch;
11150
11150
  }
11151
+ function isRecord(value) {
11152
+ return value !== null && typeof value === "object" && !Array.isArray(value);
11153
+ }
11154
+ function requireBoolean(value, field) {
11155
+ if (typeof value !== "boolean") {
11156
+ throw new TypeError(`Expected ${field} to be a boolean`);
11157
+ }
11158
+ return value;
11159
+ }
11160
+ function extractErrorMessage(data, rawBody) {
11161
+ if (isRecord(data)) {
11162
+ if (typeof data.error === "string") {
11163
+ return data.error;
11164
+ }
11165
+ if (isRecord(data.error)) {
11166
+ const nested = data.error;
11167
+ if (typeof nested.message === "string") {
11168
+ return nested.message;
11169
+ }
11170
+ if (typeof nested.code === "string") {
11171
+ return nested.code;
11172
+ }
11173
+ }
11174
+ if (typeof data.message === "string") {
11175
+ return data.message;
11176
+ }
11177
+ }
11178
+ return rawBody || "unknown error";
11179
+ }
11180
+ var BaseResource = class {
11181
+ verbose;
11182
+ getAccessToken;
11183
+ fetchImpl;
11184
+ endpoint;
11185
+ logger;
11186
+ constructor(options, endpointPath) {
11187
+ const config = resolveLinkSdkConfig(options);
11188
+ this.verbose = config.verbose;
11189
+ this.getAccessToken = config.getAccessToken;
11190
+ this.fetchImpl = requireFetchImplementation(config);
11191
+ this.endpoint = `${config.apiBaseUrl}${endpointPath}`;
11192
+ this.logger = config.logger;
11193
+ }
11194
+ async rawFetch(opts) {
11195
+ if (this.verbose) {
11196
+ const redactedHeaders = { ...opts.headers };
11197
+ if (redactedHeaders.Authorization)
11198
+ redactedHeaders.Authorization = "Bearer <redacted>";
11199
+ this.logger.debug(`> ${opts.method} ${opts.url}`);
11200
+ this.logger.debug(` Headers: ${JSON.stringify(redactedHeaders)}`);
11201
+ }
11202
+ let response;
11203
+ try {
11204
+ response = await this.fetchImpl(opts.url, {
11205
+ method: opts.method,
11206
+ headers: opts.headers
11207
+ });
11208
+ } catch (error) {
11209
+ throw new LinkTransportError(
11210
+ `Request failed: ${opts.method} ${opts.url}`,
11211
+ { cause: error }
11212
+ );
11213
+ }
11214
+ const rawBody = await response.text();
11215
+ let data = null;
11216
+ try {
11217
+ data = JSON.parse(rawBody);
11218
+ } catch {
11219
+ }
11220
+ if (this.verbose) {
11221
+ this.logger.debug(`< ${response.status} ${response.statusText}`);
11222
+ response.headers.forEach((value, key) => {
11223
+ this.logger.debug(` ${key}: ${value}`);
11224
+ });
11225
+ this.logger.debug(rawBody);
11226
+ }
11227
+ return { status: response.status, data, rawBody };
11228
+ }
11229
+ async apiFetch(opts) {
11230
+ const token = await this.getAccessToken();
11231
+ const authedOpts = {
11232
+ ...opts,
11233
+ headers: {
11234
+ ...opts.headers,
11235
+ Authorization: `Bearer ${token}`
11236
+ }
11237
+ };
11238
+ const res = await this.rawFetch(authedOpts);
11239
+ if (res.status === 401) {
11240
+ const refreshedToken = await this.getAccessToken({ forceRefresh: true });
11241
+ authedOpts.headers.Authorization = `Bearer ${refreshedToken}`;
11242
+ return this.rawFetch(authedOpts);
11243
+ }
11244
+ return res;
11245
+ }
11246
+ throwApiError(operation, status, data, rawBody, cause) {
11247
+ const msg = extractErrorMessage(data, rawBody);
11248
+ throw new LinkApiError(`Failed to ${operation} (${status}): ${msg}`, {
11249
+ status,
11250
+ rawBody,
11251
+ details: data,
11252
+ cause
11253
+ });
11254
+ }
11255
+ };
11256
+ function normalizeBalances(value) {
11257
+ if (!Array.isArray(value)) {
11258
+ throw new TypeError("Expected balances to be an array");
11259
+ }
11260
+ return value.map((item, index) => {
11261
+ if (!isRecord(item)) {
11262
+ throw new TypeError(`Expected balances[${index}] to be an object`);
11263
+ }
11264
+ return item;
11265
+ });
11266
+ }
11267
+ function normalizeBalancesPage(value) {
11268
+ if (!isRecord(value)) {
11269
+ throw new TypeError("Expected response body to be an object");
11270
+ }
11271
+ const { data, has_more, ...rest } = value;
11272
+ const normalized = normalizeBalances(data);
11273
+ return {
11274
+ ...rest,
11275
+ data: normalized,
11276
+ ...has_more !== void 0 ? { has_more: requireBoolean(has_more, "has_more") } : {}
11277
+ };
11278
+ }
11279
+ var BalancesResource = class extends BaseResource {
11280
+ constructor(options = {}) {
11281
+ super(options, "/balances");
11282
+ }
11283
+ buildUrl(params) {
11284
+ const url = new URL(this.endpoint);
11285
+ if (params.limit !== void 0) {
11286
+ url.searchParams.set("limit", String(params.limit));
11287
+ }
11288
+ if (params.starting_after !== void 0) {
11289
+ url.searchParams.set("starting_after", params.starting_after);
11290
+ }
11291
+ if (params.ending_before !== void 0) {
11292
+ url.searchParams.set("ending_before", params.ending_before);
11293
+ }
11294
+ return url.toString();
11295
+ }
11296
+ list(params = {}) {
11297
+ return this.listBalances(params);
11298
+ }
11299
+ async listBalances(params = {}) {
11300
+ const { status, data, rawBody } = await this.apiFetch({
11301
+ method: "GET",
11302
+ url: this.buildUrl(params)
11303
+ });
11304
+ if (status < 200 || status >= 300) {
11305
+ this.throwApiError("list balances", status, data, rawBody);
11306
+ }
11307
+ try {
11308
+ return normalizeBalancesPage(data);
11309
+ } catch (error) {
11310
+ const reason = error instanceof Error ? `: ${error.message}` : "";
11311
+ throw new LinkApiError(
11312
+ `Failed to list balances (${status}): invalid response shape${reason}`,
11313
+ { status, rawBody, details: data, cause: error }
11314
+ );
11315
+ }
11316
+ }
11317
+ };
11151
11318
  var PaymentMethodsResource = class {
11152
11319
  verbose;
11153
11320
  getAccessToken;
@@ -11318,6 +11485,68 @@ var ShippingAddressResource = class {
11318
11485
  return body?.shipping_addresses ?? [];
11319
11486
  }
11320
11487
  };
11488
+ function normalizeSources(value) {
11489
+ if (!Array.isArray(value)) {
11490
+ throw new TypeError("Expected sources to be an array");
11491
+ }
11492
+ return value.map((item, index) => {
11493
+ if (!isRecord(item)) {
11494
+ throw new TypeError(`Expected sources[${index}] to be an object`);
11495
+ }
11496
+ return item;
11497
+ });
11498
+ }
11499
+ function normalizeSourcesPage(value) {
11500
+ if (!isRecord(value)) {
11501
+ throw new TypeError("Expected response body to be an object");
11502
+ }
11503
+ const { data, has_more, ...rest } = value;
11504
+ const normalized = normalizeSources(data);
11505
+ return {
11506
+ ...rest,
11507
+ data: normalized,
11508
+ ...has_more !== void 0 ? { has_more: requireBoolean(has_more, "has_more") } : {}
11509
+ };
11510
+ }
11511
+ var SourcesResource = class extends BaseResource {
11512
+ constructor(options = {}) {
11513
+ super(options, "/sources");
11514
+ }
11515
+ buildUrl(params) {
11516
+ const url = new URL(this.endpoint);
11517
+ if (params.limit !== void 0) {
11518
+ url.searchParams.set("limit", String(params.limit));
11519
+ }
11520
+ if (params.starting_after !== void 0) {
11521
+ url.searchParams.set("starting_after", params.starting_after);
11522
+ }
11523
+ if (params.ending_before !== void 0) {
11524
+ url.searchParams.set("ending_before", params.ending_before);
11525
+ }
11526
+ return url.toString();
11527
+ }
11528
+ list(params = {}) {
11529
+ return this.listSources(params);
11530
+ }
11531
+ async listSources(params = {}) {
11532
+ const { status, data, rawBody } = await this.apiFetch({
11533
+ method: "GET",
11534
+ url: this.buildUrl(params)
11535
+ });
11536
+ if (status < 200 || status >= 300) {
11537
+ this.throwApiError("list sources", status, data, rawBody);
11538
+ }
11539
+ try {
11540
+ return normalizeSourcesPage(data);
11541
+ } catch (error) {
11542
+ const reason = error instanceof Error ? `: ${error.message}` : "";
11543
+ throw new LinkApiError(
11544
+ `Failed to list sources (${status}): invalid response shape${reason}`,
11545
+ { status, rawBody, details: data, cause: error }
11546
+ );
11547
+ }
11548
+ }
11549
+ };
11321
11550
  function normalizeSpendRequest(data) {
11322
11551
  const sr = data;
11323
11552
  if (typeof sr.shared_payment_token === "string") {
@@ -11524,9 +11753,6 @@ var SpendRequestResource = class {
11524
11753
  return normalizeSpendRequest(data);
11525
11754
  }
11526
11755
  };
11527
- function isRecord(value) {
11528
- return value !== null && typeof value === "object" && !Array.isArray(value);
11529
- }
11530
11756
  function requireString(value, field) {
11531
11757
  if (typeof value !== "string") {
11532
11758
  throw new TypeError(`Expected ${field} to be a string`);
@@ -11548,12 +11774,6 @@ function requireNumber(value, field) {
11548
11774
  }
11549
11775
  return value;
11550
11776
  }
11551
- function requireBoolean(value, field) {
11552
- if (typeof value !== "boolean") {
11553
- throw new TypeError(`Expected ${field} to be a boolean`);
11554
- }
11555
- return value;
11556
- }
11557
11777
  function requireTransactionOrigin(value, field) {
11558
11778
  if (value === "link" || value === "external_connection") {
11559
11779
  return value;
@@ -11611,71 +11831,9 @@ function normalizeTransactionsPage(value) {
11611
11831
  ...has_more !== void 0 ? { has_more: requireBoolean(has_more, "has_more") } : {}
11612
11832
  };
11613
11833
  }
11614
- var TransactionsResource = class {
11615
- verbose;
11616
- getAccessToken;
11617
- fetchImpl;
11618
- endpoint;
11619
- logger;
11834
+ var TransactionsResource = class extends BaseResource {
11620
11835
  constructor(options = {}) {
11621
- const config = resolveLinkSdkConfig(options);
11622
- this.verbose = config.verbose;
11623
- this.getAccessToken = config.getAccessToken;
11624
- this.fetchImpl = requireFetchImplementation(config);
11625
- this.endpoint = `${config.apiBaseUrl}/transactions`;
11626
- this.logger = config.logger;
11627
- }
11628
- async rawFetch(opts) {
11629
- if (this.verbose) {
11630
- const redactedHeaders = { ...opts.headers };
11631
- if (redactedHeaders.Authorization)
11632
- redactedHeaders.Authorization = "Bearer <redacted>";
11633
- this.logger.debug(`> ${opts.method} ${opts.url}`);
11634
- this.logger.debug(` Headers: ${JSON.stringify(redactedHeaders)}`);
11635
- }
11636
- let response;
11637
- try {
11638
- response = await this.fetchImpl(opts.url, {
11639
- method: opts.method,
11640
- headers: opts.headers
11641
- });
11642
- } catch (error) {
11643
- throw new LinkTransportError(
11644
- `Request failed: ${opts.method} ${opts.url}`,
11645
- { cause: error }
11646
- );
11647
- }
11648
- const rawBody = await response.text();
11649
- let data = null;
11650
- try {
11651
- data = JSON.parse(rawBody);
11652
- } catch {
11653
- }
11654
- if (this.verbose) {
11655
- this.logger.debug(`< ${response.status} ${response.statusText}`);
11656
- response.headers.forEach((value, key) => {
11657
- this.logger.debug(` ${key}: ${value}`);
11658
- });
11659
- this.logger.debug(rawBody);
11660
- }
11661
- return { status: response.status, data, rawBody };
11662
- }
11663
- async apiFetch(opts) {
11664
- const token = await this.getAccessToken();
11665
- const authedOpts = {
11666
- ...opts,
11667
- headers: {
11668
- ...opts.headers,
11669
- Authorization: `Bearer ${token}`
11670
- }
11671
- };
11672
- const res = await this.rawFetch(authedOpts);
11673
- if (res.status === 401) {
11674
- const refreshedToken = await this.getAccessToken({ forceRefresh: true });
11675
- authedOpts.headers.Authorization = `Bearer ${refreshedToken}`;
11676
- return this.rawFetch(authedOpts);
11677
- }
11678
- return res;
11836
+ super(options, "/transactions");
11679
11837
  }
11680
11838
  buildUrl(params) {
11681
11839
  const url = new URL(this.endpoint);
@@ -11716,19 +11874,14 @@ var TransactionsResource = class {
11716
11874
  url: this.buildUrl(params)
11717
11875
  });
11718
11876
  if (status < 200 || status >= 300) {
11719
- const body = data;
11720
- const msg = body?.error ?? body?.message ?? (rawBody || "unknown error");
11721
- throw new LinkApiError(
11722
- `Failed to list transactions (${status}): ${msg}`,
11723
- { status, rawBody, details: data }
11724
- );
11877
+ this.throwApiError("list transactions", status, data, rawBody);
11725
11878
  }
11726
11879
  try {
11727
11880
  return normalizeTransactionsPage(data);
11728
11881
  } catch (error) {
11729
11882
  const reason = error instanceof Error ? `: ${error.message}` : "";
11730
11883
  throw new LinkApiError(
11731
- `Failed to list transactions (200): invalid response shape${reason}`,
11884
+ `Failed to list transactions (${status}): invalid response shape${reason}`,
11732
11885
  { status, rawBody, details: data, cause: error }
11733
11886
  );
11734
11887
  }
@@ -11826,6 +11979,12 @@ var UserInfoResource = class {
11826
11979
  };
11827
11980
  }
11828
11981
  };
11982
+ var SOURCE_ACTIONS = [
11983
+ "read_balances",
11984
+ "read_external_transactions",
11985
+ "read_link_transactions",
11986
+ "read_source_details"
11987
+ ];
11829
11988
  var REPORT_OUTCOMES = ["success", "blocked", "abandoned"];
11830
11989
  var REPORT_TAGS = [
11831
11990
  "stripe_checkout",
@@ -12053,12 +12212,69 @@ var ReportResource = class {
12053
12212
  };
12054
12213
 
12055
12214
  // src/cli.tsx
12056
- import { Cli as Cli12 } from "incur";
12215
+ import { Cli as Cli14 } from "incur";
12057
12216
 
12058
12217
  // src/commands/auth/index.tsx
12059
12218
  import { Cli } from "incur";
12060
12219
  import { Text as Text4 } from "ink";
12061
12220
 
12221
+ // src/auth/authorization-details.ts
12222
+ var INVALID_AUTHORIZATION_DETAIL_MESSAGE = "authorization-detail must be valid JSON";
12223
+ function dedupe(values) {
12224
+ const seen = /* @__PURE__ */ new Set();
12225
+ const result = [];
12226
+ for (const value of values) {
12227
+ if (seen.has(value)) {
12228
+ continue;
12229
+ }
12230
+ seen.add(value);
12231
+ result.push(value);
12232
+ }
12233
+ return result;
12234
+ }
12235
+ function parseAuthorizationDetails(entries) {
12236
+ const parsed = [];
12237
+ for (const entry of entries ?? []) {
12238
+ try {
12239
+ parsed.push(JSON.parse(entry));
12240
+ } catch {
12241
+ throw new Error(INVALID_AUTHORIZATION_DETAIL_MESSAGE);
12242
+ }
12243
+ }
12244
+ return parsed;
12245
+ }
12246
+ function buildAuthorizationDetails(sourceActions, authorizationDetails) {
12247
+ const details = [];
12248
+ const uniqueSourceActions = dedupe(sourceActions ?? []);
12249
+ if (uniqueSourceActions.length > 0) {
12250
+ details.push({
12251
+ type: "source",
12252
+ actions: uniqueSourceActions
12253
+ });
12254
+ }
12255
+ if (authorizationDetails) {
12256
+ details.push(...authorizationDetails);
12257
+ }
12258
+ return details;
12259
+ }
12260
+
12261
+ // src/auth/scopes.ts
12262
+ var DEFAULT_SCOPES = [
12263
+ "userinfo:read",
12264
+ "payment_methods.agentic"
12265
+ ];
12266
+ var DEFAULT_SCOPE = DEFAULT_SCOPES.join(" ");
12267
+ function parseScopeTokens(scope) {
12268
+ return scope.trim().split(/\s+/).filter(Boolean);
12269
+ }
12270
+ function normalizeScopeInput(scope) {
12271
+ if (scope === void 0) {
12272
+ return void 0;
12273
+ }
12274
+ const normalized = parseScopeTokens(scope);
12275
+ return normalized.length > 0 ? normalized.join(" ") : void 0;
12276
+ }
12277
+
12062
12278
  // src/utils/poll-until.ts
12063
12279
  async function* pollUntil(options) {
12064
12280
  const { fn, isTerminal, interval, timeout, maxAttempts } = options;
@@ -12175,6 +12391,9 @@ import { jsx, jsxs } from "react/jsx-runtime";
12175
12391
  var Login = ({
12176
12392
  authResource,
12177
12393
  clientName,
12394
+ scope,
12395
+ sourceActions,
12396
+ authorizationDetails,
12178
12397
  authStorage: authStorage2 = storage,
12179
12398
  onComplete
12180
12399
  }) => {
@@ -12195,7 +12414,12 @@ var Login = ({
12195
12414
  useEffect(() => {
12196
12415
  const initAuth = async () => {
12197
12416
  try {
12198
- const authRequest = await authResource.initiateDeviceAuth(clientName);
12417
+ const authRequest = await authResource.initiateDeviceAuth({
12418
+ clientName,
12419
+ scope,
12420
+ sourceActions,
12421
+ authorizationDetails
12422
+ });
12199
12423
  setUserCode(authRequest.user_code);
12200
12424
  setVerificationUrl(authRequest.verification_url_complete);
12201
12425
  setDeviceCode(authRequest.device_code);
@@ -12206,7 +12430,7 @@ var Login = ({
12206
12430
  }
12207
12431
  };
12208
12432
  initAuth();
12209
- }, [authResource, clientName]);
12433
+ }, [authResource, authorizationDetails, clientName, scope, sourceActions]);
12210
12434
  useEffect(() => {
12211
12435
  if (status !== "waiting" || !deviceCode) return;
12212
12436
  const startPolling = async () => {
@@ -12245,17 +12469,17 @@ var Login = ({
12245
12469
  if (status === "declined") {
12246
12470
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
12247
12471
  /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2717 Authorization failed" }),
12248
- Object.entries(scopeEligibility).map(([scope, info]) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
12472
+ Object.entries(scopeEligibility).map(([scope2, info]) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
12249
12473
  /* @__PURE__ */ jsxs(Text, { children: [
12250
12474
  /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
12251
- scope,
12475
+ scope2,
12252
12476
  ":"
12253
12477
  ] }),
12254
12478
  " ineligible",
12255
12479
  info.ineligibility_reasons.length > 0 ? ` (${info.ineligibility_reasons.join(", ")})` : ""
12256
12480
  ] }),
12257
12481
  info.description ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: info.description }) : null
12258
- ] }, scope))
12482
+ ] }, scope2))
12259
12483
  ] });
12260
12484
  }
12261
12485
  if (status === "error") {
@@ -12379,10 +12603,18 @@ var Logout = ({
12379
12603
 
12380
12604
  // src/commands/auth/schema.ts
12381
12605
  import { z } from "incur";
12606
+ var SOURCE_ACTIONS_DESCRIPTION = SOURCE_ACTIONS.join(", ");
12382
12607
  var loginOptions = z.object({
12383
12608
  clientName: z.string().default("Link CLI").describe(
12384
12609
  "Agent or app name shown in the Link app when approving the device connection"
12385
12610
  ),
12611
+ scope: z.string().optional().describe(
12612
+ "Optional space-separated Link scopes to request. Quote the value when passing multiple scopes."
12613
+ ),
12614
+ sourceActions: z.array(z.enum(SOURCE_ACTIONS)).default([]).describe(
12615
+ `Source action to request via authorization_details (repeatable). Accepted values: ${SOURCE_ACTIONS_DESCRIPTION}.`
12616
+ ),
12617
+ authorizationDetail: z.array(z.string()).default([]).describe("Freeform authorization_details entry as raw JSON (repeatable)."),
12386
12618
  interval: z.coerce.number().default(0).describe(
12387
12619
  "Poll interval in seconds. When > 0, polls until authenticated or timeout is reached, yielding status on each attempt."
12388
12620
  ),
@@ -12538,10 +12770,28 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
12538
12770
  outputPolicy: "agent-only",
12539
12771
  async *run(c) {
12540
12772
  const clientName = c.options.clientName?.trim();
12773
+ const scope = normalizeScopeInput(c.options.scope);
12774
+ let authorizationDetails;
12541
12775
  if (!clientName || clientName.length === 0) {
12542
12776
  return c.error({
12543
12777
  code: "INVALID_INPUT",
12544
- message: "client-name must be a non-empty string"
12778
+ message: "client-name must be a non-empty string"
12779
+ });
12780
+ }
12781
+ if (c.options.scope !== void 0 && !scope) {
12782
+ return c.error({
12783
+ code: "INVALID_INPUT",
12784
+ message: "scope must be a non-empty string when provided"
12785
+ });
12786
+ }
12787
+ try {
12788
+ authorizationDetails = parseAuthorizationDetails(
12789
+ c.options.authorizationDetail
12790
+ );
12791
+ } catch (error) {
12792
+ return c.error({
12793
+ code: "INVALID_INPUT",
12794
+ message: error.message
12545
12795
  });
12546
12796
  }
12547
12797
  const existingAuth = storage2.getAuth();
@@ -12575,6 +12825,9 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
12575
12825
  {
12576
12826
  authResource,
12577
12827
  clientName,
12828
+ scope,
12829
+ sourceActions: c.options.sourceActions,
12830
+ authorizationDetails,
12578
12831
  authStorage: storage2,
12579
12832
  onComplete: () => {
12580
12833
  }
@@ -12583,7 +12836,12 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
12583
12836
  () => ({ authenticated: true, token_type: "Bearer" })
12584
12837
  );
12585
12838
  }
12586
- const authRequest = await authResource.initiateDeviceAuth(clientName);
12839
+ const authRequest = await authResource.initiateDeviceAuth({
12840
+ clientName,
12841
+ scope,
12842
+ sourceActions: c.options.sourceActions,
12843
+ authorizationDetails
12844
+ });
12587
12845
  storage2.setPendingDeviceAuth({
12588
12846
  device_code: authRequest.device_code,
12589
12847
  interval: authRequest.interval,
@@ -12713,29 +12971,200 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
12713
12971
  return cli2;
12714
12972
  }
12715
12973
 
12974
+ // src/commands/balances/index.tsx
12975
+ import { Cli as Cli2 } from "incur";
12976
+
12977
+ // src/utils/require-auth.ts
12978
+ var NOT_AUTHENTICATED_ERROR = {
12979
+ code: "NOT_AUTHENTICATED",
12980
+ message: 'Not authenticated. Run "link-cli auth login" first.',
12981
+ cta: {
12982
+ commands: [{ command: "auth login", description: "Log in to Link" }]
12983
+ }
12984
+ };
12985
+ function requireAuth(authStorage2, envAccessToken2) {
12986
+ const store = authStorage2 ?? storage;
12987
+ return (c, next) => {
12988
+ if (!envAccessToken2 && !store.isAuthenticated()) {
12989
+ return c.error(NOT_AUTHENTICATED_ERROR);
12990
+ }
12991
+ return next();
12992
+ };
12993
+ }
12994
+ function requireAuthGuard(c, authStorage2, envAccessToken2) {
12995
+ const store = authStorage2 ?? storage;
12996
+ if (!envAccessToken2 && !store.isAuthenticated()) {
12997
+ c.error(NOT_AUTHENTICATED_ERROR);
12998
+ }
12999
+ }
13000
+
13001
+ // src/commands/balances/list.tsx
13002
+ import { Box as Box4, Text as Text5 } from "ink";
13003
+ import Spinner3 from "ink-spinner";
13004
+ import { useCallback as useCallback2 } from "react";
13005
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
13006
+ var COLUMN_GAP = " ";
13007
+ var SOURCE_ID_MIN = 16;
13008
+ var SOURCE_ID_MAX = 48;
13009
+ var TYPE_WIDTH = 12;
13010
+ var CURRENT_WIDTH = 15;
13011
+ var CURRENCY_WIDTH = 8;
13012
+ function truncateCell(value, width) {
13013
+ if (value.length <= width) {
13014
+ return value;
13015
+ }
13016
+ if (width <= 3) {
13017
+ return value.slice(0, width);
13018
+ }
13019
+ return `${value.slice(0, width - 3)}...`;
13020
+ }
13021
+ function formatCell(value, width) {
13022
+ return truncateCell(value, width).padEnd(width);
13023
+ }
13024
+ function formatCents(cents) {
13025
+ const dollars = Math.abs(cents) / 100;
13026
+ const formatted = `$${dollars.toFixed(2)}`;
13027
+ return cents < 0 ? `-${formatted}` : formatted;
13028
+ }
13029
+ function sourceIdWidth(balances) {
13030
+ if (balances.length === 0) return SOURCE_ID_MIN;
13031
+ const maxLen = Math.max(...balances.map((b) => (b.source_id ?? "").length));
13032
+ return Math.min(SOURCE_ID_MAX, Math.max(SOURCE_ID_MIN, maxLen));
13033
+ }
13034
+ var BalancesList = ({
13035
+ resource,
13036
+ params,
13037
+ onComplete
13038
+ }) => {
13039
+ const action = useCallback2(
13040
+ () => resource.listBalances(params),
13041
+ [resource, params]
13042
+ );
13043
+ const { status, data: page, error } = useAsyncAction(action, onComplete);
13044
+ const balances = page?.data ?? [];
13045
+ const nextCursor = page?.has_more && balances.length > 0 ? balances[balances.length - 1].source_id : null;
13046
+ const idWidth = sourceIdWidth(balances);
13047
+ const headerRow = [
13048
+ formatCell("Source ID", idWidth),
13049
+ formatCell("Balance type", TYPE_WIDTH),
13050
+ formatCell("Current balance", CURRENT_WIDTH),
13051
+ formatCell("Currency", CURRENCY_WIDTH)
13052
+ ].join(COLUMN_GAP);
13053
+ const separatorRow = "-".repeat(headerRow.length);
13054
+ const rows = balances.map(
13055
+ (balance) => [
13056
+ formatCell(balance.source_id ?? "-", idWidth),
13057
+ formatCell(balance.type ?? "-", TYPE_WIDTH),
13058
+ formatCell(
13059
+ balance.current != null ? formatCents(balance.current) : "-",
13060
+ CURRENT_WIDTH
13061
+ ),
13062
+ formatCell(balance.currency ?? "-", CURRENCY_WIDTH)
13063
+ ].join(COLUMN_GAP)
13064
+ );
13065
+ if (status === "loading") {
13066
+ return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsxs4(Text5, { color: "cyan", children: [
13067
+ /* @__PURE__ */ jsx5(Spinner3, { type: "dots" }),
13068
+ " Loading balances..."
13069
+ ] }) });
13070
+ }
13071
+ if (status === "error") {
13072
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
13073
+ /* @__PURE__ */ jsx5(Text5, { color: "red", children: "Failed to load balances" }),
13074
+ /* @__PURE__ */ jsx5(Text5, { color: "red", children: error })
13075
+ ] });
13076
+ }
13077
+ if (balances.length === 0) {
13078
+ return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "No balances found" }) });
13079
+ }
13080
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
13081
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: "Balances" }),
13082
+ /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
13083
+ /* @__PURE__ */ jsx5(Text5, { bold: true, children: headerRow }),
13084
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: separatorRow }),
13085
+ rows.map((row, index) => /* @__PURE__ */ jsx5(Text5, { children: row }, balances[index].source_id ?? `balance-${index}`))
13086
+ ] }),
13087
+ page?.has_more !== void 0 ? /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
13088
+ /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
13089
+ "has_more: ",
13090
+ String(page.has_more)
13091
+ ] }),
13092
+ typeof nextCursor === "string" && nextCursor.length > 0 ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: `next page: --starting-after ${nextCursor}` }) : null
13093
+ ] }) : null
13094
+ ] });
13095
+ };
13096
+
13097
+ // src/commands/balances/schema.ts
13098
+ import { z as z2 } from "incur";
13099
+ var listOptions = z2.object({
13100
+ limit: z2.coerce.number().int().positive().max(100).optional().describe("Maximum number of balances to return (1-100)."),
13101
+ startingAfter: z2.string().optional().describe("Cursor: return balances after this balance ID."),
13102
+ endingBefore: z2.string().optional().describe("Cursor: return balances before this balance ID.")
13103
+ });
13104
+
13105
+ // src/commands/balances/index.tsx
13106
+ import { jsx as jsx6 } from "react/jsx-runtime";
13107
+ function createBalancesCli(createResource, authStorage2, envAccessToken2) {
13108
+ const cli2 = Cli2.create("balances", {
13109
+ description: "List balances from your Link wallet"
13110
+ });
13111
+ cli2.command("list", {
13112
+ description: "List balances from your Link wallet",
13113
+ options: listOptions,
13114
+ outputPolicy: "agent-only",
13115
+ middleware: [requireAuth(authStorage2, envAccessToken2)],
13116
+ async run(c) {
13117
+ const opts = c.options;
13118
+ const resource = createResource();
13119
+ const params = {};
13120
+ if (opts.limit !== void 0) params.limit = opts.limit;
13121
+ if (opts.startingAfter !== void 0)
13122
+ params.starting_after = opts.startingAfter;
13123
+ if (opts.endingBefore !== void 0)
13124
+ params.ending_before = opts.endingBefore;
13125
+ if (!c.agent && !c.formatExplicit) {
13126
+ return renderInteractive(
13127
+ /* @__PURE__ */ jsx6(
13128
+ BalancesList,
13129
+ {
13130
+ resource,
13131
+ params,
13132
+ onComplete: () => {
13133
+ }
13134
+ }
13135
+ ),
13136
+ () => resource.listBalances(params)
13137
+ );
13138
+ }
13139
+ return resource.listBalances(params);
13140
+ }
13141
+ });
13142
+ return cli2;
13143
+ }
13144
+
12716
13145
  // src/commands/demo/index.tsx
12717
- import { Cli as Cli2, z as z2 } from "incur";
13146
+ import { Cli as Cli3, z as z3 } from "incur";
12718
13147
 
12719
13148
  // src/commands/demo/demo-runner.tsx
12720
- import { Box as Box8, Text as Text10, useApp, useInput as useInput4 } from "ink";
12721
- import { useCallback as useCallback2, useState as useState7 } from "react";
13149
+ import { Box as Box9, Text as Text11, useApp, useInput as useInput4 } from "ink";
13150
+ import { useCallback as useCallback3, useState as useState7 } from "react";
12722
13151
 
12723
13152
  // src/utils/markdown-text.tsx
12724
- import { Text as Text5 } from "ink";
12725
- import { jsx as jsx5 } from "react/jsx-runtime";
13153
+ import { Text as Text6 } from "ink";
13154
+ import { jsx as jsx7 } from "react/jsx-runtime";
12726
13155
  var MarkdownText = ({
12727
13156
  children,
12728
13157
  dimColor
12729
13158
  }) => {
12730
13159
  const parts = tokenize(children);
12731
- return /* @__PURE__ */ jsx5(Text5, { dimColor, children: parts.map((part) => {
13160
+ return /* @__PURE__ */ jsx7(Text6, { dimColor, children: parts.map((part) => {
12732
13161
  if (part.type === "bold") {
12733
- return /* @__PURE__ */ jsx5(Text5, { bold: true, children: part.text }, part.key);
13162
+ return /* @__PURE__ */ jsx7(Text6, { bold: true, children: part.text }, part.key);
12734
13163
  }
12735
13164
  if (part.type === "code") {
12736
- return /* @__PURE__ */ jsx5(Text5, { color: "yellow", children: part.text }, part.key);
13165
+ return /* @__PURE__ */ jsx7(Text6, { color: "yellow", children: part.text }, part.key);
12737
13166
  }
12738
- return /* @__PURE__ */ jsx5(Text5, { children: part.text }, part.key);
13167
+ return /* @__PURE__ */ jsx7(Text6, { children: part.text }, part.key);
12739
13168
  }) });
12740
13169
  };
12741
13170
  function tokenize(input) {
@@ -12770,7 +13199,7 @@ function tokenize(input) {
12770
13199
  }
12771
13200
 
12772
13201
  // src/commands/spend-request/app-download-qr-codes.tsx
12773
- import { Box as Box4, Text as Text6 } from "ink";
13202
+ import { Box as Box5, Text as Text7 } from "ink";
12774
13203
  import { useMemo } from "react";
12775
13204
 
12776
13205
  // src/utils/render-qr-matrix.ts
@@ -12807,24 +13236,24 @@ function renderQrMatrix(url) {
12807
13236
  }
12808
13237
 
12809
13238
  // src/commands/spend-request/app-download-qr-codes.tsx
12810
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
13239
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
12811
13240
  var DOWNLOAD_URL = "https://link.com/download";
12812
13241
  var AppDownloadQrCodes = () => {
12813
13242
  const qrLines = useMemo(() => renderQrMatrix(DOWNLOAD_URL), []);
12814
- return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
12815
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Get the Link app to approve spend requests from your phone" }),
12816
- /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", alignItems: "flex-start", marginTop: 1, children: [
13243
+ return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
13244
+ /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Get the Link app to approve spend requests from your phone" }),
13245
+ /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", alignItems: "flex-start", marginTop: 1, children: [
12817
13246
  qrLines.map((line, i) => (
12818
13247
  // biome-ignore lint/suspicious/noArrayIndexKey: stable static array
12819
- /* @__PURE__ */ jsx6(Text6, { children: line }, i)
13248
+ /* @__PURE__ */ jsx8(Text7, { children: line }, i)
12820
13249
  )),
12821
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: DOWNLOAD_URL })
13250
+ /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: DOWNLOAD_URL })
12822
13251
  ] })
12823
13252
  ] });
12824
13253
  };
12825
13254
 
12826
13255
  // src/commands/demo/card-flow.tsx
12827
- import { Box as Box5, Text as Text7, useInput as useInput2 } from "ink";
13256
+ import { Box as Box6, Text as Text8, useInput as useInput2 } from "ink";
12828
13257
  import { useEffect as useEffect4, useRef as useRef2, useState as useState4 } from "react";
12829
13258
 
12830
13259
  // src/utils/poll-until-approved.ts
@@ -12989,7 +13418,7 @@ var ONBOARD = {
12989
13418
  };
12990
13419
 
12991
13420
  // src/commands/demo/card-flow.tsx
12992
- import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
13421
+ import { Fragment, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
12993
13422
  function formatPmLabel(pm) {
12994
13423
  return `${pm.card_details?.brand ?? pm.type} ****${pm.card_details?.last4 ?? ""}`;
12995
13424
  }
@@ -13173,22 +13602,22 @@ var CardFlow = ({
13173
13602
  ];
13174
13603
  return order.indexOf(step) > order.indexOf(target);
13175
13604
  };
13176
- const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs5(Text7, { dimColor: true, children: [
13605
+ const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
13177
13606
  "\n",
13178
13607
  ">",
13179
13608
  " ",
13180
13609
  label
13181
13610
  ] });
13182
- return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", gap: 1, children: [
13183
- /* @__PURE__ */ jsx7(Text7, { bold: true, color: "cyan", children: CARD_FLOW.title }),
13184
- /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13185
- /* @__PURE__ */ jsxs5(Box5, { flexDirection: "row", gap: 1, children: [
13186
- /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "[testmode]" }),
13187
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: DEMO_MERCHANT_URL })
13611
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", gap: 1, children: [
13612
+ /* @__PURE__ */ jsx9(Text8, { bold: true, color: "cyan", children: CARD_FLOW.title }),
13613
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13614
+ /* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", gap: 1, children: [
13615
+ /* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "[testmode]" }),
13616
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: DEMO_MERCHANT_URL })
13188
13617
  ] }),
13189
- /* @__PURE__ */ jsx7(MarkdownText, { children: CARD_FLOW.intro.description }),
13190
- /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, flexDirection: "column", children: [
13191
- /* @__PURE__ */ jsx7(Text7, { children: "What happens:" }),
13618
+ /* @__PURE__ */ jsx9(MarkdownText, { children: CARD_FLOW.intro.description }),
13619
+ /* @__PURE__ */ jsxs6(Box6, { marginTop: 1, flexDirection: "column", children: [
13620
+ /* @__PURE__ */ jsx9(Text8, { children: "What happens:" }),
13192
13621
  CARD_FLOW.intro.steps.map((s, i) => {
13193
13622
  const doneAfter = [
13194
13623
  "pick-pm",
@@ -13204,17 +13633,17 @@ var CardFlow = ({
13204
13633
  ];
13205
13634
  const done = pastStep(doneAfter[i]);
13206
13635
  const active = !done && (step === activeFrom[i] || pastStep(activeFrom[i]));
13207
- return done ? /* @__PURE__ */ jsxs5(Text7, { dimColor: true, strikethrough: true, children: [
13636
+ return done ? /* @__PURE__ */ jsxs6(Text8, { dimColor: true, strikethrough: true, children: [
13208
13637
  " ",
13209
13638
  i + 1,
13210
13639
  ". ",
13211
13640
  s
13212
- ] }, s) : active ? /* @__PURE__ */ jsxs5(Text7, { bold: true, color: "cyan", children: [
13641
+ ] }, s) : active ? /* @__PURE__ */ jsxs6(Text8, { bold: true, color: "cyan", children: [
13213
13642
  " ",
13214
13643
  i + 1,
13215
13644
  ". ",
13216
13645
  s
13217
- ] }, s) : /* @__PURE__ */ jsxs5(Text7, { dimColor: true, children: [
13646
+ ] }, s) : /* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
13218
13647
  " ",
13219
13648
  i + 1,
13220
13649
  ". ",
@@ -13224,45 +13653,45 @@ var CardFlow = ({
13224
13653
  ] }),
13225
13654
  step === "intro" && prompt(CARD_FLOW.intro.prompt)
13226
13655
  ] }),
13227
- step === "fetch-pm" && /* @__PURE__ */ jsx7(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Fetching payment methods from your Link wallet..." }) }),
13228
- (step === "pick-pm" || step === "explain-pm") && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13229
- step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13230
- /* @__PURE__ */ jsx7(Text7, { children: "Which payment method should we use for the demo?" }),
13231
- /* @__PURE__ */ jsx7(Box5, { flexDirection: "column", marginTop: 1, children: paymentMethods.map((pm, i) => /* @__PURE__ */ jsx7(Text7, { children: i === selectedPmIndex ? /* @__PURE__ */ jsxs5(Text7, { color: "cyan", bold: true, children: [
13656
+ step === "fetch-pm" && /* @__PURE__ */ jsx9(Box6, { flexDirection: "column", children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Fetching payment methods from your Link wallet..." }) }),
13657
+ (step === "pick-pm" || step === "explain-pm") && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13658
+ step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13659
+ /* @__PURE__ */ jsx9(Text8, { children: "Which payment method should we use for the demo?" }),
13660
+ /* @__PURE__ */ jsx9(Box6, { flexDirection: "column", marginTop: 1, children: paymentMethods.map((pm, i) => /* @__PURE__ */ jsx9(Text8, { children: i === selectedPmIndex ? /* @__PURE__ */ jsxs6(Text8, { color: "cyan", bold: true, children: [
13232
13661
  ">",
13233
13662
  " ",
13234
13663
  formatPmLabel(pm),
13235
13664
  pm.is_default ? " (default)" : ""
13236
- ] }) : /* @__PURE__ */ jsxs5(Text7, { dimColor: true, children: [
13665
+ ] }) : /* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
13237
13666
  " ",
13238
13667
  formatPmLabel(pm),
13239
13668
  pm.is_default ? " (default)" : ""
13240
13669
  ] }) }, pm.id)) }),
13241
- /* @__PURE__ */ jsx7(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Use \u2191\u2193 to select, [Enter] to confirm" }) })
13670
+ /* @__PURE__ */ jsx9(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Use \u2191\u2193 to select, [Enter] to confirm" }) })
13242
13671
  ] }),
13243
- paymentMethod && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13244
- /* @__PURE__ */ jsxs5(Text7, { color: "green", children: [
13672
+ paymentMethod && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13673
+ /* @__PURE__ */ jsxs6(Text8, { color: "green", children: [
13245
13674
  "\u2713 Using ",
13246
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: pmLabel }),
13675
+ /* @__PURE__ */ jsx9(Text8, { bold: true, children: pmLabel }),
13247
13676
  paymentMethod.is_default ? " (default)" : ""
13248
13677
  ] }),
13249
13678
  step === "explain-pm" && prompt(CARD_FLOW.explainPm.prompt)
13250
13679
  ] })
13251
13680
  ] }),
13252
- step === "create-spend" && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13253
- /* @__PURE__ */ jsx7(MarkdownText, { children: CARD_FLOW.createSpend.description }),
13254
- /* @__PURE__ */ jsx7(Box5, { marginY: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "cyan", children: CARD_FLOW.createSpend.loading }) })
13681
+ step === "create-spend" && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13682
+ /* @__PURE__ */ jsx9(MarkdownText, { children: CARD_FLOW.createSpend.description }),
13683
+ /* @__PURE__ */ jsx9(Box6, { marginY: 1, children: /* @__PURE__ */ jsx9(Text8, { color: "cyan", children: CARD_FLOW.createSpend.loading }) })
13255
13684
  ] }),
13256
- (step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13257
- /* @__PURE__ */ jsxs5(Text7, { color: "green", children: [
13685
+ (step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13686
+ /* @__PURE__ */ jsxs6(Text8, { color: "green", children: [
13258
13687
  "\u2713 Spend request created (",
13259
13688
  spendRequest.id,
13260
13689
  ")"
13261
13690
  ] }),
13262
- step === "await-approval" && /* @__PURE__ */ jsxs5(Fragment, { children: [
13263
- /* @__PURE__ */ jsx7(Text7, { children: CARD_FLOW.approval.description }),
13264
- /* @__PURE__ */ jsxs5(
13265
- Box5,
13691
+ step === "await-approval" && /* @__PURE__ */ jsxs6(Fragment, { children: [
13692
+ /* @__PURE__ */ jsx9(Text8, { children: CARD_FLOW.approval.description }),
13693
+ /* @__PURE__ */ jsxs6(
13694
+ Box6,
13266
13695
  {
13267
13696
  flexDirection: "column",
13268
13697
  borderStyle: "round",
@@ -13271,21 +13700,21 @@ var CardFlow = ({
13271
13700
  paddingY: 1,
13272
13701
  marginTop: 1,
13273
13702
  children: [
13274
- /* @__PURE__ */ jsxs5(Text7, { children: [
13703
+ /* @__PURE__ */ jsxs6(Text8, { children: [
13275
13704
  "Approve at:",
13276
13705
  " ",
13277
- /* @__PURE__ */ jsx7(Text7, { bold: true, color: "cyan", children: approvalUrl })
13706
+ /* @__PURE__ */ jsx9(Text8, { bold: true, color: "cyan", children: approvalUrl })
13278
13707
  ] }),
13279
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: CARD_FLOW.approval.browserHint })
13708
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: CARD_FLOW.approval.browserHint })
13280
13709
  ]
13281
13710
  }
13282
13711
  ),
13283
- /* @__PURE__ */ jsx7(Box5, { marginY: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "cyan", children: CARD_FLOW.approval.loading }) })
13712
+ /* @__PURE__ */ jsx9(Box6, { marginY: 1, children: /* @__PURE__ */ jsx9(Text8, { color: "cyan", children: CARD_FLOW.approval.loading }) })
13284
13713
  ] }),
13285
- step === "approval-timeout" && /* @__PURE__ */ jsxs5(Fragment, { children: [
13286
- /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "\u26A0 Approval timed out (5 min). Still pending \u2014 you can still approve." }),
13287
- /* @__PURE__ */ jsxs5(
13288
- Box5,
13714
+ step === "approval-timeout" && /* @__PURE__ */ jsxs6(Fragment, { children: [
13715
+ /* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "\u26A0 Approval timed out (5 min). Still pending \u2014 you can still approve." }),
13716
+ /* @__PURE__ */ jsxs6(
13717
+ Box6,
13289
13718
  {
13290
13719
  flexDirection: "column",
13291
13720
  borderStyle: "round",
@@ -13294,38 +13723,38 @@ var CardFlow = ({
13294
13723
  paddingY: 1,
13295
13724
  marginTop: 1,
13296
13725
  children: [
13297
- /* @__PURE__ */ jsxs5(Text7, { children: [
13726
+ /* @__PURE__ */ jsxs6(Text8, { children: [
13298
13727
  "Approve at:",
13299
13728
  " ",
13300
- /* @__PURE__ */ jsx7(Text7, { bold: true, color: "cyan", children: approvalUrl })
13729
+ /* @__PURE__ */ jsx9(Text8, { bold: true, color: "cyan", children: approvalUrl })
13301
13730
  ] }),
13302
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Press [Enter] to open in browser" })
13731
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Press [Enter] to open in browser" })
13303
13732
  ]
13304
13733
  }
13305
13734
  ),
13306
- /* @__PURE__ */ jsx7(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "r Retry polling q Quit demo" }) })
13735
+ /* @__PURE__ */ jsx9(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "r Retry polling q Quit demo" }) })
13307
13736
  ] })
13308
13737
  ] }),
13309
- (step === "show-card" || step === "open-url" || step === "done") && card && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13310
- /* @__PURE__ */ jsx7(Text7, { color: "green", children: "\u2713 Approved!" }),
13311
- /* @__PURE__ */ jsx7(MarkdownText, { children: CARD_FLOW.showCard.description }),
13312
- /* @__PURE__ */ jsx7(Box5, { flexDirection: "column", paddingX: 2, marginTop: 1, children: /* @__PURE__ */ jsxs5(Text7, { children: [
13313
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Number " }),
13314
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: formatCardNumber(card.number) }),
13738
+ (step === "show-card" || step === "open-url" || step === "done") && card && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13739
+ /* @__PURE__ */ jsx9(Text8, { color: "green", children: "\u2713 Approved!" }),
13740
+ /* @__PURE__ */ jsx9(MarkdownText, { children: CARD_FLOW.showCard.description }),
13741
+ /* @__PURE__ */ jsx9(Box6, { flexDirection: "column", paddingX: 2, marginTop: 1, children: /* @__PURE__ */ jsxs6(Text8, { children: [
13742
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Number " }),
13743
+ /* @__PURE__ */ jsx9(Text8, { bold: true, children: formatCardNumber(card.number) }),
13315
13744
  " ",
13316
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Exp " }),
13317
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: formatExpiry(card.exp_month, card.exp_year) }),
13745
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Exp " }),
13746
+ /* @__PURE__ */ jsx9(Text8, { bold: true, children: formatExpiry(card.exp_month, card.exp_year) }),
13318
13747
  " ",
13319
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "CVC " }),
13320
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: card.cvc }),
13321
- card.billing_address?.postal_code && /* @__PURE__ */ jsxs5(Fragment, { children: [
13748
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "CVC " }),
13749
+ /* @__PURE__ */ jsx9(Text8, { bold: true, children: card.cvc }),
13750
+ card.billing_address?.postal_code && /* @__PURE__ */ jsxs6(Fragment, { children: [
13322
13751
  " ",
13323
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Zip " }),
13324
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: card.billing_address.postal_code })
13752
+ /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Zip " }),
13753
+ /* @__PURE__ */ jsx9(Text8, { bold: true, children: card.billing_address.postal_code })
13325
13754
  ] }),
13326
- card.valid_until && /* @__PURE__ */ jsxs5(Fragment, { children: [
13755
+ card.valid_until && /* @__PURE__ */ jsxs6(Fragment, { children: [
13327
13756
  " ",
13328
- /* @__PURE__ */ jsxs5(Text7, { dimColor: true, children: [
13757
+ /* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
13329
13758
  "expires",
13330
13759
  " ",
13331
13760
  new Date(card.valid_until).toLocaleTimeString([], {
@@ -13337,14 +13766,14 @@ var CardFlow = ({
13337
13766
  ] }) }),
13338
13767
  step === "show-card" && prompt(CARD_FLOW.showCard.prompt)
13339
13768
  ] }),
13340
- step === "done" && /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
13341
- /* @__PURE__ */ jsxs5(Text7, { color: "green", children: [
13769
+ step === "done" && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13770
+ /* @__PURE__ */ jsxs6(Text8, { color: "green", children: [
13342
13771
  "\u2713 ",
13343
13772
  CARD_FLOW.done.success
13344
13773
  ] }),
13345
- /* @__PURE__ */ jsx7(Text7, { children: CARD_FLOW.done.detail })
13774
+ /* @__PURE__ */ jsx9(Text8, { children: CARD_FLOW.done.detail })
13346
13775
  ] }),
13347
- step === "error" && /* @__PURE__ */ jsxs5(Text7, { color: "red", children: [
13776
+ step === "error" && /* @__PURE__ */ jsxs6(Text8, { color: "red", children: [
13348
13777
  "Error: ",
13349
13778
  error
13350
13779
  ] })
@@ -13352,7 +13781,7 @@ var CardFlow = ({
13352
13781
  };
13353
13782
 
13354
13783
  // src/commands/demo/spt-flow.tsx
13355
- import { Box as Box7, Text as Text9, useInput as useInput3 } from "ink";
13784
+ import { Box as Box8, Text as Text10, useInput as useInput3 } from "ink";
13356
13785
  import { useEffect as useEffect6, useRef as useRef3, useState as useState6 } from "react";
13357
13786
 
13358
13787
  // src/commands/mpp/decode.ts
@@ -13434,13 +13863,13 @@ function decodeStripeChallenge(challengeHeader) {
13434
13863
  }
13435
13864
 
13436
13865
  // src/commands/mpp/pay.tsx
13437
- import { Box as Box6, Text as Text8 } from "ink";
13438
- import Spinner3 from "ink-spinner";
13866
+ import { Box as Box7, Text as Text9 } from "ink";
13867
+ import Spinner4 from "ink-spinner";
13439
13868
  import { Credential, Method } from "mppx";
13440
13869
  import { Mppx, Transport } from "mppx/client";
13441
13870
  import { Methods as StripeMethods } from "mppx/stripe";
13442
13871
  import { useEffect as useEffect5, useState as useState5 } from "react";
13443
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
13872
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
13444
13873
  function buildHeaders(data, headers) {
13445
13874
  const result = {};
13446
13875
  if (data !== void 0) {
@@ -13614,21 +14043,21 @@ function MppPay({
13614
14043
  done: "Done"
13615
14044
  };
13616
14045
  if (error) {
13617
- return /* @__PURE__ */ jsxs6(Text8, { color: "red", children: [
14046
+ return /* @__PURE__ */ jsxs7(Text9, { color: "red", children: [
13618
14047
  "Error: ",
13619
14048
  error
13620
14049
  ] });
13621
14050
  }
13622
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13623
- step !== "done" && /* @__PURE__ */ jsx8(Box6, { children: /* @__PURE__ */ jsxs6(Text8, { color: "cyan", children: [
13624
- /* @__PURE__ */ jsx8(Spinner3, { type: "dots" }),
14051
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
14052
+ step !== "done" && /* @__PURE__ */ jsx10(Box7, { children: /* @__PURE__ */ jsxs7(Text9, { color: "cyan", children: [
14053
+ /* @__PURE__ */ jsx10(Spinner4, { type: "dots" }),
13625
14054
  " ",
13626
14055
  stepLabels[step],
13627
14056
  "..."
13628
14057
  ] }) }),
13629
- result && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
13630
- /* @__PURE__ */ jsxs6(
13631
- Text8,
14058
+ result && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
14059
+ /* @__PURE__ */ jsxs7(
14060
+ Text9,
13632
14061
  {
13633
14062
  color: result.status >= 400 ? "red" : result.status >= 300 ? "yellow" : "green",
13634
14063
  children: [
@@ -13637,13 +14066,13 @@ function MppPay({
13637
14066
  ]
13638
14067
  }
13639
14068
  ),
13640
- /* @__PURE__ */ jsx8(Text8, { children: result.body })
14069
+ /* @__PURE__ */ jsx10(Text9, { children: result.body })
13641
14070
  ] })
13642
14071
  ] });
13643
14072
  }
13644
14073
 
13645
14074
  // src/commands/demo/spt-flow.tsx
13646
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
14075
+ import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
13647
14076
  var SptFlow = ({
13648
14077
  spendRequestRepo: spendRequestRepo2,
13649
14078
  paymentMethodsResource,
@@ -13826,26 +14255,26 @@ var SptFlow = ({
13826
14255
  ];
13827
14256
  return order.indexOf(step) > order.indexOf(target);
13828
14257
  };
13829
- const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
14258
+ const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
13830
14259
  "\n",
13831
14260
  ">",
13832
14261
  " ",
13833
14262
  label
13834
14263
  ] });
13835
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", gap: 1, children: [
13836
- /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: SPT_FLOW.title }),
13837
- /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
13838
- /* @__PURE__ */ jsxs7(Box7, { flexDirection: "row", gap: 1, children: [
13839
- /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "[testmode]" }),
13840
- /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
14264
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, children: [
14265
+ /* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: SPT_FLOW.title }),
14266
+ /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14267
+ /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", gap: 1, children: [
14268
+ /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "[testmode]" }),
14269
+ /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
13841
14270
  DEMO_CLIMATE_API_URL,
13842
14271
  " ",
13843
14272
  DEMO_MPP_DEV_URL
13844
14273
  ] })
13845
14274
  ] }),
13846
- /* @__PURE__ */ jsx9(MarkdownText, { children: SPT_FLOW.intro.description }),
13847
- /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
13848
- /* @__PURE__ */ jsx9(Text9, { children: SPT_FLOW.intro.preamble }),
14275
+ /* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.intro.description }),
14276
+ /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
14277
+ /* @__PURE__ */ jsx11(Text10, { children: SPT_FLOW.intro.preamble }),
13849
14278
  SPT_FLOW.intro.steps.map((s, i) => {
13850
14279
  const doneAfter = [
13851
14280
  "pick-pm",
@@ -13864,17 +14293,17 @@ var SptFlow = ({
13864
14293
  const done = pastStep(doneAfter[i]);
13865
14294
  const active = !done && (step === activeFrom[i] || pastStep(activeFrom[i]));
13866
14295
  const label = s.replace(/`/g, "");
13867
- return done ? /* @__PURE__ */ jsxs7(Text9, { dimColor: true, strikethrough: true, children: [
14296
+ return done ? /* @__PURE__ */ jsxs8(Text10, { dimColor: true, strikethrough: true, children: [
13868
14297
  " ",
13869
14298
  i + 1,
13870
14299
  ". ",
13871
14300
  label
13872
- ] }, s) : active ? /* @__PURE__ */ jsxs7(Text9, { bold: true, color: "cyan", children: [
14301
+ ] }, s) : active ? /* @__PURE__ */ jsxs8(Text10, { bold: true, color: "cyan", children: [
13873
14302
  " ",
13874
14303
  i + 1,
13875
14304
  ". ",
13876
14305
  label
13877
- ] }, s) : /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
14306
+ ] }, s) : /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
13878
14307
  " ",
13879
14308
  i + 1,
13880
14309
  ". ",
@@ -13884,47 +14313,47 @@ var SptFlow = ({
13884
14313
  ] }),
13885
14314
  step === "intro" && prompt(SPT_FLOW.intro.prompt)
13886
14315
  ] }),
13887
- step === "fetch-pm" && /* @__PURE__ */ jsx9(Box7, { marginY: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: "Fetching payment methods..." }) }),
13888
- step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
13889
- /* @__PURE__ */ jsx9(Text9, { children: "Which payment method should we use for the demo?" }),
13890
- /* @__PURE__ */ jsx9(Box7, { flexDirection: "column", marginTop: 1, children: paymentMethods.map((pm, i) => /* @__PURE__ */ jsx9(Text9, { children: i === selectedPmIndex ? /* @__PURE__ */ jsxs7(Text9, { color: "cyan", bold: true, children: [
14316
+ step === "fetch-pm" && /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: "Fetching payment methods..." }) }),
14317
+ step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14318
+ /* @__PURE__ */ jsx11(Text10, { children: "Which payment method should we use for the demo?" }),
14319
+ /* @__PURE__ */ jsx11(Box8, { flexDirection: "column", marginTop: 1, children: paymentMethods.map((pm, i) => /* @__PURE__ */ jsx11(Text10, { children: i === selectedPmIndex ? /* @__PURE__ */ jsxs8(Text10, { color: "cyan", bold: true, children: [
13891
14320
  ">",
13892
14321
  " ",
13893
14322
  pm.card_details ? `${pm.card_details.brand} ****${pm.card_details.last4}` : pm.type,
13894
14323
  pm.is_default ? " (default)" : ""
13895
- ] }) : /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
14324
+ ] }) : /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
13896
14325
  " ",
13897
14326
  pm.card_details ? `${pm.card_details.brand} ****${pm.card_details.last4}` : pm.type,
13898
14327
  pm.is_default ? " (default)" : ""
13899
14328
  ] }) }, pm.id)) }),
13900
- /* @__PURE__ */ jsx9(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Use \u2191\u2193 to select, [Enter] to confirm" }) })
14329
+ /* @__PURE__ */ jsx11(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "Use \u2191\u2193 to select, [Enter] to confirm" }) })
13901
14330
  ] }),
13902
- (step === "probe" || step === "explain-402") && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
13903
- /* @__PURE__ */ jsx9(MarkdownText, { children: SPT_FLOW.probe.description }),
13904
- step === "probe" && /* @__PURE__ */ jsx9(Box7, { marginY: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: SPT_FLOW.probe.loading }) }),
13905
- step === "explain-402" && networkId && /* @__PURE__ */ jsxs7(Fragment2, { children: [
13906
- /* @__PURE__ */ jsx9(MarkdownText, { children: SPT_FLOW.probe.detail }),
13907
- /* @__PURE__ */ jsxs7(Text9, { color: "green", children: [
14331
+ (step === "probe" || step === "explain-402") && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14332
+ /* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.probe.description }),
14333
+ step === "probe" && /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.probe.loading }) }),
14334
+ step === "explain-402" && networkId && /* @__PURE__ */ jsxs8(Fragment2, { children: [
14335
+ /* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.probe.detail }),
14336
+ /* @__PURE__ */ jsxs8(Text10, { color: "green", children: [
13908
14337
  "\u2713 Got HTTP 402 \u2014 network_id: ",
13909
- /* @__PURE__ */ jsx9(Text9, { bold: true, children: networkId })
14338
+ /* @__PURE__ */ jsx11(Text10, { bold: true, children: networkId })
13910
14339
  ] }),
13911
14340
  prompt(SPT_FLOW.probe.prompt)
13912
14341
  ] })
13913
14342
  ] }),
13914
- step === "create-spend" && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
13915
- /* @__PURE__ */ jsx9(MarkdownText, { children: SPT_FLOW.createSpend.description }),
13916
- /* @__PURE__ */ jsx9(Box7, { marginY: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: SPT_FLOW.createSpend.loading }) })
14343
+ step === "create-spend" && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14344
+ /* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.createSpend.description }),
14345
+ /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.createSpend.loading }) })
13917
14346
  ] }),
13918
- (step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
13919
- /* @__PURE__ */ jsxs7(Text9, { color: "green", children: [
14347
+ (step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14348
+ /* @__PURE__ */ jsxs8(Text10, { color: "green", children: [
13920
14349
  "\u2713 Spend request created (",
13921
14350
  spendRequest.id,
13922
14351
  ")"
13923
14352
  ] }),
13924
- step === "await-approval" && /* @__PURE__ */ jsxs7(Fragment2, { children: [
13925
- /* @__PURE__ */ jsx9(Text9, { children: SPT_FLOW.approval.description }),
13926
- /* @__PURE__ */ jsxs7(
13927
- Box7,
14353
+ step === "await-approval" && /* @__PURE__ */ jsxs8(Fragment2, { children: [
14354
+ /* @__PURE__ */ jsx11(Text10, { children: SPT_FLOW.approval.description }),
14355
+ /* @__PURE__ */ jsxs8(
14356
+ Box8,
13928
14357
  {
13929
14358
  flexDirection: "column",
13930
14359
  borderStyle: "round",
@@ -13933,21 +14362,21 @@ var SptFlow = ({
13933
14362
  paddingY: 1,
13934
14363
  marginTop: 1,
13935
14364
  children: [
13936
- /* @__PURE__ */ jsxs7(Text9, { children: [
14365
+ /* @__PURE__ */ jsxs8(Text10, { children: [
13937
14366
  "Approve at:",
13938
14367
  " ",
13939
- /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: approvalUrl })
14368
+ /* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: approvalUrl })
13940
14369
  ] }),
13941
- /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: SPT_FLOW.approval.browserHint })
14370
+ /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: SPT_FLOW.approval.browserHint })
13942
14371
  ]
13943
14372
  }
13944
14373
  ),
13945
- /* @__PURE__ */ jsx9(Box7, { marginY: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: SPT_FLOW.approval.loading }) })
14374
+ /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.approval.loading }) })
13946
14375
  ] }),
13947
- step === "approval-timeout" && /* @__PURE__ */ jsxs7(Fragment2, { children: [
13948
- /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "\u26A0 Approval timed out (5 min). Still pending \u2014 you can still approve." }),
13949
- /* @__PURE__ */ jsxs7(
13950
- Box7,
14376
+ step === "approval-timeout" && /* @__PURE__ */ jsxs8(Fragment2, { children: [
14377
+ /* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "\u26A0 Approval timed out (5 min). Still pending \u2014 you can still approve." }),
14378
+ /* @__PURE__ */ jsxs8(
14379
+ Box8,
13951
14380
  {
13952
14381
  flexDirection: "column",
13953
14382
  borderStyle: "round",
@@ -13956,35 +14385,35 @@ var SptFlow = ({
13956
14385
  paddingY: 1,
13957
14386
  marginTop: 1,
13958
14387
  children: [
13959
- /* @__PURE__ */ jsxs7(Text9, { children: [
14388
+ /* @__PURE__ */ jsxs8(Text10, { children: [
13960
14389
  "Approve at:",
13961
14390
  " ",
13962
- /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: approvalUrl })
14391
+ /* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: approvalUrl })
13963
14392
  ] }),
13964
- /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Press [Enter] to open in browser" })
14393
+ /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "Press [Enter] to open in browser" })
13965
14394
  ]
13966
14395
  }
13967
14396
  ),
13968
- /* @__PURE__ */ jsx9(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "r Retry polling q Quit demo" }) })
14397
+ /* @__PURE__ */ jsx11(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "r Retry polling q Quit demo" }) })
13969
14398
  ] })
13970
14399
  ] }),
13971
- (step === "mpp-pay-gate" || step === "mpp-pay") && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
13972
- /* @__PURE__ */ jsx9(Text9, { color: "green", children: "\u2713 Approved!" }),
13973
- /* @__PURE__ */ jsx9(MarkdownText, { children: SPT_FLOW.mppPay.description }),
14400
+ (step === "mpp-pay-gate" || step === "mpp-pay") && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14401
+ /* @__PURE__ */ jsx11(Text10, { color: "green", children: "\u2713 Approved!" }),
14402
+ /* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.mppPay.description }),
13974
14403
  step === "mpp-pay-gate" && prompt(SPT_FLOW.mppPay.prompt),
13975
- step === "mpp-pay" && /* @__PURE__ */ jsx9(Box7, { marginY: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "cyan", children: SPT_FLOW.mppPay.loading }) })
14404
+ step === "mpp-pay" && /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.mppPay.loading }) })
13976
14405
  ] }),
13977
- step === "done" && payResult && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
13978
- /* @__PURE__ */ jsxs7(Text9, { bold: true, color: "green", children: [
14406
+ step === "done" && payResult && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14407
+ /* @__PURE__ */ jsxs8(Text10, { bold: true, color: "green", children: [
13979
14408
  "\u2713 ",
13980
14409
  SPT_FLOW.done.success,
13981
14410
  " (HTTP ",
13982
14411
  payResult.status,
13983
14412
  ")"
13984
14413
  ] }),
13985
- /* @__PURE__ */ jsx9(MarkdownText, { children: SPT_FLOW.done.detail })
14414
+ /* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.done.detail })
13986
14415
  ] }),
13987
- step === "error" && /* @__PURE__ */ jsxs7(Text9, { color: "red", children: [
14416
+ step === "error" && /* @__PURE__ */ jsxs8(Text10, { color: "red", children: [
13988
14417
  "Error: ",
13989
14418
  error
13990
14419
  ] })
@@ -13992,7 +14421,7 @@ var SptFlow = ({
13992
14421
  };
13993
14422
 
13994
14423
  // src/commands/demo/demo-runner.tsx
13995
- import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
14424
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
13996
14425
  var DemoRunner = ({
13997
14426
  authRepo: authRepo2,
13998
14427
  spendRequestRepo: spendRequestRepo2,
@@ -14034,7 +14463,7 @@ var DemoRunner = ({
14034
14463
  setPhase("spt-flow");
14035
14464
  }
14036
14465
  });
14037
- const onCardComplete = useCallback2(
14466
+ const onCardComplete = useCallback3(
14038
14467
  (result) => {
14039
14468
  setPaymentMethodId(result.paymentMethodId);
14040
14469
  setCardSuccess(result.success);
@@ -14050,7 +14479,7 @@ var DemoRunner = ({
14050
14479
  },
14051
14480
  [runSpt, onComplete, exit]
14052
14481
  );
14053
- const onSptComplete = useCallback2(
14482
+ const onSptComplete = useCallback3(
14054
14483
  (success) => {
14055
14484
  setSptSuccess(success);
14056
14485
  setPhase("summary");
@@ -14061,12 +14490,12 @@ var DemoRunner = ({
14061
14490
  },
14062
14491
  [onComplete, exit]
14063
14492
  );
14064
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, children: [
14065
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14066
- /* @__PURE__ */ jsx10(Text10, { bold: true, children: DEMO_MENU.title }),
14067
- /* @__PURE__ */ jsx10(Text10, { children: DEMO_MENU.subtitle })
14493
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, children: [
14494
+ /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
14495
+ /* @__PURE__ */ jsx12(Text11, { bold: true, children: DEMO_MENU.title }),
14496
+ /* @__PURE__ */ jsx12(Text11, { children: DEMO_MENU.subtitle })
14068
14497
  ] }),
14069
- phase === "auth" && /* @__PURE__ */ jsx10(
14498
+ phase === "auth" && /* @__PURE__ */ jsx12(
14070
14499
  Login,
14071
14500
  {
14072
14501
  authResource: authRepo2,
@@ -14075,25 +14504,25 @@ var DemoRunner = ({
14075
14504
  onComplete: () => setPhase(postAuthPhase)
14076
14505
  }
14077
14506
  ),
14078
- phase === "menu" && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14079
- /* @__PURE__ */ jsx10(Text10, { children: DEMO_MENU.question }),
14080
- /* @__PURE__ */ jsx10(Box8, { flexDirection: "column", marginTop: 1, gap: 1, children: DEMO_MENU.options.map((opt, i) => /* @__PURE__ */ jsx10(Box8, { flexDirection: "column", children: i === menuIndex ? /* @__PURE__ */ jsxs8(Fragment3, { children: [
14081
- /* @__PURE__ */ jsxs8(Text10, { color: "cyan", bold: true, children: [
14507
+ phase === "menu" && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
14508
+ /* @__PURE__ */ jsx12(Text11, { children: DEMO_MENU.question }),
14509
+ /* @__PURE__ */ jsx12(Box9, { flexDirection: "column", marginTop: 1, gap: 1, children: DEMO_MENU.options.map((opt, i) => /* @__PURE__ */ jsx12(Box9, { flexDirection: "column", children: i === menuIndex ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
14510
+ /* @__PURE__ */ jsxs9(Text11, { color: "cyan", bold: true, children: [
14082
14511
  ">",
14083
14512
  " ",
14084
14513
  opt.label
14085
14514
  ] }),
14086
- /* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
14515
+ /* @__PURE__ */ jsxs9(Text11, { color: "cyan", children: [
14087
14516
  " ",
14088
14517
  opt.description
14089
14518
  ] })
14090
- ] }) : /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
14519
+ ] }) : /* @__PURE__ */ jsxs9(Text11, { dimColor: true, children: [
14091
14520
  " ",
14092
14521
  opt.label
14093
14522
  ] }) }, opt.key)) }),
14094
- /* @__PURE__ */ jsx10(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: DEMO_MENU.hint }) })
14523
+ /* @__PURE__ */ jsx12(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: DEMO_MENU.hint }) })
14095
14524
  ] }),
14096
- runCard && phase !== "menu" && /* @__PURE__ */ jsx10(
14525
+ runCard && phase !== "menu" && /* @__PURE__ */ jsx12(
14097
14526
  CardFlow,
14098
14527
  {
14099
14528
  spendRequestRepo: spendRequestRepo2,
@@ -14102,19 +14531,19 @@ var DemoRunner = ({
14102
14531
  onComplete: onCardComplete
14103
14532
  }
14104
14533
  ),
14105
- phase === "card-done" && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14106
- /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "\u2500\u2500\u2500" }),
14107
- /* @__PURE__ */ jsx10(MarkdownText, { children: DEMO_MENU.transition }),
14108
- /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
14534
+ phase === "card-done" && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
14535
+ /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "\u2500\u2500\u2500" }),
14536
+ /* @__PURE__ */ jsx12(MarkdownText, { children: DEMO_MENU.transition }),
14537
+ /* @__PURE__ */ jsxs9(Text11, { dimColor: true, children: [
14109
14538
  "\n",
14110
14539
  ">",
14111
14540
  " ",
14112
14541
  DEMO_MENU.transitionPrompt
14113
14542
  ] })
14114
14543
  ] }),
14115
- runSpt && (phase === "spt-flow" || phase === "summary") && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14116
- runCard && /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "\u2500\u2500\u2500" }),
14117
- /* @__PURE__ */ jsx10(
14544
+ runSpt && (phase === "spt-flow" || phase === "summary") && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
14545
+ runCard && /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "\u2500\u2500\u2500" }),
14546
+ /* @__PURE__ */ jsx12(
14118
14547
  SptFlow,
14119
14548
  {
14120
14549
  spendRequestRepo: spendRequestRepo2,
@@ -14124,30 +14553,30 @@ var DemoRunner = ({
14124
14553
  }
14125
14554
  )
14126
14555
  ] }),
14127
- phase === "summary" && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
14128
- /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "\u2500\u2500\u2500" }),
14129
- /* @__PURE__ */ jsx10(Text10, { bold: true, children: "Done!" }),
14130
- cardSuccess !== null && /* @__PURE__ */ jsxs8(Text10, { color: cardSuccess ? "green" : "red", children: [
14556
+ phase === "summary" && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
14557
+ /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "\u2500\u2500\u2500" }),
14558
+ /* @__PURE__ */ jsx12(Text11, { bold: true, children: "Done!" }),
14559
+ cardSuccess !== null && /* @__PURE__ */ jsxs9(Text11, { color: cardSuccess ? "green" : "red", children: [
14131
14560
  cardSuccess ? "\u2713" : "\u2717",
14132
14561
  " Virtual card flow"
14133
14562
  ] }),
14134
- sptSuccess !== null && /* @__PURE__ */ jsxs8(Text10, { color: sptSuccess ? "green" : "red", children: [
14563
+ sptSuccess !== null && /* @__PURE__ */ jsxs9(Text11, { color: sptSuccess ? "green" : "red", children: [
14135
14564
  sptSuccess ? "\u2713" : "\u2717",
14136
14565
  " Machine payment flow"
14137
14566
  ] }),
14138
- /* @__PURE__ */ jsx10(AppDownloadQrCodes, {})
14567
+ /* @__PURE__ */ jsx12(AppDownloadQrCodes, {})
14139
14568
  ] })
14140
14569
  ] });
14141
14570
  };
14142
14571
 
14143
14572
  // src/commands/demo/index.tsx
14144
- import { jsx as jsx11 } from "react/jsx-runtime";
14145
- var demoOptions = z2.object({
14146
- onlyCard: z2.boolean().default(false).describe("Run only the virtual card flow"),
14147
- onlySpt: z2.boolean().default(false).describe("Run only the machine payment (SPT) flow")
14573
+ import { jsx as jsx13 } from "react/jsx-runtime";
14574
+ var demoOptions = z3.object({
14575
+ onlyCard: z3.boolean().default(false).describe("Run only the virtual card flow"),
14576
+ onlySpt: z3.boolean().default(false).describe("Run only the machine payment (SPT) flow")
14148
14577
  });
14149
14578
  function createDemoCli(authRepo2, spendRequestRepo2, createPaymentMethodsResource, authStorage2) {
14150
- return Cli2.create("demo", {
14579
+ return Cli3.create("demo", {
14151
14580
  description: "Run an interactive demo of both Link payment flows (virtual card + machine payment)",
14152
14581
  options: demoOptions,
14153
14582
  outputPolicy: "agent-only",
@@ -14160,7 +14589,7 @@ function createDemoCli(authRepo2, spendRequestRepo2, createPaymentMethodsResourc
14160
14589
  }
14161
14590
  const paymentMethodsResource = createPaymentMethodsResource();
14162
14591
  return renderInteractive(
14163
- /* @__PURE__ */ jsx11(
14592
+ /* @__PURE__ */ jsx13(
14164
14593
  DemoRunner,
14165
14594
  {
14166
14595
  authRepo: authRepo2,
@@ -14180,85 +14609,61 @@ function createDemoCli(authRepo2, spendRequestRepo2, createPaymentMethodsResourc
14180
14609
  }
14181
14610
 
14182
14611
  // src/commands/mpp/index.tsx
14183
- import { Cli as Cli3, z as z4 } from "incur";
14184
-
14185
- // src/utils/require-auth.ts
14186
- var NOT_AUTHENTICATED_ERROR = {
14187
- code: "NOT_AUTHENTICATED",
14188
- message: 'Not authenticated. Run "link-cli auth login" first.',
14189
- cta: {
14190
- commands: [{ command: "auth login", description: "Log in to Link" }]
14191
- }
14192
- };
14193
- function requireAuth(authStorage2, envAccessToken2) {
14194
- const store = authStorage2 ?? storage;
14195
- return (c, next) => {
14196
- if (!envAccessToken2 && !store.isAuthenticated()) {
14197
- return c.error(NOT_AUTHENTICATED_ERROR);
14198
- }
14199
- return next();
14200
- };
14201
- }
14202
- function requireAuthGuard(c, authStorage2, envAccessToken2) {
14203
- const store = authStorage2 ?? storage;
14204
- if (!envAccessToken2 && !store.isAuthenticated()) {
14205
- c.error(NOT_AUTHENTICATED_ERROR);
14206
- }
14207
- }
14612
+ import { Cli as Cli4, z as z5 } from "incur";
14208
14613
 
14209
14614
  // src/commands/mpp/decode-view.tsx
14210
- import { Box as Box9, Text as Text11 } from "ink";
14211
- import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
14615
+ import { Box as Box10, Text as Text12 } from "ink";
14616
+ import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
14212
14617
  function DecodeChallengeView({
14213
14618
  decoded
14214
14619
  }) {
14215
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
14216
- /* @__PURE__ */ jsx12(Text11, { color: "green", children: "\u2713 Stripe challenge decoded" }),
14217
- /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
14218
- /* @__PURE__ */ jsxs9(Text11, { children: [
14620
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
14621
+ /* @__PURE__ */ jsx14(Text12, { color: "green", children: "\u2713 Stripe challenge decoded" }),
14622
+ /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
14623
+ /* @__PURE__ */ jsxs10(Text12, { children: [
14219
14624
  "ID: ",
14220
- /* @__PURE__ */ jsx12(Text11, { bold: true, children: decoded.id })
14625
+ /* @__PURE__ */ jsx14(Text12, { bold: true, children: decoded.id })
14221
14626
  ] }),
14222
- /* @__PURE__ */ jsxs9(Text11, { children: [
14627
+ /* @__PURE__ */ jsxs10(Text12, { children: [
14223
14628
  "Realm: ",
14224
- /* @__PURE__ */ jsx12(Text11, { bold: true, children: decoded.realm })
14629
+ /* @__PURE__ */ jsx14(Text12, { bold: true, children: decoded.realm })
14225
14630
  ] }),
14226
- /* @__PURE__ */ jsxs9(Text11, { children: [
14631
+ /* @__PURE__ */ jsxs10(Text12, { children: [
14227
14632
  "Network ID: ",
14228
- /* @__PURE__ */ jsx12(Text11, { bold: true, children: decoded.network_id })
14633
+ /* @__PURE__ */ jsx14(Text12, { bold: true, children: decoded.network_id })
14229
14634
  ] }),
14230
- /* @__PURE__ */ jsx12(Text11, { children: "Request JSON:" }),
14231
- /* @__PURE__ */ jsx12(Text11, { children: JSON.stringify(decoded.request_json, null, 2) })
14635
+ /* @__PURE__ */ jsx14(Text12, { children: "Request JSON:" }),
14636
+ /* @__PURE__ */ jsx14(Text12, { children: JSON.stringify(decoded.request_json, null, 2) })
14232
14637
  ] })
14233
14638
  ] });
14234
14639
  }
14235
14640
 
14236
14641
  // src/commands/mpp/schema.ts
14237
- import { z as z3 } from "incur";
14238
- var payOptions = z3.object({
14239
- spendRequestId: z3.string().describe(
14642
+ import { z as z4 } from "incur";
14643
+ var payOptions = z4.object({
14644
+ spendRequestId: z4.string().describe(
14240
14645
  'Approved spend request ID with credential_type "shared_payment_token"'
14241
14646
  ),
14242
- method: z3.string().optional().describe("HTTP method (default: GET, or POST if --data is provided)"),
14243
- data: z3.string().optional().describe("Request body (implies POST if --method is not set)"),
14244
- header: z3.array(z3.string()).default([]).describe('Request header in "Name: Value" format (repeatable)')
14647
+ method: z4.string().optional().describe("HTTP method (default: GET, or POST if --data is provided)"),
14648
+ data: z4.string().optional().describe("Request body (implies POST if --method is not set)"),
14649
+ header: z4.array(z4.string()).default([]).describe('Request header in "Name: Value" format (repeatable)')
14245
14650
  });
14246
- var decodeOptions = z3.object({
14247
- challenge: z3.string().describe(
14651
+ var decodeOptions = z4.object({
14652
+ challenge: z4.string().describe(
14248
14653
  "Raw WWW-Authenticate header value; may include multiple payment challenges"
14249
14654
  )
14250
14655
  });
14251
14656
 
14252
14657
  // src/commands/mpp/index.tsx
14253
- import { jsx as jsx13 } from "react/jsx-runtime";
14658
+ import { jsx as jsx15 } from "react/jsx-runtime";
14254
14659
  function createMppCli(repository, authStorage2, envAccessToken2) {
14255
- const cli2 = Cli3.create("mpp", {
14660
+ const cli2 = Cli4.create("mpp", {
14256
14661
  description: "Machine payment protocol (MPP) commands"
14257
14662
  });
14258
14663
  cli2.command("pay", {
14259
14664
  description: "Complete a machine payment protocol (MPP) payment using an approved spend request",
14260
- args: z4.object({
14261
- url: z4.string().describe("URL to pay")
14665
+ args: z5.object({
14666
+ url: z5.string().describe("URL to pay")
14262
14667
  }),
14263
14668
  options: payOptions,
14264
14669
  alias: { method: "X", data: "d", header: "H" },
@@ -14273,7 +14678,7 @@ function createMppCli(repository, authStorage2, envAccessToken2) {
14273
14678
  if (!c.agent && !c.formatExplicit) {
14274
14679
  let capturedResult = null;
14275
14680
  return renderInteractive(
14276
- /* @__PURE__ */ jsx13(
14681
+ /* @__PURE__ */ jsx15(
14277
14682
  MppPay,
14278
14683
  {
14279
14684
  url,
@@ -14312,7 +14717,7 @@ function createMppCli(repository, authStorage2, envAccessToken2) {
14312
14717
  const decoded = decodeStripeChallenge(c.options.challenge);
14313
14718
  if (!c.agent && !c.formatExplicit) {
14314
14719
  return renderInteractive(
14315
- /* @__PURE__ */ jsx13(DecodeChallengeView, { decoded }),
14720
+ /* @__PURE__ */ jsx15(DecodeChallengeView, { decoded }),
14316
14721
  () => decoded
14317
14722
  );
14318
14723
  }
@@ -14323,12 +14728,12 @@ function createMppCli(repository, authStorage2, envAccessToken2) {
14323
14728
  }
14324
14729
 
14325
14730
  // src/commands/onboard/index.tsx
14326
- import { Cli as Cli4 } from "incur";
14731
+ import { Cli as Cli5 } from "incur";
14327
14732
 
14328
14733
  // src/commands/onboard/onboard-runner.tsx
14329
- import { Box as Box10, Text as Text12, useApp as useApp2, useInput as useInput5 } from "ink";
14734
+ import { Box as Box11, Text as Text13, useApp as useApp2, useInput as useInput5 } from "ink";
14330
14735
  import { useEffect as useEffect7, useRef as useRef4, useState as useState8 } from "react";
14331
- import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
14736
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
14332
14737
  var OnboardRunner = ({
14333
14738
  authRepo: authRepo2,
14334
14739
  spendRequestRepo: spendRequestRepo2,
@@ -14394,21 +14799,21 @@ var OnboardRunner = ({
14394
14799
  const order = ["welcome", "auth", "payment-methods", "demo"];
14395
14800
  return order.indexOf(phase) > order.indexOf(target);
14396
14801
  };
14397
- const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs10(Text12, { dimColor: true, children: [
14802
+ const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs11(Text13, { dimColor: true, children: [
14398
14803
  "\n",
14399
14804
  ">",
14400
14805
  " ",
14401
14806
  label
14402
14807
  ] });
14403
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", gap: 1, children: [
14404
- /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
14405
- /* @__PURE__ */ jsx14(Text12, { bold: true, children: ONBOARD.title }),
14406
- /* @__PURE__ */ jsx14(Text12, { children: ONBOARD.subtitle })
14808
+ return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", gap: 1, children: [
14809
+ /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
14810
+ /* @__PURE__ */ jsx16(Text13, { bold: true, children: ONBOARD.title }),
14811
+ /* @__PURE__ */ jsx16(Text13, { children: ONBOARD.subtitle })
14407
14812
  ] }),
14408
- /* @__PURE__ */ jsx14(Box10, { flexDirection: "column", children: authSkipped || pastPhase("auth") ? /* @__PURE__ */ jsxs10(Text12, { color: "green", children: [
14813
+ /* @__PURE__ */ jsx16(Box11, { flexDirection: "column", children: authSkipped || pastPhase("auth") ? /* @__PURE__ */ jsxs11(Text13, { color: "green", children: [
14409
14814
  "\u2713 ",
14410
14815
  authSkipped ? ONBOARD.auth.alreadyLoggedIn : ONBOARD.auth.authenticated
14411
- ] }) : phase === "auth" && !storage2.isAuthenticated() ? /* @__PURE__ */ jsx14(
14816
+ ] }) : phase === "auth" && !storage2.isAuthenticated() ? /* @__PURE__ */ jsx16(
14412
14817
  Login,
14413
14818
  {
14414
14819
  authResource: authRepo2,
@@ -14417,24 +14822,24 @@ var OnboardRunner = ({
14417
14822
  onComplete: () => authResolver.current?.()
14418
14823
  }
14419
14824
  ) : null }),
14420
- pastPhase("auth") && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
14421
- phase === "payment-methods" && !pmMissing && /* @__PURE__ */ jsx14(Text12, { color: "cyan", children: ONBOARD.paymentMethods.loading }),
14422
- pmMissing && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
14423
- /* @__PURE__ */ jsx14(Text12, { color: "yellow", children: ONBOARD.paymentMethods.missing }),
14424
- /* @__PURE__ */ jsx14(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text12, { children: [
14825
+ pastPhase("auth") && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
14826
+ phase === "payment-methods" && !pmMissing && /* @__PURE__ */ jsx16(Text13, { color: "cyan", children: ONBOARD.paymentMethods.loading }),
14827
+ pmMissing && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
14828
+ /* @__PURE__ */ jsx16(Text13, { color: "yellow", children: ONBOARD.paymentMethods.missing }),
14829
+ /* @__PURE__ */ jsx16(Box11, { marginTop: 1, children: /* @__PURE__ */ jsxs11(Text13, { children: [
14425
14830
  "Visit",
14426
14831
  " ",
14427
- /* @__PURE__ */ jsx14(Text12, { bold: true, color: "cyan", children: "app.link.com/wallet" }),
14832
+ /* @__PURE__ */ jsx16(Text13, { bold: true, color: "cyan", children: "app.link.com/wallet" }),
14428
14833
  " ",
14429
14834
  "to add a payment method, then press [Enter] to continue."
14430
14835
  ] }) }),
14431
14836
  prompt(ONBOARD.paymentMethods.retryPrompt)
14432
14837
  ] }),
14433
- pastPhase("payment-methods") && /* @__PURE__ */ jsx14(Text12, { color: "green", children: "\u2713 Payment method found" })
14838
+ pastPhase("payment-methods") && /* @__PURE__ */ jsx16(Text13, { color: "green", children: "\u2713 Payment method found" })
14434
14839
  ] }),
14435
- phase === "demo" && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
14436
- /* @__PURE__ */ jsx14(Text12, { dimColor: true, children: "\u2500\u2500\u2500" }),
14437
- /* @__PURE__ */ jsx14(
14840
+ phase === "demo" && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
14841
+ /* @__PURE__ */ jsx16(Text13, { dimColor: true, children: "\u2500\u2500\u2500" }),
14842
+ /* @__PURE__ */ jsx16(
14438
14843
  DemoRunner,
14439
14844
  {
14440
14845
  authRepo: authRepo2,
@@ -14445,7 +14850,7 @@ var OnboardRunner = ({
14445
14850
  }
14446
14851
  )
14447
14852
  ] }),
14448
- error && /* @__PURE__ */ jsxs10(Text12, { color: "red", children: [
14853
+ error && /* @__PURE__ */ jsxs11(Text13, { color: "red", children: [
14449
14854
  "Error: ",
14450
14855
  error
14451
14856
  ] })
@@ -14453,9 +14858,9 @@ var OnboardRunner = ({
14453
14858
  };
14454
14859
 
14455
14860
  // src/commands/onboard/index.tsx
14456
- import { jsx as jsx15 } from "react/jsx-runtime";
14861
+ import { jsx as jsx17 } from "react/jsx-runtime";
14457
14862
  function createOnboardCli(authRepo2, spendRequestRepo2, createPaymentMethodsResource, authStorage2) {
14458
- return Cli4.create("onboard", {
14863
+ return Cli5.create("onboard", {
14459
14864
  description: "Guided setup: authenticate, verify payment methods, and demo both payment flows",
14460
14865
  outputPolicy: "agent-only",
14461
14866
  async run(c) {
@@ -14467,7 +14872,7 @@ function createOnboardCli(authRepo2, spendRequestRepo2, createPaymentMethodsReso
14467
14872
  }
14468
14873
  const paymentMethodsResource = createPaymentMethodsResource();
14469
14874
  return renderInteractive(
14470
- /* @__PURE__ */ jsx15(
14875
+ /* @__PURE__ */ jsx17(
14471
14876
  OnboardRunner,
14472
14877
  {
14473
14878
  authRepo: authRepo2,
@@ -14485,11 +14890,11 @@ function createOnboardCli(authRepo2, spendRequestRepo2, createPaymentMethodsReso
14485
14890
  }
14486
14891
 
14487
14892
  // src/commands/payment-methods/index.tsx
14488
- import { Cli as Cli5 } from "incur";
14893
+ import { Cli as Cli6 } from "incur";
14489
14894
 
14490
14895
  // src/commands/payment-methods/add.tsx
14491
- import { Box as Box11, Text as Text13, useApp as useApp3, useInput as useInput6 } from "ink";
14492
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
14896
+ import { Box as Box12, Text as Text14, useApp as useApp3, useInput as useInput6 } from "ink";
14897
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
14493
14898
  var WALLET_URL = "https://app.link.com/wallet";
14494
14899
  var AddPaymentMethod = () => {
14495
14900
  const { exit } = useApp3();
@@ -14499,10 +14904,10 @@ var AddPaymentMethod = () => {
14499
14904
  exit();
14500
14905
  }
14501
14906
  });
14502
- return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingY: 1, children: [
14503
- /* @__PURE__ */ jsx16(Box11, { marginBottom: 1, children: /* @__PURE__ */ jsx16(Text13, { bold: true, children: "Add Payment Method" }) }),
14504
- /* @__PURE__ */ jsxs11(
14505
- Box11,
14907
+ return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingY: 1, children: [
14908
+ /* @__PURE__ */ jsx18(Box12, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Text14, { bold: true, children: "Add Payment Method" }) }),
14909
+ /* @__PURE__ */ jsxs12(
14910
+ Box12,
14506
14911
  {
14507
14912
  flexDirection: "column",
14508
14913
  borderStyle: "round",
@@ -14510,12 +14915,12 @@ var AddPaymentMethod = () => {
14510
14915
  paddingX: 2,
14511
14916
  paddingY: 1,
14512
14917
  children: [
14513
- /* @__PURE__ */ jsxs11(Text13, { children: [
14918
+ /* @__PURE__ */ jsxs12(Text14, { children: [
14514
14919
  "Open:",
14515
14920
  " ",
14516
- /* @__PURE__ */ jsx16(Text13, { bold: true, color: "cyan", children: WALLET_URL })
14921
+ /* @__PURE__ */ jsx18(Text14, { bold: true, color: "cyan", children: WALLET_URL })
14517
14922
  ] }),
14518
- /* @__PURE__ */ jsx16(Text13, { dimColor: true, children: "Press Enter to open in browser" })
14923
+ /* @__PURE__ */ jsx18(Text14, { dimColor: true, children: "Press Enter to open in browser" })
14519
14924
  ]
14520
14925
  }
14521
14926
  )
@@ -14523,48 +14928,48 @@ var AddPaymentMethod = () => {
14523
14928
  };
14524
14929
 
14525
14930
  // src/commands/payment-methods/list.tsx
14526
- import { Box as Box12, Text as Text14 } from "ink";
14527
- import Spinner4 from "ink-spinner";
14528
- import { useCallback as useCallback3 } from "react";
14529
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
14931
+ import { Box as Box13, Text as Text15 } from "ink";
14932
+ import Spinner5 from "ink-spinner";
14933
+ import { useCallback as useCallback4 } from "react";
14934
+ import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
14530
14935
  var PaymentMethodsList = ({
14531
14936
  resource,
14532
14937
  onComplete
14533
14938
  }) => {
14534
- const action = useCallback3(() => resource.listPaymentMethods(), [resource]);
14939
+ const action = useCallback4(() => resource.listPaymentMethods(), [resource]);
14535
14940
  const { status, data: methods, error } = useAsyncAction(action, onComplete);
14536
14941
  if (status === "loading") {
14537
- return /* @__PURE__ */ jsx17(Box12, { children: /* @__PURE__ */ jsxs12(Text14, { color: "cyan", children: [
14538
- /* @__PURE__ */ jsx17(Spinner4, { type: "dots" }),
14942
+ return /* @__PURE__ */ jsx19(Box13, { children: /* @__PURE__ */ jsxs13(Text15, { color: "cyan", children: [
14943
+ /* @__PURE__ */ jsx19(Spinner5, { type: "dots" }),
14539
14944
  " Loading payment methods..."
14540
14945
  ] }) });
14541
14946
  }
14542
14947
  if (status === "error") {
14543
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
14544
- /* @__PURE__ */ jsx17(Text14, { color: "red", children: "\u2717 Failed to load payment methods" }),
14545
- /* @__PURE__ */ jsx17(Text14, { color: "red", children: error })
14948
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
14949
+ /* @__PURE__ */ jsx19(Text15, { color: "red", children: "\u2717 Failed to load payment methods" }),
14950
+ /* @__PURE__ */ jsx19(Text15, { color: "red", children: error })
14546
14951
  ] });
14547
14952
  }
14548
14953
  if (!methods || methods.length === 0) {
14549
- return /* @__PURE__ */ jsx17(Box12, { children: /* @__PURE__ */ jsx17(Text14, { dimColor: true, children: "No payment methods found" }) });
14954
+ return /* @__PURE__ */ jsx19(Box13, { children: /* @__PURE__ */ jsx19(Text15, { dimColor: true, children: "No payment methods found" }) });
14550
14955
  }
14551
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
14552
- /* @__PURE__ */ jsx17(Text14, { bold: true, children: "Payment Methods" }),
14553
- /* @__PURE__ */ jsx17(Box12, { flexDirection: "column", marginTop: 1, children: methods.map((pm) => {
14956
+ return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
14957
+ /* @__PURE__ */ jsx19(Text15, { bold: true, children: "Payment Methods" }),
14958
+ /* @__PURE__ */ jsx19(Box13, { flexDirection: "column", marginTop: 1, children: methods.map((pm) => {
14554
14959
  const label = pm.card_details?.brand ?? pm.bank_account_details?.bank_name ?? "Bank account";
14555
14960
  const last4 = pm.card_details?.last4 ?? pm.bank_account_details?.last4;
14556
14961
  const suffix = pm.nickname ? `(${pm.nickname})` : "";
14557
14962
  const agenticCap = pm.capabilities?.agentic_payments;
14558
14963
  const ineligible = agenticCap && !agenticCap.eligible;
14559
- return /* @__PURE__ */ jsx17(Box12, { paddingX: 2, children: /* @__PURE__ */ jsxs12(Text14, { children: [
14560
- /* @__PURE__ */ jsx17(Text14, { dimColor: true, children: pm.id }),
14964
+ return /* @__PURE__ */ jsx19(Box13, { paddingX: 2, children: /* @__PURE__ */ jsxs13(Text15, { children: [
14965
+ /* @__PURE__ */ jsx19(Text15, { dimColor: true, children: pm.id }),
14561
14966
  " ",
14562
14967
  label,
14563
14968
  " ****",
14564
14969
  last4,
14565
14970
  suffix ? ` ${suffix}` : "",
14566
- pm.is_default ? /* @__PURE__ */ jsx17(Text14, { color: "green", children: " (default)" }) : "",
14567
- ineligible ? /* @__PURE__ */ jsxs12(Text14, { dimColor: true, children: [
14971
+ pm.is_default ? /* @__PURE__ */ jsx19(Text15, { color: "green", children: " (default)" }) : "",
14972
+ ineligible ? /* @__PURE__ */ jsxs13(Text15, { dimColor: true, children: [
14568
14973
  " ",
14569
14974
  "agentic_payments: ineligible",
14570
14975
  agenticCap.ineligibility_reasons?.length > 0 ? ` (${agenticCap.ineligibility_reasons.join(", ")})` : ""
@@ -14575,9 +14980,9 @@ var PaymentMethodsList = ({
14575
14980
  };
14576
14981
 
14577
14982
  // src/commands/payment-methods/index.tsx
14578
- import { jsx as jsx18 } from "react/jsx-runtime";
14983
+ import { jsx as jsx20 } from "react/jsx-runtime";
14579
14984
  function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2) {
14580
- const cli2 = Cli5.create("payment-methods", {
14985
+ const cli2 = Cli6.create("payment-methods", {
14581
14986
  description: "Payment methods management commands"
14582
14987
  });
14583
14988
  cli2.command("list", {
@@ -14588,7 +14993,7 @@ function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2)
14588
14993
  const resource = createResource();
14589
14994
  if (!c.agent && !c.formatExplicit) {
14590
14995
  return renderInteractive(
14591
- /* @__PURE__ */ jsx18(PaymentMethodsList, { resource, onComplete: () => {
14996
+ /* @__PURE__ */ jsx20(PaymentMethodsList, { resource, onComplete: () => {
14592
14997
  } }),
14593
14998
  () => resource.listPaymentMethods()
14594
14999
  );
@@ -14602,7 +15007,7 @@ function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2)
14602
15007
  middleware: [requireAuth(authStorage2, envAccessToken2)],
14603
15008
  async run(c) {
14604
15009
  if (!c.agent && !c.formatExplicit) {
14605
- return renderInteractive(/* @__PURE__ */ jsx18(AddPaymentMethod, {}), () => ({
15010
+ return renderInteractive(/* @__PURE__ */ jsx20(AddPaymentMethod, {}), () => ({
14606
15011
  url: WALLET_URL
14607
15012
  }));
14608
15013
  }
@@ -14613,22 +15018,22 @@ function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2)
14613
15018
  }
14614
15019
 
14615
15020
  // src/commands/report/index.tsx
14616
- import { Cli as Cli6 } from "incur";
15021
+ import { Cli as Cli7 } from "incur";
14617
15022
 
14618
15023
  // src/commands/report/schema.ts
14619
- import { z as z5 } from "incur";
14620
- var reportOptions = z5.object({
14621
- domain: z5.string().describe("Domain where the outcome occurred"),
14622
- outcome: z5.enum(REPORT_OUTCOMES).describe("What happened: success, blocked, or abandoned"),
14623
- spendRequestId: z5.string().describe("Spend request ID (lsrq_...)"),
14624
- tag: z5.array(z5.enum(REPORT_TAGS)).optional().describe("Outcome tags (repeatable)"),
14625
- step: z5.string().max(500).optional().describe("Where in the flow the agent was"),
14626
- freeformContext: z5.string().max(500).optional().describe("Additional context (max 500 chars)")
15024
+ import { z as z6 } from "incur";
15025
+ var reportOptions = z6.object({
15026
+ domain: z6.string().describe("Domain where the outcome occurred"),
15027
+ outcome: z6.enum(REPORT_OUTCOMES).describe("What happened: success, blocked, or abandoned"),
15028
+ spendRequestId: z6.string().describe("Spend request ID (lsrq_...)"),
15029
+ tag: z6.array(z6.enum(REPORT_TAGS)).optional().describe("Outcome tags (repeatable)"),
15030
+ step: z6.string().max(500).optional().describe("Where in the flow the agent was"),
15031
+ freeformContext: z6.string().max(500).optional().describe("Additional context (max 500 chars)")
14627
15032
  });
14628
15033
 
14629
15034
  // src/commands/report/index.tsx
14630
15035
  function createReportCli(createResource, authStorage2, envAccessToken2) {
14631
- const cli2 = Cli6.create("report", {
15036
+ const cli2 = Cli7.create("report", {
14632
15037
  description: "Report the outcome of an agent action on a domain. Call after every purchase attempt.",
14633
15038
  options: reportOptions,
14634
15039
  outputPolicy: "agent-only",
@@ -14653,7 +15058,7 @@ function createReportCli(createResource, authStorage2, envAccessToken2) {
14653
15058
  import {
14654
15059
  createServer
14655
15060
  } from "http";
14656
- import { Cli as Cli7, z as z6 } from "incur";
15061
+ import { Cli as Cli8, z as z7 } from "incur";
14657
15062
  async function nodeRequestToWebRequest(req, port) {
14658
15063
  const body = await new Promise((resolve) => {
14659
15064
  const chunks = [];
@@ -14679,10 +15084,10 @@ async function sendWebResponse(webRes, res) {
14679
15084
  res.end(Buffer.from(buffer));
14680
15085
  }
14681
15086
  function createServeCli(rootCli) {
14682
- return Cli7.create("serve", {
15087
+ return Cli8.create("serve", {
14683
15088
  description: "Start an HTTP server exposing link-cli as an MCP endpoint at /mcp",
14684
- options: z6.object({
14685
- port: z6.coerce.number().default(54321).describe("Port to listen on")
15089
+ options: z7.object({
15090
+ port: z7.coerce.number().default(54321).describe("Port to listen on")
14686
15091
  }),
14687
15092
  async run(c) {
14688
15093
  const { port } = c.options;
@@ -14727,13 +15132,13 @@ function createServeCli(rootCli) {
14727
15132
  }
14728
15133
 
14729
15134
  // src/commands/shipping-address/index.tsx
14730
- import { Cli as Cli8 } from "incur";
15135
+ import { Cli as Cli9 } from "incur";
14731
15136
 
14732
15137
  // src/commands/shipping-address/list.tsx
14733
- import { Box as Box13, Text as Text15 } from "ink";
14734
- import Spinner5 from "ink-spinner";
14735
- import { useCallback as useCallback4 } from "react";
14736
- import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
15138
+ import { Box as Box14, Text as Text16 } from "ink";
15139
+ import Spinner6 from "ink-spinner";
15140
+ import { useCallback as useCallback5 } from "react";
15141
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
14737
15142
  function formatStreetLine(address) {
14738
15143
  const parts = [address.line_1, address.line_2].filter(Boolean);
14739
15144
  return parts.length > 0 ? parts.join(", ") : null;
@@ -14749,102 +15154,313 @@ function formatLocalityLine(address) {
14749
15154
  if (localityPostal && address.country_code) {
14750
15155
  return `${localityPostal}, ${address.country_code}`;
14751
15156
  }
14752
- return localityPostal || address.country_code || null;
15157
+ return localityPostal || address.country_code || null;
15158
+ }
15159
+ function formatAddressLines(addressRecord) {
15160
+ if (!addressRecord.address) {
15161
+ return ["Address details unavailable"];
15162
+ }
15163
+ const address = addressRecord.address;
15164
+ const lines = [formatStreetLine(address), formatLocalityLine(address)].filter(
15165
+ (line) => Boolean(line)
15166
+ );
15167
+ return lines.length > 0 ? lines : ["Address details unavailable"];
15168
+ }
15169
+ var ShippingAddressList = ({
15170
+ resource,
15171
+ onComplete
15172
+ }) => {
15173
+ const action = useCallback5(
15174
+ () => resource.listShippingAddresses(),
15175
+ [resource]
15176
+ );
15177
+ const {
15178
+ status,
15179
+ data: shippingAddresses,
15180
+ error
15181
+ } = useAsyncAction(action, onComplete);
15182
+ if (status === "loading") {
15183
+ return /* @__PURE__ */ jsx21(Box14, { children: /* @__PURE__ */ jsxs14(Text16, { color: "cyan", children: [
15184
+ /* @__PURE__ */ jsx21(Spinner6, { type: "dots" }),
15185
+ " Loading shipping addresses..."
15186
+ ] }) });
15187
+ }
15188
+ if (status === "error") {
15189
+ return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
15190
+ /* @__PURE__ */ jsx21(Text16, { color: "red", children: "\u2717 Failed to load shipping addresses" }),
15191
+ /* @__PURE__ */ jsx21(Text16, { color: "red", children: error })
15192
+ ] });
15193
+ }
15194
+ if (!shippingAddresses || shippingAddresses.length === 0) {
15195
+ return /* @__PURE__ */ jsx21(Box14, { children: /* @__PURE__ */ jsx21(Text16, { dimColor: true, children: "No shipping addresses found" }) });
15196
+ }
15197
+ return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
15198
+ /* @__PURE__ */ jsx21(Text16, { bold: true, children: "Shipping Addresses" }),
15199
+ /* @__PURE__ */ jsx21(Box14, { flexDirection: "column", marginTop: 1, children: shippingAddresses.map((shippingAddress) => {
15200
+ const addressName = shippingAddress.address?.name;
15201
+ const nickname = shippingAddress.nickname ? ` (${shippingAddress.nickname})` : "";
15202
+ return /* @__PURE__ */ jsxs14(
15203
+ Box14,
15204
+ {
15205
+ flexDirection: "column",
15206
+ paddingX: 2,
15207
+ marginBottom: 1,
15208
+ children: [
15209
+ /* @__PURE__ */ jsxs14(Text16, { children: [
15210
+ /* @__PURE__ */ jsx21(Text16, { dimColor: true, children: shippingAddress.id }),
15211
+ nickname,
15212
+ shippingAddress.is_default ? /* @__PURE__ */ jsx21(Text16, { color: "green", children: " (default)" }) : null
15213
+ ] }),
15214
+ /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", marginTop: 1, children: [
15215
+ addressName ? /* @__PURE__ */ jsx21(Text16, { bold: true, children: addressName }) : null,
15216
+ formatAddressLines(shippingAddress).map((line) => /* @__PURE__ */ jsx21(Text16, { children: line }, `${shippingAddress.id}:${line}`))
15217
+ ] })
15218
+ ]
15219
+ },
15220
+ shippingAddress.id
15221
+ );
15222
+ }) })
15223
+ ] });
15224
+ };
15225
+
15226
+ // src/commands/shipping-address/index.tsx
15227
+ import { jsx as jsx22 } from "react/jsx-runtime";
15228
+ function createShippingAddressCli(createResource, authStorage2, envAccessToken2) {
15229
+ const cli2 = Cli9.create("shipping-address", {
15230
+ description: "Shipping address management commands"
15231
+ });
15232
+ cli2.command("list", {
15233
+ description: "List all shipping addresses on your account",
15234
+ outputPolicy: "agent-only",
15235
+ middleware: [requireAuth(authStorage2, envAccessToken2)],
15236
+ async run(c) {
15237
+ const resource = createResource();
15238
+ if (!c.agent && !c.formatExplicit) {
15239
+ return renderInteractive(
15240
+ /* @__PURE__ */ jsx22(ShippingAddressList, { resource, onComplete: () => {
15241
+ } }),
15242
+ () => resource.listShippingAddresses()
15243
+ );
15244
+ }
15245
+ return resource.listShippingAddresses();
15246
+ }
15247
+ });
15248
+ return cli2;
15249
+ }
15250
+
15251
+ // src/commands/sources/index.tsx
15252
+ import { Cli as Cli10 } from "incur";
15253
+
15254
+ // src/commands/sources/list.tsx
15255
+ import { Box as Box15, Text as Text17 } from "ink";
15256
+ import Spinner7 from "ink-spinner";
15257
+ import { useCallback as useCallback6 } from "react";
15258
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
15259
+ var COLUMN_GAP2 = " ";
15260
+ var HORIZONTAL_PADDING = 4;
15261
+ function truncateCell2(value, width) {
15262
+ if (value.length <= width) {
15263
+ return value;
15264
+ }
15265
+ if (width <= 3) {
15266
+ return value.slice(0, width);
15267
+ }
15268
+ return `${value.slice(0, width - 3)}...`;
15269
+ }
15270
+ function formatCell2(value, width) {
15271
+ return truncateCell2(value, width).padEnd(width);
15272
+ }
15273
+ function sourceId(source, index) {
15274
+ return typeof source.id === "string" && source.id.length > 0 ? source.id : `source-${index + 1}`;
15275
+ }
15276
+ function statusFromValue(value) {
15277
+ if (value && typeof value === "object" && !Array.isArray(value)) {
15278
+ const status = value.status;
15279
+ return typeof status === "string" ? status : null;
15280
+ }
15281
+ return null;
14753
15282
  }
14754
- function formatAddressLines(addressRecord) {
14755
- if (!addressRecord.address) {
14756
- return ["Address details unavailable"];
15283
+ function formatCapabilities(source) {
15284
+ const capabilities = source.capabilities;
15285
+ if (!capabilities || typeof capabilities !== "object") {
15286
+ return "-";
15287
+ }
15288
+ const entries = Object.entries(capabilities).map(([capability, value]) => {
15289
+ const status = statusFromValue(value);
15290
+ return status ? `${capability}:${status}` : capability;
15291
+ }).sort();
15292
+ return entries.length > 0 ? entries.join(", ") : "-";
15293
+ }
15294
+ function formatExternalConnection(source) {
15295
+ const status = statusFromValue(source.external_connection);
15296
+ return status ?? "-";
15297
+ }
15298
+ function sourceRow(source, index) {
15299
+ const capabilities = formatCapabilities(source);
15300
+ const external = formatExternalConnection(source);
15301
+ return {
15302
+ key: sourceId(source, index),
15303
+ name: source.name ?? "Source",
15304
+ type: source.type ?? "-",
15305
+ id: sourceId(source, index),
15306
+ capabilities,
15307
+ external
15308
+ };
15309
+ }
15310
+ function tableColumns() {
15311
+ return [
15312
+ { label: "Name", value: (row) => row.name, minWidth: 14, maxWidth: 24 },
15313
+ { label: "Type", value: (row) => row.type, minWidth: 10, maxWidth: 14 },
15314
+ { label: "ID", value: (row) => row.id, minWidth: 16, maxWidth: 48 },
15315
+ {
15316
+ label: "Capabilities",
15317
+ value: (row) => row.capabilities,
15318
+ minWidth: 8,
15319
+ maxWidth: 48
15320
+ },
15321
+ {
15322
+ label: "External connection status",
15323
+ value: (row) => row.external,
15324
+ minWidth: 8,
15325
+ maxWidth: 36
15326
+ }
15327
+ ];
15328
+ }
15329
+ function distributeWidths(columns, availableWidth) {
15330
+ const gapWidth = COLUMN_GAP2.length * Math.max(0, columns.length - 1);
15331
+ const contentWidth2 = Math.max(columns.length, availableWidth - gapWidth);
15332
+ const widths = columns.map((column) => column.minWidth);
15333
+ let remaining = contentWidth2 - widths.reduce((total, width) => total + width, 0);
15334
+ while (remaining > 0) {
15335
+ let changed = false;
15336
+ for (let index = 0; index < columns.length && remaining > 0; index += 1) {
15337
+ if (widths[index] >= columns[index].maxWidth) {
15338
+ continue;
15339
+ }
15340
+ widths[index] += 1;
15341
+ remaining -= 1;
15342
+ changed = true;
15343
+ }
15344
+ if (!changed) {
15345
+ break;
15346
+ }
14757
15347
  }
14758
- const address = addressRecord.address;
14759
- const lines = [formatStreetLine(address), formatLocalityLine(address)].filter(
14760
- (line) => Boolean(line)
15348
+ return widths;
15349
+ }
15350
+ function renderTableRows(rows, terminalWidth) {
15351
+ const columns = tableColumns();
15352
+ const availableWidth = contentWidth(terminalWidth);
15353
+ const widths = distributeWidths(columns, availableWidth);
15354
+ const headerRow = columns.map((column, index) => formatCell2(column.label, widths[index])).join(COLUMN_GAP2).slice(0, availableWidth);
15355
+ const separatorRow = "-".repeat(headerRow.length).slice(0, availableWidth);
15356
+ const bodyRows = rows.map(
15357
+ (row) => columns.map((column, index) => formatCell2(column.value(row), widths[index])).join(COLUMN_GAP2).slice(0, availableWidth)
14761
15358
  );
14762
- return lines.length > 0 ? lines : ["Address details unavailable"];
15359
+ return { headerRow, separatorRow, bodyRows };
14763
15360
  }
14764
- var ShippingAddressList = ({
15361
+ function contentWidth(terminalWidth) {
15362
+ return Math.max(1, terminalWidth - HORIZONTAL_PADDING);
15363
+ }
15364
+ var SourcesList = ({
14765
15365
  resource,
15366
+ params,
14766
15367
  onComplete
14767
15368
  }) => {
14768
- const action = useCallback4(
14769
- () => resource.listShippingAddresses(),
14770
- [resource]
15369
+ const action = useCallback6(
15370
+ () => resource.listSources(params),
15371
+ [resource, params]
15372
+ );
15373
+ const { status, data: page, error } = useAsyncAction(action, onComplete);
15374
+ const sources = page?.data ?? [];
15375
+ const nextCursor = page?.has_more && sources.length > 0 ? sources[sources.length - 1].id : null;
15376
+ const rows = sources.map(sourceRow);
15377
+ const terminalWidth = process.stdout.columns ?? 140;
15378
+ const { headerRow, separatorRow, bodyRows } = renderTableRows(
15379
+ rows,
15380
+ terminalWidth
14771
15381
  );
14772
- const {
14773
- status,
14774
- data: shippingAddresses,
14775
- error
14776
- } = useAsyncAction(action, onComplete);
14777
15382
  if (status === "loading") {
14778
- return /* @__PURE__ */ jsx19(Box13, { children: /* @__PURE__ */ jsxs13(Text15, { color: "cyan", children: [
14779
- /* @__PURE__ */ jsx19(Spinner5, { type: "dots" }),
14780
- " Loading shipping addresses..."
15383
+ return /* @__PURE__ */ jsx23(Box15, { children: /* @__PURE__ */ jsxs15(Text17, { color: "cyan", children: [
15384
+ /* @__PURE__ */ jsx23(Spinner7, { type: "dots" }),
15385
+ " Loading sources..."
14781
15386
  ] }) });
14782
15387
  }
14783
15388
  if (status === "error") {
14784
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
14785
- /* @__PURE__ */ jsx19(Text15, { color: "red", children: "\u2717 Failed to load shipping addresses" }),
14786
- /* @__PURE__ */ jsx19(Text15, { color: "red", children: error })
15389
+ return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
15390
+ /* @__PURE__ */ jsx23(Text17, { color: "red", children: "Failed to load sources" }),
15391
+ /* @__PURE__ */ jsx23(Text17, { color: "red", children: error })
14787
15392
  ] });
14788
15393
  }
14789
- if (!shippingAddresses || shippingAddresses.length === 0) {
14790
- return /* @__PURE__ */ jsx19(Box13, { children: /* @__PURE__ */ jsx19(Text15, { dimColor: true, children: "No shipping addresses found" }) });
15394
+ if (sources.length === 0) {
15395
+ return /* @__PURE__ */ jsx23(Box15, { children: /* @__PURE__ */ jsx23(Text17, { dimColor: true, children: "No sources found" }) });
14791
15396
  }
14792
- return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
14793
- /* @__PURE__ */ jsx19(Text15, { bold: true, children: "Shipping Addresses" }),
14794
- /* @__PURE__ */ jsx19(Box13, { flexDirection: "column", marginTop: 1, children: shippingAddresses.map((shippingAddress) => {
14795
- const addressName = shippingAddress.address?.name;
14796
- const nickname = shippingAddress.nickname ? ` (${shippingAddress.nickname})` : "";
14797
- return /* @__PURE__ */ jsxs13(
14798
- Box13,
14799
- {
14800
- flexDirection: "column",
14801
- paddingX: 2,
14802
- marginBottom: 1,
14803
- children: [
14804
- /* @__PURE__ */ jsxs13(Text15, { children: [
14805
- /* @__PURE__ */ jsx19(Text15, { dimColor: true, children: shippingAddress.id }),
14806
- nickname,
14807
- shippingAddress.is_default ? /* @__PURE__ */ jsx19(Text15, { color: "green", children: " (default)" }) : null
14808
- ] }),
14809
- /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", marginTop: 1, children: [
14810
- addressName ? /* @__PURE__ */ jsx19(Text15, { bold: true, children: addressName }) : null,
14811
- formatAddressLines(shippingAddress).map((line) => /* @__PURE__ */ jsx19(Text15, { children: line }, `${shippingAddress.id}:${line}`))
14812
- ] })
14813
- ]
14814
- },
14815
- shippingAddress.id
14816
- );
14817
- }) })
15397
+ return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
15398
+ /* @__PURE__ */ jsx23(Text17, { bold: true, children: "Sources" }),
15399
+ /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15400
+ /* @__PURE__ */ jsx23(Text17, { bold: true, children: headerRow }),
15401
+ /* @__PURE__ */ jsx23(Text17, { dimColor: true, children: separatorRow }),
15402
+ bodyRows.map((row, index) => /* @__PURE__ */ jsx23(Text17, { children: row }, rows[index].key))
15403
+ ] }),
15404
+ page?.has_more !== void 0 ? /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginTop: 1, children: [
15405
+ /* @__PURE__ */ jsxs15(Text17, { dimColor: true, children: [
15406
+ "has_more: ",
15407
+ String(page.has_more)
15408
+ ] }),
15409
+ typeof nextCursor === "string" && nextCursor.length > 0 ? /* @__PURE__ */ jsx23(Text17, { dimColor: true, children: `next page: --starting-after ${nextCursor}` }) : null
15410
+ ] }) : null
14818
15411
  ] });
14819
15412
  };
14820
15413
 
14821
- // src/commands/shipping-address/index.tsx
14822
- import { jsx as jsx20 } from "react/jsx-runtime";
14823
- function createShippingAddressCli(createResource, authStorage2, envAccessToken2) {
14824
- const cli2 = Cli8.create("shipping-address", {
14825
- description: "Shipping address management commands"
15414
+ // src/commands/sources/schema.ts
15415
+ import { z as z8 } from "incur";
15416
+ var listOptions2 = z8.object({
15417
+ limit: z8.coerce.number().int().positive().max(100).optional().describe("Maximum number of sources to return (1-100)."),
15418
+ startingAfter: z8.string().optional().describe("Cursor: return sources after this source ID."),
15419
+ endingBefore: z8.string().optional().describe("Cursor: return sources before this source ID.")
15420
+ });
15421
+
15422
+ // src/commands/sources/index.tsx
15423
+ import { jsx as jsx24 } from "react/jsx-runtime";
15424
+ function createSourcesCli(createResource, authStorage2, envAccessToken2) {
15425
+ const cli2 = Cli10.create("sources", {
15426
+ description: "List sources from your Link wallet"
14826
15427
  });
14827
15428
  cli2.command("list", {
14828
- description: "List all shipping addresses on your account",
15429
+ description: "List sources from your Link wallet",
15430
+ options: listOptions2,
14829
15431
  outputPolicy: "agent-only",
14830
15432
  middleware: [requireAuth(authStorage2, envAccessToken2)],
14831
15433
  async run(c) {
15434
+ const opts = c.options;
14832
15435
  const resource = createResource();
15436
+ const params = {};
15437
+ if (opts.limit !== void 0) params.limit = opts.limit;
15438
+ if (opts.startingAfter !== void 0)
15439
+ params.starting_after = opts.startingAfter;
15440
+ if (opts.endingBefore !== void 0)
15441
+ params.ending_before = opts.endingBefore;
14833
15442
  if (!c.agent && !c.formatExplicit) {
14834
15443
  return renderInteractive(
14835
- /* @__PURE__ */ jsx20(ShippingAddressList, { resource, onComplete: () => {
14836
- } }),
14837
- () => resource.listShippingAddresses()
15444
+ /* @__PURE__ */ jsx24(
15445
+ SourcesList,
15446
+ {
15447
+ resource,
15448
+ params,
15449
+ onComplete: () => {
15450
+ }
15451
+ }
15452
+ ),
15453
+ () => resource.listSources(params)
14838
15454
  );
14839
15455
  }
14840
- return resource.listShippingAddresses();
15456
+ return resource.listSources(params);
14841
15457
  }
14842
15458
  });
14843
15459
  return cli2;
14844
15460
  }
14845
15461
 
14846
15462
  // src/commands/spend-request/index.tsx
14847
- import { Cli as Cli9, z as z9 } from "incur";
15463
+ import { Cli as Cli11, z as z11 } from "incur";
14848
15464
 
14849
15465
  // src/utils/credential-output.ts
14850
15466
  import { constants } from "fs";
@@ -14902,21 +15518,21 @@ async function writeCredentialFile(filePath, data, force) {
14902
15518
  }
14903
15519
 
14904
15520
  // src/utils/line-item-parser.ts
14905
- import { z as z7 } from "zod";
14906
- var LineItemSchema = z7.object({
14907
- name: z7.string(),
14908
- url: z7.string().optional(),
14909
- image_url: z7.string().optional(),
14910
- description: z7.string().optional(),
14911
- sku: z7.string().optional(),
14912
- quantity: z7.coerce.number().optional(),
14913
- unit_amount: z7.coerce.number().optional(),
14914
- product_url: z7.string().optional()
15521
+ import { z as z9 } from "zod";
15522
+ var LineItemSchema = z9.object({
15523
+ name: z9.string(),
15524
+ url: z9.string().optional(),
15525
+ image_url: z9.string().optional(),
15526
+ description: z9.string().optional(),
15527
+ sku: z9.string().optional(),
15528
+ quantity: z9.coerce.number().optional(),
15529
+ unit_amount: z9.coerce.number().optional(),
15530
+ product_url: z9.string().optional()
14915
15531
  }).strict();
14916
- var TotalSchema = z7.object({
14917
- type: z7.string(),
14918
- display_text: z7.string(),
14919
- amount: z7.coerce.number()
15532
+ var TotalSchema = z9.object({
15533
+ type: z9.string(),
15534
+ display_text: z9.string(),
15535
+ amount: z9.coerce.number()
14920
15536
  }).strict();
14921
15537
  function parseKvString(raw) {
14922
15538
  const result = {};
@@ -14946,7 +15562,7 @@ function parseLineItemFlag(raw) {
14946
15562
  try {
14947
15563
  return LineItemSchema.parse(obj);
14948
15564
  } catch (err) {
14949
- if (err instanceof z7.ZodError)
15565
+ if (err instanceof z9.ZodError)
14950
15566
  throw formatZodError(err, "Line item", LineItemSchema);
14951
15567
  throw err;
14952
15568
  }
@@ -14956,65 +15572,65 @@ function parseTotalFlag(raw) {
14956
15572
  try {
14957
15573
  return TotalSchema.parse(obj);
14958
15574
  } catch (err) {
14959
- if (err instanceof z7.ZodError)
15575
+ if (err instanceof z9.ZodError)
14960
15576
  throw formatZodError(err, "Total", TotalSchema);
14961
15577
  throw err;
14962
15578
  }
14963
15579
  }
14964
15580
 
14965
15581
  // src/commands/spend-request/cancel.tsx
14966
- import { Box as Box14, Text as Text16 } from "ink";
14967
- import Spinner6 from "ink-spinner";
14968
- import { useCallback as useCallback5 } from "react";
14969
- import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
15582
+ import { Box as Box16, Text as Text18 } from "ink";
15583
+ import Spinner8 from "ink-spinner";
15584
+ import { useCallback as useCallback7 } from "react";
15585
+ import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
14970
15586
  var CancelSpendRequest = ({
14971
15587
  repository,
14972
15588
  id,
14973
15589
  onComplete
14974
15590
  }) => {
14975
- const action = useCallback5(
15591
+ const action = useCallback7(
14976
15592
  () => repository.cancelSpendRequest(id),
14977
15593
  [repository, id]
14978
15594
  );
14979
15595
  const { status, data: request, error } = useAsyncAction(action, onComplete);
14980
15596
  if (status === "loading") {
14981
- return /* @__PURE__ */ jsx21(Box14, { children: /* @__PURE__ */ jsxs14(Text16, { color: "cyan", children: [
14982
- /* @__PURE__ */ jsx21(Spinner6, { type: "dots" }),
15597
+ return /* @__PURE__ */ jsx25(Box16, { children: /* @__PURE__ */ jsxs16(Text18, { color: "cyan", children: [
15598
+ /* @__PURE__ */ jsx25(Spinner8, { type: "dots" }),
14983
15599
  " Canceling spend request ",
14984
15600
  id,
14985
15601
  "..."
14986
15602
  ] }) });
14987
15603
  }
14988
15604
  if (status === "error") {
14989
- return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
14990
- /* @__PURE__ */ jsx21(Text16, { color: "red", children: "\u2717 Failed to cancel spend request" }),
14991
- /* @__PURE__ */ jsx21(Text16, { color: "red", children: error })
15605
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
15606
+ /* @__PURE__ */ jsx25(Text18, { color: "red", children: "\u2717 Failed to cancel spend request" }),
15607
+ /* @__PURE__ */ jsx25(Text18, { color: "red", children: error })
14992
15608
  ] });
14993
15609
  }
14994
- return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
14995
- /* @__PURE__ */ jsx21(Text16, { color: "green", children: "\u2713 Spend request canceled" }),
14996
- /* @__PURE__ */ jsx21(Box14, { flexDirection: "column", marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs14(Text16, { children: [
15610
+ return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
15611
+ /* @__PURE__ */ jsx25(Text18, { color: "green", children: "\u2713 Spend request canceled" }),
15612
+ /* @__PURE__ */ jsx25(Box16, { flexDirection: "column", marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs16(Text18, { children: [
14997
15613
  "ID: ",
14998
- /* @__PURE__ */ jsx21(Text16, { bold: true, children: request?.id })
15614
+ /* @__PURE__ */ jsx25(Text18, { bold: true, children: request?.id })
14999
15615
  ] }) })
15000
15616
  ] });
15001
15617
  };
15002
15618
 
15003
15619
  // src/commands/spend-request/create.tsx
15004
- import { Box as Box16, Text as Text18, useApp as useApp4 } from "ink";
15005
- import Spinner8 from "ink-spinner";
15006
- import { useCallback as useCallback6, useEffect as useEffect9, useState as useState9 } from "react";
15620
+ import { Box as Box18, Text as Text20, useApp as useApp4 } from "ink";
15621
+ import Spinner10 from "ink-spinner";
15622
+ import { useCallback as useCallback8, useEffect as useEffect9, useState as useState9 } from "react";
15007
15623
 
15008
15624
  // src/commands/spend-request/approval-waiting-view.tsx
15009
- import { Box as Box15, Text as Text17 } from "ink";
15010
- import Spinner7 from "ink-spinner";
15011
- import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
15625
+ import { Box as Box17, Text as Text19 } from "ink";
15626
+ import Spinner9 from "ink-spinner";
15627
+ import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
15012
15628
  var ApprovalWaitingView = ({
15013
15629
  status,
15014
15630
  approvalUrl
15015
- }) => /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", paddingY: 1, children: [
15016
- /* @__PURE__ */ jsxs15(
15017
- Box15,
15631
+ }) => /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", paddingY: 1, children: [
15632
+ /* @__PURE__ */ jsxs17(
15633
+ Box17,
15018
15634
  {
15019
15635
  flexDirection: "column",
15020
15636
  borderStyle: "round",
@@ -15022,20 +15638,20 @@ var ApprovalWaitingView = ({
15022
15638
  paddingX: 2,
15023
15639
  paddingY: 1,
15024
15640
  children: [
15025
- /* @__PURE__ */ jsxs15(Text17, { children: [
15641
+ /* @__PURE__ */ jsxs17(Text19, { children: [
15026
15642
  "Approve at:",
15027
15643
  " ",
15028
- /* @__PURE__ */ jsx22(Text17, { bold: true, color: "cyan", children: approvalUrl })
15644
+ /* @__PURE__ */ jsx26(Text19, { bold: true, color: "cyan", children: approvalUrl })
15029
15645
  ] }),
15030
- /* @__PURE__ */ jsx22(Text17, { dimColor: true, children: "Press Enter to open in browser" })
15646
+ /* @__PURE__ */ jsx26(Text19, { dimColor: true, children: "Press Enter to open in browser" })
15031
15647
  ]
15032
15648
  }
15033
15649
  ),
15034
- /* @__PURE__ */ jsx22(AppDownloadQrCodes, {}),
15035
- /* @__PURE__ */ jsx22(Box15, { marginTop: 1, children: status === "polling" ? /* @__PURE__ */ jsxs15(Text17, { color: "cyan", children: [
15036
- /* @__PURE__ */ jsx22(Spinner7, { type: "dots" }),
15650
+ /* @__PURE__ */ jsx26(AppDownloadQrCodes, {}),
15651
+ /* @__PURE__ */ jsx26(Box17, { marginTop: 1, children: status === "polling" ? /* @__PURE__ */ jsxs17(Text19, { color: "cyan", children: [
15652
+ /* @__PURE__ */ jsx26(Spinner9, { type: "dots" }),
15037
15653
  " Waiting for approval..."
15038
- ] }) : /* @__PURE__ */ jsx22(Text17, { dimColor: true, children: "Waiting..." }) })
15654
+ ] }) : /* @__PURE__ */ jsx26(Text19, { dimColor: true, children: "Waiting..." }) })
15039
15655
  ] });
15040
15656
 
15041
15657
  // src/commands/spend-request/use-approval-polling.ts
@@ -15104,7 +15720,7 @@ function useApprovalPolling({
15104
15720
  }
15105
15721
 
15106
15722
  // src/commands/spend-request/create.tsx
15107
- import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
15723
+ import { Fragment as Fragment4, jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
15108
15724
  var CreateSpendRequest = ({
15109
15725
  repository,
15110
15726
  params,
@@ -15121,18 +15737,18 @@ var CreateSpendRequest = ({
15121
15737
  const [fileError, setFileError] = useState9("");
15122
15738
  const approvalUrl = request?.approval_url ?? "";
15123
15739
  const { exit } = useApp4();
15124
- const completeAndExit = useCallback6(
15740
+ const completeAndExit = useCallback8(
15125
15741
  (result) => {
15126
15742
  onComplete(result);
15127
15743
  exit();
15128
15744
  },
15129
15745
  [onComplete, exit]
15130
15746
  );
15131
- const onSuccess = useCallback6(
15747
+ const onSuccess = useCallback8(
15132
15748
  (result) => setRequest(result),
15133
15749
  []
15134
15750
  );
15135
- const onError = useCallback6((msg) => setError(msg), []);
15751
+ const onError = useCallback8((msg) => setError(msg), []);
15136
15752
  useApprovalPolling({
15137
15753
  status,
15138
15754
  setStatus,
@@ -15179,105 +15795,105 @@ var CreateSpendRequest = ({
15179
15795
  writeCredentialFile(outputFile, fileData, force ?? false).then((path7) => setOutputFilePath(path7)).catch((err) => setFileError(err.message));
15180
15796
  }, [status, outputFile, force, request]);
15181
15797
  if (status === "creating") {
15182
- return /* @__PURE__ */ jsx23(Box16, { children: /* @__PURE__ */ jsxs16(Text18, { color: "cyan", children: [
15183
- /* @__PURE__ */ jsx23(Spinner8, { type: "dots" }),
15798
+ return /* @__PURE__ */ jsx27(Box18, { children: /* @__PURE__ */ jsxs18(Text20, { color: "cyan", children: [
15799
+ /* @__PURE__ */ jsx27(Spinner10, { type: "dots" }),
15184
15800
  " Creating spend request..."
15185
15801
  ] }) });
15186
15802
  }
15187
15803
  if (status === "error") {
15188
- return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
15189
- /* @__PURE__ */ jsx23(Text18, { color: "red", children: "\u2717 Failed to create spend request" }),
15190
- /* @__PURE__ */ jsx23(Text18, { color: "red", children: error }),
15191
- verificationUrl && /* @__PURE__ */ jsxs16(Text18, { color: "red", children: [
15804
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
15805
+ /* @__PURE__ */ jsx27(Text20, { color: "red", children: "\u2717 Failed to create spend request" }),
15806
+ /* @__PURE__ */ jsx27(Text20, { color: "red", children: error }),
15807
+ verificationUrl && /* @__PURE__ */ jsxs18(Text20, { color: "red", children: [
15192
15808
  "Complete additional verification at: ",
15193
15809
  verificationUrl
15194
15810
  ] })
15195
15811
  ] });
15196
15812
  }
15197
15813
  if (status === "success") {
15198
- return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
15199
- /* @__PURE__ */ jsx23(Text18, { color: "green", children: "\u2713 Spend request created" }),
15200
- /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15201
- /* @__PURE__ */ jsxs16(Text18, { children: [
15814
+ return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
15815
+ /* @__PURE__ */ jsx27(Text20, { color: "green", children: "\u2713 Spend request created" }),
15816
+ /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15817
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15202
15818
  "ID: ",
15203
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request?.id })
15819
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.id })
15204
15820
  ] }),
15205
- /* @__PURE__ */ jsxs16(Text18, { children: [
15821
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15206
15822
  "Status: ",
15207
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request?.status })
15823
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.status })
15208
15824
  ] }),
15209
- /* @__PURE__ */ jsxs16(Text18, { children: [
15825
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15210
15826
  "Amount:",
15211
15827
  " ",
15212
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request?.amount != null ? `${request.amount} ${request.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
15828
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.amount != null ? `${request.amount} ${request.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
15213
15829
  ] }),
15214
- /* @__PURE__ */ jsxs16(Text18, { children: [
15830
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15215
15831
  "Merchant: ",
15216
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request?.merchant_name })
15832
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.merchant_name })
15217
15833
  ] }),
15218
- /* @__PURE__ */ jsxs16(Text18, { children: [
15834
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15219
15835
  "Line Items:",
15220
15836
  " ",
15221
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") || "N/A" })
15837
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") || "N/A" })
15222
15838
  ] }),
15223
- request?.credential_type === "shared_payment_token" && request.shared_payment_token && /* @__PURE__ */ jsxs16(Text18, { children: [
15839
+ request?.credential_type === "shared_payment_token" && request.shared_payment_token && /* @__PURE__ */ jsxs18(Text20, { children: [
15224
15840
  "Token: ",
15225
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request.shared_payment_token.id })
15841
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request.shared_payment_token.id })
15226
15842
  ] })
15227
15843
  ] }),
15228
- request?.card && !outputFile && /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginTop: 1, children: [
15229
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: "Card Details:" }),
15230
- /* @__PURE__ */ jsxs16(Text18, { children: [
15844
+ request?.card && !outputFile && /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, children: [
15845
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: "Card Details:" }),
15846
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15231
15847
  " ",
15232
15848
  "Number: ",
15233
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request.card.number })
15849
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.number })
15234
15850
  ] }),
15235
- /* @__PURE__ */ jsxs16(Text18, { children: [
15851
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15236
15852
  " ",
15237
15853
  "Brand: ",
15238
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request.card.brand })
15854
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.brand })
15239
15855
  ] }),
15240
- /* @__PURE__ */ jsxs16(Text18, { children: [
15856
+ /* @__PURE__ */ jsxs18(Text20, { children: [
15241
15857
  " ",
15242
15858
  "Expiry:",
15243
15859
  " ",
15244
- /* @__PURE__ */ jsxs16(Text18, { bold: true, children: [
15860
+ /* @__PURE__ */ jsxs18(Text20, { bold: true, children: [
15245
15861
  String(request.card.exp_month).padStart(2, "0"),
15246
15862
  "/",
15247
15863
  request.card.exp_year
15248
15864
  ] })
15249
15865
  ] }),
15250
- request.card.cvc && /* @__PURE__ */ jsxs16(Text18, { children: [
15866
+ request.card.cvc && /* @__PURE__ */ jsxs18(Text20, { children: [
15251
15867
  " ",
15252
15868
  "CVC: ",
15253
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request.card.cvc })
15869
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.cvc })
15254
15870
  ] }),
15255
- request.card.valid_until && /* @__PURE__ */ jsxs16(Text18, { children: [
15871
+ request.card.valid_until && /* @__PURE__ */ jsxs18(Text20, { children: [
15256
15872
  " ",
15257
15873
  "Valid Until: ",
15258
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request.card.valid_until })
15874
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.valid_until })
15259
15875
  ] })
15260
15876
  ] }),
15261
- request?.card && outputFile && /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginTop: 1, children: [
15262
- outputFilePath && /* @__PURE__ */ jsxs16(Text18, { color: "green", children: [
15877
+ request?.card && outputFile && /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, children: [
15878
+ outputFilePath && /* @__PURE__ */ jsxs18(Text20, { color: "green", children: [
15263
15879
  "Card credentials written to ",
15264
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: outputFilePath })
15880
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: outputFilePath })
15265
15881
  ] }),
15266
- fileError && /* @__PURE__ */ jsxs16(Text18, { color: "red", children: [
15882
+ fileError && /* @__PURE__ */ jsxs18(Text20, { color: "red", children: [
15267
15883
  "Failed to write card file: ",
15268
15884
  fileError
15269
15885
  ] })
15270
15886
  ] }),
15271
- /* @__PURE__ */ jsx23(AppDownloadQrCodes, {})
15887
+ /* @__PURE__ */ jsx27(AppDownloadQrCodes, {})
15272
15888
  ] });
15273
15889
  }
15274
- return /* @__PURE__ */ jsxs16(Fragment4, { children: [
15275
- /* @__PURE__ */ jsx23(Box16, { children: /* @__PURE__ */ jsxs16(Text18, { color: "green", children: [
15890
+ return /* @__PURE__ */ jsxs18(Fragment4, { children: [
15891
+ /* @__PURE__ */ jsx27(Box18, { children: /* @__PURE__ */ jsxs18(Text20, { color: "green", children: [
15276
15892
  "\u2713 Spend request created (ID: ",
15277
- /* @__PURE__ */ jsx23(Text18, { bold: true, children: request?.id }),
15893
+ /* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.id }),
15278
15894
  ")"
15279
15895
  ] }) }),
15280
- /* @__PURE__ */ jsx23(
15896
+ /* @__PURE__ */ jsx27(
15281
15897
  ApprovalWaitingView,
15282
15898
  {
15283
15899
  status,
@@ -15288,21 +15904,21 @@ var CreateSpendRequest = ({
15288
15904
  };
15289
15905
 
15290
15906
  // src/commands/spend-request/list.tsx
15291
- import { Box as Box17, Text as Text19, useApp as useApp5 } from "ink";
15292
- import Spinner9 from "ink-spinner";
15293
- import { useCallback as useCallback7 } from "react";
15294
- import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
15907
+ import { Box as Box19, Text as Text21, useApp as useApp5 } from "ink";
15908
+ import Spinner11 from "ink-spinner";
15909
+ import { useCallback as useCallback9 } from "react";
15910
+ import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
15295
15911
  var SpendRequestList = ({
15296
15912
  repository,
15297
15913
  includeHistory = false,
15298
15914
  onComplete
15299
15915
  }) => {
15300
15916
  const { exit } = useApp5();
15301
- const action = useCallback7(
15917
+ const action = useCallback9(
15302
15918
  () => repository.listSpendRequests({ includeHistory }),
15303
15919
  [repository, includeHistory]
15304
15920
  );
15305
- const wrappedOnComplete = useCallback7(
15921
+ const wrappedOnComplete = useCallback9(
15306
15922
  (result) => {
15307
15923
  onComplete(result);
15308
15924
  exit();
@@ -15315,29 +15931,29 @@ var SpendRequestList = ({
15315
15931
  error
15316
15932
  } = useAsyncAction(action, wrappedOnComplete);
15317
15933
  if (status === "loading") {
15318
- return /* @__PURE__ */ jsx24(Box17, { children: /* @__PURE__ */ jsxs17(Text19, { color: "cyan", children: [
15319
- /* @__PURE__ */ jsx24(Spinner9, { type: "dots" }),
15934
+ return /* @__PURE__ */ jsx28(Box19, { children: /* @__PURE__ */ jsxs19(Text21, { color: "cyan", children: [
15935
+ /* @__PURE__ */ jsx28(Spinner11, { type: "dots" }),
15320
15936
  " Loading spend requests..."
15321
15937
  ] }) });
15322
15938
  }
15323
15939
  if (status === "error") {
15324
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
15325
- /* @__PURE__ */ jsx24(Text19, { color: "red", children: "\u2717 Failed to load spend requests" }),
15326
- /* @__PURE__ */ jsx24(Text19, { color: "red", children: error })
15940
+ return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
15941
+ /* @__PURE__ */ jsx28(Text21, { color: "red", children: "\u2717 Failed to load spend requests" }),
15942
+ /* @__PURE__ */ jsx28(Text21, { color: "red", children: error })
15327
15943
  ] });
15328
15944
  }
15329
15945
  if (!requests || requests.length === 0) {
15330
- return /* @__PURE__ */ jsx24(Box17, { children: /* @__PURE__ */ jsx24(Text19, { dimColor: true, children: includeHistory ? "No spend requests found" : "No active spend requests found" }) });
15946
+ return /* @__PURE__ */ jsx28(Box19, { children: /* @__PURE__ */ jsx28(Text21, { dimColor: true, children: includeHistory ? "No spend requests found" : "No active spend requests found" }) });
15331
15947
  }
15332
- return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
15333
- /* @__PURE__ */ jsx24(Text19, { bold: true, children: includeHistory ? "All Spend Requests" : "Active Spend Requests" }),
15334
- /* @__PURE__ */ jsx24(Box17, { flexDirection: "column", marginTop: 1, children: requests.map((sr) => {
15948
+ return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
15949
+ /* @__PURE__ */ jsx28(Text21, { bold: true, children: includeHistory ? "All Spend Requests" : "Active Spend Requests" }),
15950
+ /* @__PURE__ */ jsx28(Box19, { flexDirection: "column", marginTop: 1, children: requests.map((sr) => {
15335
15951
  const statusColor = sr.status === "approved" ? "green" : sr.status === "pending_approval" ? "yellow" : "white";
15336
15952
  const amount = sr.amount != null ? `$${(sr.amount / 100).toFixed(2)} ${(sr.currency ?? "usd").toUpperCase()}` : "";
15337
- return /* @__PURE__ */ jsx24(Box17, { paddingX: 2, children: /* @__PURE__ */ jsxs17(Text19, { children: [
15338
- /* @__PURE__ */ jsx24(Text19, { dimColor: true, children: sr.id }),
15953
+ return /* @__PURE__ */ jsx28(Box19, { paddingX: 2, children: /* @__PURE__ */ jsxs19(Text21, { children: [
15954
+ /* @__PURE__ */ jsx28(Text21, { dimColor: true, children: sr.id }),
15339
15955
  " ",
15340
- /* @__PURE__ */ jsx24(Text19, { color: statusColor, children: sr.status }),
15956
+ /* @__PURE__ */ jsx28(Text21, { color: statusColor, children: sr.status }),
15341
15957
  sr.merchant_name ? ` ${sr.merchant_name}` : "",
15342
15958
  amount ? ` ${amount}` : ""
15343
15959
  ] }) }, sr.id);
@@ -15346,10 +15962,10 @@ var SpendRequestList = ({
15346
15962
  };
15347
15963
 
15348
15964
  // src/commands/spend-request/request-approval.tsx
15349
- import { Box as Box18, Text as Text20, useApp as useApp6 } from "ink";
15350
- import Spinner10 from "ink-spinner";
15351
- import { useCallback as useCallback8, useEffect as useEffect10, useState as useState10 } from "react";
15352
- import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
15965
+ import { Box as Box20, Text as Text22, useApp as useApp6 } from "ink";
15966
+ import Spinner12 from "ink-spinner";
15967
+ import { useCallback as useCallback10, useEffect as useEffect10, useState as useState10 } from "react";
15968
+ import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
15353
15969
  var RequestApproval = ({
15354
15970
  repository,
15355
15971
  id,
@@ -15361,15 +15977,15 @@ var RequestApproval = ({
15361
15977
  const [error, setError] = useState10("");
15362
15978
  const [verificationUrl, setVerificationUrl] = useState10("");
15363
15979
  const { exit } = useApp6();
15364
- const completeAndExit = useCallback8(
15980
+ const completeAndExit = useCallback10(
15365
15981
  (result2) => {
15366
15982
  onComplete(result2);
15367
15983
  exit();
15368
15984
  },
15369
15985
  [onComplete, exit]
15370
15986
  );
15371
- const onSuccess = useCallback8((r) => setResult(r), []);
15372
- const onError = useCallback8((msg) => setError(msg), []);
15987
+ const onSuccess = useCallback10((r) => setResult(r), []);
15988
+ const onError = useCallback10((msg) => setError(msg), []);
15373
15989
  useApprovalPolling({
15374
15990
  status,
15375
15991
  setStatus,
@@ -15402,50 +16018,50 @@ var RequestApproval = ({
15402
16018
  request();
15403
16019
  }, [repository, id, exit, onComplete]);
15404
16020
  if (status === "requesting") {
15405
- return /* @__PURE__ */ jsx25(Box18, { children: /* @__PURE__ */ jsxs18(Text20, { color: "cyan", children: [
15406
- /* @__PURE__ */ jsx25(Spinner10, { type: "dots" }),
16021
+ return /* @__PURE__ */ jsx29(Box20, { children: /* @__PURE__ */ jsxs20(Text22, { color: "cyan", children: [
16022
+ /* @__PURE__ */ jsx29(Spinner12, { type: "dots" }),
15407
16023
  " Requesting approval..."
15408
16024
  ] }) });
15409
16025
  }
15410
16026
  if (status === "error") {
15411
- return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
15412
- /* @__PURE__ */ jsx25(Text20, { color: "red", children: "\u2717 Failed to request approval" }),
15413
- /* @__PURE__ */ jsx25(Text20, { color: "red", children: error }),
15414
- verificationUrl && /* @__PURE__ */ jsxs18(Text20, { color: "red", children: [
16027
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
16028
+ /* @__PURE__ */ jsx29(Text22, { color: "red", children: "\u2717 Failed to request approval" }),
16029
+ /* @__PURE__ */ jsx29(Text22, { color: "red", children: error }),
16030
+ verificationUrl && /* @__PURE__ */ jsxs20(Text22, { color: "red", children: [
15415
16031
  "Complete additional verification at: ",
15416
16032
  verificationUrl
15417
16033
  ] })
15418
16034
  ] });
15419
16035
  }
15420
16036
  if (status === "success") {
15421
- return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
15422
- /* @__PURE__ */ jsx25(Text20, { color: "green", children: "\u2713 Approval completed" }),
15423
- /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15424
- /* @__PURE__ */ jsxs18(Text20, { children: [
16037
+ return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
16038
+ /* @__PURE__ */ jsx29(Text22, { color: "green", children: "\u2713 Approval completed" }),
16039
+ /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16040
+ /* @__PURE__ */ jsxs20(Text22, { children: [
15425
16041
  "ID: ",
15426
- /* @__PURE__ */ jsx25(Text20, { bold: true, children: result?.id })
16042
+ /* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.id })
15427
16043
  ] }),
15428
- /* @__PURE__ */ jsxs18(Text20, { children: [
16044
+ /* @__PURE__ */ jsxs20(Text22, { children: [
15429
16045
  "Status: ",
15430
- /* @__PURE__ */ jsx25(Text20, { bold: true, children: result?.status })
16046
+ /* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.status })
15431
16047
  ] }),
15432
- /* @__PURE__ */ jsxs18(Text20, { children: [
16048
+ /* @__PURE__ */ jsxs20(Text22, { children: [
15433
16049
  "Amount:",
15434
16050
  " ",
15435
- /* @__PURE__ */ jsx25(Text20, { bold: true, children: result?.amount != null ? `${result.amount} ${result.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
16051
+ /* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.amount != null ? `${result.amount} ${result.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
15436
16052
  ] }),
15437
- /* @__PURE__ */ jsxs18(Text20, { children: [
16053
+ /* @__PURE__ */ jsxs20(Text22, { children: [
15438
16054
  "Merchant: ",
15439
- /* @__PURE__ */ jsx25(Text20, { bold: true, children: result?.merchant_name })
16055
+ /* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.merchant_name })
15440
16056
  ] }),
15441
- result?.credential_type === "shared_payment_token" && result.shared_payment_token && /* @__PURE__ */ jsxs18(Text20, { children: [
16057
+ result?.credential_type === "shared_payment_token" && result.shared_payment_token && /* @__PURE__ */ jsxs20(Text22, { children: [
15442
16058
  "Token: ",
15443
- /* @__PURE__ */ jsx25(Text20, { bold: true, children: result.shared_payment_token.id })
16059
+ /* @__PURE__ */ jsx29(Text22, { bold: true, children: result.shared_payment_token.id })
15444
16060
  ] })
15445
16061
  ] })
15446
16062
  ] });
15447
16063
  }
15448
- return /* @__PURE__ */ jsx25(
16064
+ return /* @__PURE__ */ jsx29(
15449
16065
  ApprovalWaitingView,
15450
16066
  {
15451
16067
  status,
@@ -15455,10 +16071,10 @@ var RequestApproval = ({
15455
16071
  };
15456
16072
 
15457
16073
  // src/commands/spend-request/retrieve.tsx
15458
- import { Box as Box19, Text as Text21 } from "ink";
15459
- import Spinner11 from "ink-spinner";
16074
+ import { Box as Box21, Text as Text23 } from "ink";
16075
+ import Spinner13 from "ink-spinner";
15460
16076
  import { useEffect as useEffect11, useRef as useRef5, useState as useState11 } from "react";
15461
- import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
16077
+ import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
15462
16078
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
15463
16079
  "approved",
15464
16080
  "denied",
@@ -15582,121 +16198,121 @@ var RetrieveSpendRequest = ({
15582
16198
  };
15583
16199
  }, [phase, repository, id, include, timeout, onComplete]);
15584
16200
  if (phase === "fetching") {
15585
- return /* @__PURE__ */ jsx26(Box19, { children: /* @__PURE__ */ jsxs19(Text21, { color: "cyan", children: [
15586
- /* @__PURE__ */ jsx26(Spinner11, { type: "dots" }),
16201
+ return /* @__PURE__ */ jsx30(Box21, { children: /* @__PURE__ */ jsxs21(Text23, { color: "cyan", children: [
16202
+ /* @__PURE__ */ jsx30(Spinner13, { type: "dots" }),
15587
16203
  " Retrieving spend request ",
15588
16204
  id,
15589
16205
  "..."
15590
16206
  ] }) });
15591
16207
  }
15592
16208
  if (phase === "error") {
15593
- return /* @__PURE__ */ jsx26(Box19, { flexDirection: "column", children: /* @__PURE__ */ jsxs19(Text21, { color: "red", children: [
16209
+ return /* @__PURE__ */ jsx30(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsxs21(Text23, { color: "red", children: [
15594
16210
  "\u2717 ",
15595
16211
  error
15596
16212
  ] }) });
15597
16213
  }
15598
16214
  if (phase === "timeout") {
15599
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
15600
- /* @__PURE__ */ jsxs19(Text21, { color: "yellow", children: [
16215
+ return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16216
+ /* @__PURE__ */ jsxs21(Text23, { color: "yellow", children: [
15601
16217
  "\u2717 Timed out waiting for approval after ",
15602
16218
  timeout,
15603
16219
  "s"
15604
16220
  ] }),
15605
- request && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15606
- /* @__PURE__ */ jsxs19(Text21, { children: [
16221
+ request && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16222
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15607
16223
  "ID: ",
15608
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.id })
16224
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.id })
15609
16225
  ] }),
15610
- /* @__PURE__ */ jsxs19(Text21, { children: [
16226
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15611
16227
  "Status: ",
15612
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.status })
16228
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.status })
15613
16229
  ] })
15614
16230
  ] })
15615
16231
  ] });
15616
16232
  }
15617
16233
  if (phase === "polling") {
15618
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
15619
- /* @__PURE__ */ jsx26(Box19, { children: /* @__PURE__ */ jsxs19(Text21, { color: "cyan", children: [
15620
- /* @__PURE__ */ jsx26(Spinner11, { type: "dots" }),
16234
+ return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16235
+ /* @__PURE__ */ jsx30(Box21, { children: /* @__PURE__ */ jsxs21(Text23, { color: "cyan", children: [
16236
+ /* @__PURE__ */ jsx30(Spinner13, { type: "dots" }),
15621
16237
  " Awaiting approval... (",
15622
16238
  elapsed,
15623
16239
  "s elapsed)"
15624
16240
  ] }) }),
15625
- request?.approval_url && /* @__PURE__ */ jsx26(Box19, { marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs19(Text21, { dimColor: true, children: [
16241
+ request?.approval_url && /* @__PURE__ */ jsx30(Box21, { marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs21(Text23, { dimColor: true, children: [
15626
16242
  "Approval URL: ",
15627
- /* @__PURE__ */ jsx26(Text21, { color: "cyan", children: request.approval_url })
16243
+ /* @__PURE__ */ jsx30(Text23, { color: "cyan", children: request.approval_url })
15628
16244
  ] }) })
15629
16245
  ] });
15630
16246
  }
15631
16247
  if (phase === "finalized") {
15632
16248
  const psd = request?.payment_status_details;
15633
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
15634
- /* @__PURE__ */ jsxs19(Text21, { color: "yellow", children: [
16249
+ return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16250
+ /* @__PURE__ */ jsxs21(Text23, { color: "yellow", children: [
15635
16251
  "Spend request reached terminal status: ",
15636
16252
  request?.status
15637
16253
  ] }),
15638
- /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15639
- /* @__PURE__ */ jsxs19(Text21, { children: [
16254
+ /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16255
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15640
16256
  "ID: ",
15641
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.id })
16257
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.id })
15642
16258
  ] }),
15643
- /* @__PURE__ */ jsxs19(Text21, { children: [
16259
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15644
16260
  "Status: ",
15645
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.status })
16261
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.status })
15646
16262
  ] }),
15647
- psd && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15648
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: "Payment Details:" }),
15649
- /* @__PURE__ */ jsxs19(Text21, { children: [
16263
+ psd && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16264
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: "Payment Details:" }),
16265
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15650
16266
  " ",
15651
16267
  "Outcome:",
15652
16268
  " ",
15653
- /* @__PURE__ */ jsx26(Text21, { bold: true, color: psd.outcome === "success" ? "green" : "red", children: psd.outcome })
16269
+ /* @__PURE__ */ jsx30(Text23, { bold: true, color: psd.outcome === "success" ? "green" : "red", children: psd.outcome })
15654
16270
  ] }),
15655
- psd.code && /* @__PURE__ */ jsxs19(Text21, { children: [
16271
+ psd.code && /* @__PURE__ */ jsxs21(Text23, { children: [
15656
16272
  " ",
15657
16273
  "Code: ",
15658
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: psd.code })
16274
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: psd.code })
15659
16275
  ] }),
15660
- psd.decline_code && /* @__PURE__ */ jsxs19(Text21, { children: [
16276
+ psd.decline_code && /* @__PURE__ */ jsxs21(Text23, { children: [
15661
16277
  " ",
15662
16278
  "Decline Reason: ",
15663
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: psd.decline_code })
16279
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: psd.decline_code })
15664
16280
  ] }),
15665
- /* @__PURE__ */ jsxs19(Text21, { children: [
16281
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15666
16282
  " ",
15667
16283
  "Amount:",
15668
16284
  " ",
15669
- /* @__PURE__ */ jsxs19(Text21, { bold: true, children: [
16285
+ /* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
15670
16286
  psd.amount,
15671
16287
  " ",
15672
16288
  psd.currency
15673
16289
  ] })
15674
16290
  ] }),
15675
- psd.created && /* @__PURE__ */ jsxs19(Text21, { children: [
16291
+ psd.created && /* @__PURE__ */ jsxs21(Text23, { children: [
15676
16292
  " ",
15677
16293
  "Charged At:",
15678
16294
  " ",
15679
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: new Date(psd.created * 1e3).toISOString() })
16295
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: new Date(psd.created * 1e3).toISOString() })
15680
16296
  ] }),
15681
- psd.refund_details && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15682
- /* @__PURE__ */ jsxs19(Text21, { bold: true, children: [
16297
+ psd.refund_details && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16298
+ /* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
15683
16299
  " ",
15684
16300
  "Refund:"
15685
16301
  ] }),
15686
- /* @__PURE__ */ jsxs19(Text21, { children: [
16302
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15687
16303
  " ",
15688
16304
  "Amount:",
15689
16305
  " ",
15690
- /* @__PURE__ */ jsxs19(Text21, { bold: true, children: [
16306
+ /* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
15691
16307
  psd.refund_details.amount,
15692
16308
  " ",
15693
16309
  psd.refund_details.currency
15694
16310
  ] })
15695
16311
  ] }),
15696
- /* @__PURE__ */ jsxs19(Text21, { children: [
16312
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15697
16313
  " ",
15698
16314
  "State: ",
15699
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: psd.refund_details.state })
16315
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: psd.refund_details.state })
15700
16316
  ] })
15701
16317
  ] })
15702
16318
  ] })
@@ -15704,71 +16320,71 @@ var RetrieveSpendRequest = ({
15704
16320
  ] });
15705
16321
  }
15706
16322
  if (phase === "declined") {
15707
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
15708
- /* @__PURE__ */ jsx26(Text21, { color: "red", children: "\u2717 Spend request declined" }),
15709
- /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15710
- /* @__PURE__ */ jsxs19(Text21, { children: [
16323
+ return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16324
+ /* @__PURE__ */ jsx30(Text23, { color: "red", children: "\u2717 Spend request declined" }),
16325
+ /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16326
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15711
16327
  "ID: ",
15712
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.id })
16328
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.id })
15713
16329
  ] }),
15714
- /* @__PURE__ */ jsxs19(Text21, { children: [
16330
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15715
16331
  "Status:",
15716
16332
  " ",
15717
- /* @__PURE__ */ jsx26(Text21, { bold: true, color: "red", children: request?.status })
16333
+ /* @__PURE__ */ jsx30(Text23, { bold: true, color: "red", children: request?.status })
15718
16334
  ] }),
15719
- /* @__PURE__ */ jsxs19(Text21, { children: [
16335
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15720
16336
  "Amount:",
15721
16337
  " ",
15722
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
16338
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
15723
16339
  ] }),
15724
- /* @__PURE__ */ jsxs19(Text21, { children: [
16340
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15725
16341
  "Merchant: ",
15726
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.merchant_name })
16342
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.merchant_name })
15727
16343
  ] })
15728
16344
  ] })
15729
16345
  ] });
15730
16346
  }
15731
- return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
15732
- /* @__PURE__ */ jsx26(Text21, { color: "green", children: "\u2713 Spend request approved" }),
15733
- /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15734
- /* @__PURE__ */ jsxs19(Text21, { children: [
16347
+ return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16348
+ /* @__PURE__ */ jsx30(Text23, { color: "green", children: "\u2713 Spend request approved" }),
16349
+ /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16350
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15735
16351
  "ID: ",
15736
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.id })
16352
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.id })
15737
16353
  ] }),
15738
- /* @__PURE__ */ jsxs19(Text21, { children: [
16354
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15739
16355
  "Status:",
15740
16356
  " ",
15741
- /* @__PURE__ */ jsx26(Text21, { bold: true, color: "green", children: request?.status })
16357
+ /* @__PURE__ */ jsx30(Text23, { bold: true, color: "green", children: request?.status })
15742
16358
  ] }),
15743
- /* @__PURE__ */ jsxs19(Text21, { children: [
16359
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15744
16360
  "Amount:",
15745
16361
  " ",
15746
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
16362
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
15747
16363
  ] }),
15748
- /* @__PURE__ */ jsxs19(Text21, { children: [
16364
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15749
16365
  "Merchant: ",
15750
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.merchant_name })
16366
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.merchant_name })
15751
16367
  ] }),
15752
- /* @__PURE__ */ jsxs19(Text21, { children: [
16368
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15753
16369
  "Line Items:",
15754
16370
  " ",
15755
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") })
16371
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") })
15756
16372
  ] }),
15757
- request?.link_pay_token && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15758
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: "Link Pay Token:" }),
15759
- /* @__PURE__ */ jsxs19(Text21, { children: [
16373
+ request?.link_pay_token && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16374
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: "Link Pay Token:" }),
16375
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15760
16376
  " ",
15761
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.link_pay_token })
16377
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.link_pay_token })
15762
16378
  ] })
15763
16379
  ] }),
15764
- request?.payment_status_details && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15765
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: "Last Payment Attempt:" }),
15766
- /* @__PURE__ */ jsxs19(Text21, { children: [
16380
+ request?.payment_status_details && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16381
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: "Last Payment Attempt:" }),
16382
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15767
16383
  " ",
15768
16384
  "Outcome:",
15769
16385
  " ",
15770
- /* @__PURE__ */ jsx26(
15771
- Text21,
16386
+ /* @__PURE__ */ jsx30(
16387
+ Text23,
15772
16388
  {
15773
16389
  bold: true,
15774
16390
  color: request.payment_status_details.outcome === "success" ? "green" : "red",
@@ -15776,79 +16392,79 @@ var RetrieveSpendRequest = ({
15776
16392
  }
15777
16393
  )
15778
16394
  ] }),
15779
- request.payment_status_details.code && /* @__PURE__ */ jsxs19(Text21, { children: [
16395
+ request.payment_status_details.code && /* @__PURE__ */ jsxs21(Text23, { children: [
15780
16396
  " ",
15781
16397
  "Code:",
15782
16398
  " ",
15783
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.payment_status_details.code })
16399
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.payment_status_details.code })
15784
16400
  ] }),
15785
- request.payment_status_details.decline_code && /* @__PURE__ */ jsxs19(Text21, { children: [
16401
+ request.payment_status_details.decline_code && /* @__PURE__ */ jsxs21(Text23, { children: [
15786
16402
  " ",
15787
16403
  "Decline Reason:",
15788
16404
  " ",
15789
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.payment_status_details.decline_code })
16405
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.payment_status_details.decline_code })
15790
16406
  ] })
15791
16407
  ] }),
15792
- request?.shared_payment_token && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15793
- /* @__PURE__ */ jsxs19(Text21, { bold: true, children: [
16408
+ request?.shared_payment_token && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16409
+ /* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
15794
16410
  "\x1B]8;;https://docs.stripe.com/agentic-commerce/concepts/shared-payment-tokens\x07",
15795
16411
  "Shared Payment Token",
15796
16412
  "\x1B]8;;\x07",
15797
16413
  ":"
15798
16414
  ] }),
15799
- /* @__PURE__ */ jsxs19(Text21, { children: [
16415
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15800
16416
  " ",
15801
16417
  "Token: ",
15802
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.shared_payment_token.id })
16418
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.shared_payment_token.id })
15803
16419
  ] })
15804
16420
  ] }),
15805
- request?.card && !outputFile && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15806
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: "Card Details:" }),
15807
- /* @__PURE__ */ jsxs19(Text21, { children: [
16421
+ request?.card && !outputFile && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16422
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: "Card Details:" }),
16423
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15808
16424
  " ",
15809
16425
  "Number: ",
15810
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.card.number })
16426
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.card.number })
15811
16427
  ] }),
15812
- /* @__PURE__ */ jsxs19(Text21, { children: [
16428
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15813
16429
  " ",
15814
16430
  "Brand: ",
15815
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request?.card.brand })
16431
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.card.brand })
15816
16432
  ] }),
15817
- /* @__PURE__ */ jsxs19(Text21, { children: [
16433
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15818
16434
  " ",
15819
16435
  "Expiry:",
15820
16436
  " ",
15821
- /* @__PURE__ */ jsxs19(Text21, { bold: true, children: [
16437
+ /* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
15822
16438
  String(request?.card.exp_month).padStart(2, "0"),
15823
16439
  "/",
15824
16440
  request?.card.exp_year
15825
16441
  ] })
15826
16442
  ] }),
15827
- request?.card.cvc && /* @__PURE__ */ jsxs19(Text21, { children: [
16443
+ request?.card.cvc && /* @__PURE__ */ jsxs21(Text23, { children: [
15828
16444
  " ",
15829
16445
  "CVC: ",
15830
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.card.cvc })
16446
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.card.cvc })
15831
16447
  ] }),
15832
- request?.card.valid_until && /* @__PURE__ */ jsxs19(Text21, { children: [
16448
+ request?.card.valid_until && /* @__PURE__ */ jsxs21(Text23, { children: [
15833
16449
  " ",
15834
16450
  "Valid Until: ",
15835
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: request.card.valid_until })
16451
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: request.card.valid_until })
15836
16452
  ] }),
15837
- request?.card.billing_address && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15838
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: " Billing Address:" }),
15839
- /* @__PURE__ */ jsxs19(Text21, { children: [
16453
+ request?.card.billing_address && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16454
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: " Billing Address:" }),
16455
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15840
16456
  " ",
15841
16457
  request.card.billing_address.name
15842
16458
  ] }),
15843
- /* @__PURE__ */ jsxs19(Text21, { children: [
16459
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15844
16460
  " ",
15845
16461
  request.card.billing_address.line1
15846
16462
  ] }),
15847
- request.card.billing_address.line2 && /* @__PURE__ */ jsxs19(Text21, { children: [
16463
+ request.card.billing_address.line2 && /* @__PURE__ */ jsxs21(Text23, { children: [
15848
16464
  " ",
15849
16465
  request.card.billing_address.line2
15850
16466
  ] }),
15851
- /* @__PURE__ */ jsxs19(Text21, { children: [
16467
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15852
16468
  " ",
15853
16469
  [
15854
16470
  request.card.billing_address.city,
@@ -15856,18 +16472,18 @@ var RetrieveSpendRequest = ({
15856
16472
  request.card.billing_address.postal_code
15857
16473
  ].filter(Boolean).join(", ")
15858
16474
  ] }),
15859
- /* @__PURE__ */ jsxs19(Text21, { children: [
16475
+ /* @__PURE__ */ jsxs21(Text23, { children: [
15860
16476
  " ",
15861
16477
  request.card.billing_address.country
15862
16478
  ] })
15863
16479
  ] })
15864
16480
  ] }),
15865
- request?.card && outputFile && /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", marginTop: 1, children: [
15866
- outputFilePath && /* @__PURE__ */ jsxs19(Text21, { color: "green", children: [
16481
+ request?.card && outputFile && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16482
+ outputFilePath && /* @__PURE__ */ jsxs21(Text23, { color: "green", children: [
15867
16483
  "Card credentials written to ",
15868
- /* @__PURE__ */ jsx26(Text21, { bold: true, children: outputFilePath })
16484
+ /* @__PURE__ */ jsx30(Text23, { bold: true, children: outputFilePath })
15869
16485
  ] }),
15870
- fileError && /* @__PURE__ */ jsxs19(Text21, { color: "red", children: [
16486
+ fileError && /* @__PURE__ */ jsxs21(Text23, { color: "red", children: [
15871
16487
  "Failed to write card file: ",
15872
16488
  fileError
15873
16489
  ] })
@@ -15877,140 +16493,143 @@ var RetrieveSpendRequest = ({
15877
16493
  };
15878
16494
 
15879
16495
  // src/commands/spend-request/schema.ts
15880
- import { z as z8 } from "incur";
15881
- var createOptions = z8.object({
15882
- paymentMethodId: z8.string().optional().describe("Payment method ID"),
15883
- credentialType: z8.enum(["shared_payment_token", "card"]).default("card").describe(
16496
+ import { z as z10 } from "incur";
16497
+ var createOptions = z10.object({
16498
+ paymentMethodId: z10.string().optional().describe("Payment method ID"),
16499
+ credentialType: z10.enum(["shared_payment_token", "card"]).default("card").describe(
15884
16500
  '"card" for checkout forms/Stripe Elements; "shared_payment_token" for HTTP 402/machine payment flows'
15885
16501
  ),
15886
- networkId: z8.string().optional().describe(
16502
+ networkId: z10.string().optional().describe(
15887
16503
  "Network ID (required for shared_payment_token) \u2014 use `link-cli mpp decode` to extract"
15888
16504
  ),
15889
- amount: z8.coerce.number().int().positive().max(5e5).describe("Amount in cents, max 500000 ($5,000.00)"),
15890
- currency: z8.string().length(3).default("usd").describe("Currency code"),
15891
- merchantName: z8.string().optional().describe(
16505
+ amount: z10.coerce.number().int().positive().max(5e5).describe("Amount in cents, max 500000 ($5,000.00)"),
16506
+ currency: z10.string().length(3).default("usd").describe("Currency code"),
16507
+ merchantName: z10.string().optional().describe(
15892
16508
  "Merchant name (required for card; forbidden for shared_payment_token)"
15893
16509
  ),
15894
- merchantUrl: z8.string().optional().describe(
16510
+ merchantUrl: z10.string().optional().describe(
15895
16511
  "Merchant URL (required for card; forbidden for shared_payment_token)"
15896
16512
  ),
15897
- context: z8.string().min(100).describe(
16513
+ context: z10.string().min(100).describe(
15898
16514
  "Min 100 chars \u2014 describe the purchase and rationale; the user reads this when approving"
15899
16515
  ),
15900
- lineItem: z8.array(z8.union([z8.string(), z8.record(z8.string(), z8.unknown())])).default([]).describe(
16516
+ lineItem: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
15901
16517
  'Line item (repeatable, key:value format). Keys: name (required), quantity, unit_amount, description, sku, url, image_url, product_url. Example: "name:Shoes,unit_amount:5000,quantity:2"'
15902
16518
  ),
15903
- total: z8.array(z8.union([z8.string(), z8.record(z8.string(), z8.unknown())])).default([]).describe(
16519
+ total: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
15904
16520
  'Total (repeatable, key:value format). Keys: type (required; one of: subtotal, tax, total, items_base_amount, items_discount, discount, fulfillment, shipping, fee, gift_wrap, tip, store_credit), display_text (required), amount (required). Example: "type:total,display_text:Total,amount:5000"'
15905
16521
  ),
15906
- requestApproval: z8.boolean().default(true).describe("Request approval and poll until approved/denied/expired"),
15907
- test: z8.boolean().default(false).describe(
16522
+ requestApproval: z10.boolean().default(true).describe("Request approval and poll until approved/denied/expired"),
16523
+ test: z10.boolean().default(false).describe(
15908
16524
  "Use test mode (creates testmode credentials from test card data)"
15909
16525
  ),
15910
- approve: z8.boolean().default(false).describe(""),
15911
- outputFile: z8.string().optional().describe(
16526
+ approve: z10.boolean().default(false).describe(""),
16527
+ outputFile: z10.string().optional().describe(
15912
16528
  "Write full card credentials to this file path; stdout shows redacted card data only"
15913
16529
  ),
15914
- force: z8.boolean().default(false).describe("Overwrite output file if it already exists")
16530
+ force: z10.boolean().default(false).describe("Overwrite output file if it already exists"),
16531
+ approvalDetail: z10.union([z10.string(), z10.record(z10.string(), z10.unknown())]).optional().describe(
16532
+ "Approval details object (MCP/agent: pass as object; CLI: pass as JSON string). Required fields: approved_at (unix timestamp), approval_method (click|programmatic|voice), app_name, external_user_id. Optional: ip_address, user_agent, device_type (mobile|web), agent_log_id, external_user_name, external_session_id, authentication_method (biometric_face|biometric_fingerprint|passkey)."
16533
+ )
15915
16534
  });
15916
- var listOptions = z8.object({
15917
- includeHistory: z8.boolean().default(false).describe("Include expired and terminal spend requests")
16535
+ var listOptions3 = z10.object({
16536
+ includeHistory: z10.boolean().default(false).describe("Include expired and terminal spend requests")
15918
16537
  });
15919
- var retrieveOptions = z8.object({
15920
- timeout: z8.coerce.number().default(600).describe(
16538
+ var retrieveOptions = z10.object({
16539
+ timeout: z10.coerce.number().default(600).describe(
15921
16540
  "Polling timeout in seconds. When reached during active polling, exits non-zero with POLLING_TIMEOUT. Default exceeds the server-side spend-request expiry so polling outlives the request itself."
15922
16541
  ),
15923
- interval: z8.coerce.number().default(0).describe(
16542
+ interval: z10.coerce.number().default(0).describe(
15924
16543
  "Poll interval in seconds. When > 0, polls until status is terminal, timeout is reached, or max attempts are exhausted."
15925
16544
  ),
15926
- maxAttempts: z8.coerce.number().default(0).describe(
16545
+ maxAttempts: z10.coerce.number().default(0).describe(
15927
16546
  "Max poll attempts. 0 = unlimited. Exhaustion during active polling exits non-zero with POLLING_TIMEOUT."
15928
16547
  ),
15929
- include: z8.array(z8.string()).default([]).describe("Include extra data (repeatable, e.g. --include card)"),
15930
- outputFile: z8.string().optional().describe(
16548
+ include: z10.array(z10.string()).default([]).describe("Include extra data (repeatable, e.g. --include card)"),
16549
+ outputFile: z10.string().optional().describe(
15931
16550
  "Write full card credentials to this file path; stdout shows redacted card data only"
15932
16551
  ),
15933
- force: z8.boolean().default(false).describe("Overwrite output file if it already exists")
16552
+ force: z10.boolean().default(false).describe("Overwrite output file if it already exists")
15934
16553
  });
15935
- var updateOptions = z8.object({
15936
- paymentMethodId: z8.string().optional().describe("Payment method ID"),
15937
- amount: z8.coerce.number().optional().describe("Amount in cents"),
15938
- merchantUrl: z8.string().optional().describe("Merchant URL"),
15939
- profileId: z8.string().optional().describe("Profile ID"),
15940
- merchantId: z8.string().optional().describe("Merchant ID"),
15941
- currency: z8.string().optional().describe("Currency code"),
15942
- lineItem: z8.array(z8.union([z8.string(), z8.record(z8.string(), z8.unknown())])).default([]).describe(
16554
+ var updateOptions = z10.object({
16555
+ paymentMethodId: z10.string().optional().describe("Payment method ID"),
16556
+ amount: z10.coerce.number().optional().describe("Amount in cents"),
16557
+ merchantUrl: z10.string().optional().describe("Merchant URL"),
16558
+ profileId: z10.string().optional().describe("Profile ID"),
16559
+ merchantId: z10.string().optional().describe("Merchant ID"),
16560
+ currency: z10.string().optional().describe("Currency code"),
16561
+ lineItem: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
15943
16562
  'Line item (repeatable, key:value format). Keys: name (required), quantity, unit_amount, description, sku, url, image_url, product_url. Example: "name:Shoes,unit_amount:5000,quantity:2"'
15944
16563
  ),
15945
- total: z8.array(z8.union([z8.string(), z8.record(z8.string(), z8.unknown())])).default([]).describe(
16564
+ total: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
15946
16565
  'Total (repeatable, key:value format). Keys: type (required; one of: subtotal, tax, total, items_base_amount, items_discount, discount, fulfillment, shipping, fee, gift_wrap, tip, store_credit), display_text (required), amount (required). Example: "type:total,display_text:Total,amount:5000"'
15947
16566
  )
15948
16567
  });
15949
16568
 
15950
16569
  // src/commands/spend-request/update.tsx
15951
- import { Box as Box20, Text as Text22 } from "ink";
15952
- import Spinner12 from "ink-spinner";
15953
- import { useCallback as useCallback9 } from "react";
15954
- import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
16570
+ import { Box as Box22, Text as Text24 } from "ink";
16571
+ import Spinner14 from "ink-spinner";
16572
+ import { useCallback as useCallback11 } from "react";
16573
+ import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
15955
16574
  var UpdateSpendRequest = ({
15956
16575
  repository,
15957
16576
  id,
15958
16577
  params,
15959
16578
  onComplete
15960
16579
  }) => {
15961
- const action = useCallback9(
16580
+ const action = useCallback11(
15962
16581
  () => repository.updateSpendRequest(id, params),
15963
16582
  [repository, id, params]
15964
16583
  );
15965
16584
  const { status, data: request, error } = useAsyncAction(action, onComplete);
15966
16585
  if (status === "loading") {
15967
- return /* @__PURE__ */ jsx27(Box20, { children: /* @__PURE__ */ jsxs20(Text22, { color: "cyan", children: [
15968
- /* @__PURE__ */ jsx27(Spinner12, { type: "dots" }),
16586
+ return /* @__PURE__ */ jsx31(Box22, { children: /* @__PURE__ */ jsxs22(Text24, { color: "cyan", children: [
16587
+ /* @__PURE__ */ jsx31(Spinner14, { type: "dots" }),
15969
16588
  " Updating spend request ",
15970
16589
  id,
15971
16590
  "..."
15972
16591
  ] }) });
15973
16592
  }
15974
16593
  if (status === "error") {
15975
- return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
15976
- /* @__PURE__ */ jsx27(Text22, { color: "red", children: "\u2717 Failed to update spend request" }),
15977
- /* @__PURE__ */ jsx27(Text22, { color: "red", children: error })
16594
+ return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
16595
+ /* @__PURE__ */ jsx31(Text24, { color: "red", children: "\u2717 Failed to update spend request" }),
16596
+ /* @__PURE__ */ jsx31(Text24, { color: "red", children: error })
15978
16597
  ] });
15979
16598
  }
15980
- return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
15981
- /* @__PURE__ */ jsx27(Text22, { color: "green", children: "\u2713 Spend request updated" }),
15982
- /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
15983
- /* @__PURE__ */ jsxs20(Text22, { children: [
16599
+ return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
16600
+ /* @__PURE__ */ jsx31(Text24, { color: "green", children: "\u2713 Spend request updated" }),
16601
+ /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16602
+ /* @__PURE__ */ jsxs22(Text24, { children: [
15984
16603
  "ID: ",
15985
- /* @__PURE__ */ jsx27(Text22, { bold: true, children: request?.id })
16604
+ /* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.id })
15986
16605
  ] }),
15987
- /* @__PURE__ */ jsxs20(Text22, { children: [
16606
+ /* @__PURE__ */ jsxs22(Text24, { children: [
15988
16607
  "Status: ",
15989
- /* @__PURE__ */ jsx27(Text22, { bold: true, children: request?.status })
16608
+ /* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.status })
15990
16609
  ] }),
15991
- /* @__PURE__ */ jsxs20(Text22, { children: [
16610
+ /* @__PURE__ */ jsxs22(Text24, { children: [
15992
16611
  "Amount:",
15993
16612
  " ",
15994
- /* @__PURE__ */ jsx27(Text22, { bold: true, children: (() => {
16613
+ /* @__PURE__ */ jsx31(Text24, { bold: true, children: (() => {
15995
16614
  const t = request?.totals.find((t2) => t2.type === "total");
15996
16615
  return t ? String(t.amount) : "N/A";
15997
16616
  })() })
15998
16617
  ] }),
15999
- /* @__PURE__ */ jsxs20(Text22, { children: [
16618
+ /* @__PURE__ */ jsxs22(Text24, { children: [
16000
16619
  "Merchant: ",
16001
- /* @__PURE__ */ jsx27(Text22, { bold: true, children: request?.merchant_name })
16620
+ /* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.merchant_name })
16002
16621
  ] }),
16003
- /* @__PURE__ */ jsxs20(Text22, { children: [
16622
+ /* @__PURE__ */ jsxs22(Text24, { children: [
16004
16623
  "Line Items:",
16005
16624
  " ",
16006
- /* @__PURE__ */ jsx27(Text22, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") })
16625
+ /* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") })
16007
16626
  ] })
16008
16627
  ] })
16009
16628
  ] });
16010
16629
  };
16011
16630
 
16012
16631
  // src/commands/spend-request/index.tsx
16013
- import { jsx as jsx28 } from "react/jsx-runtime";
16632
+ import { jsx as jsx32 } from "react/jsx-runtime";
16014
16633
  async function applyOutputFile(request, outputFile, force) {
16015
16634
  if (!outputFile || !request.card) return request;
16016
16635
  const fileData = {
@@ -16029,19 +16648,19 @@ async function applyOutputFile(request, outputFile, force) {
16029
16648
  };
16030
16649
  }
16031
16650
  function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16032
- const cli2 = Cli9.create("spend-request", {
16651
+ const cli2 = Cli11.create("spend-request", {
16033
16652
  description: "Spend request management commands"
16034
16653
  });
16035
16654
  cli2.command("list", {
16036
16655
  description: "List spend requests. By default returns only active requests (created, pending_approval, approved). Use --include-history to return all spend requests including expired and terminal states.",
16037
16656
  outputPolicy: "agent-only",
16038
- options: listOptions,
16657
+ options: listOptions3,
16039
16658
  middleware: [requireAuth(authStorage2, envAccessToken2)],
16040
16659
  async run(c) {
16041
16660
  const opts = { includeHistory: c.options.includeHistory ?? false };
16042
16661
  if (!c.agent && !c.formatExplicit) {
16043
16662
  return renderInteractive(
16044
- /* @__PURE__ */ jsx28(
16663
+ /* @__PURE__ */ jsx32(
16045
16664
  SpendRequestList,
16046
16665
  {
16047
16666
  repository,
@@ -16105,6 +16724,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16105
16724
  const totals = opts.total?.length ? opts.total.map(
16106
16725
  (item) => typeof item === "string" ? parseTotalFlag(item) : item
16107
16726
  ) : void 0;
16727
+ const approvalDetails = opts.approvalDetail !== void 0 ? typeof opts.approvalDetail === "string" ? JSON.parse(opts.approvalDetail) : opts.approvalDetail : void 0;
16108
16728
  const createParams = {
16109
16729
  payment_details: opts.paymentMethodId,
16110
16730
  credential_type: credentialType,
@@ -16118,14 +16738,15 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16118
16738
  totals,
16119
16739
  request_approval: requestApproval || void 0,
16120
16740
  test: opts.test ? true : void 0,
16121
- approve: opts.approve ? true : void 0
16741
+ approve: opts.approve ? true : void 0,
16742
+ approval_details: approvalDetails
16122
16743
  };
16123
16744
  const outputFile = opts.outputFile;
16124
16745
  const forceOverwrite = opts.force;
16125
16746
  if (!c.agent && !c.formatExplicit) {
16126
16747
  let capturedResult = void 0;
16127
16748
  return renderInteractive(
16128
- /* @__PURE__ */ jsx28(
16749
+ /* @__PURE__ */ jsx32(
16129
16750
  CreateSpendRequest,
16130
16751
  {
16131
16752
  repository,
@@ -16185,8 +16806,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16185
16806
  });
16186
16807
  cli2.command("update", {
16187
16808
  description: "Update a spend request",
16188
- args: z9.object({
16189
- id: z9.string().describe("Spend request ID")
16809
+ args: z11.object({
16810
+ id: z11.string().describe("Spend request ID")
16190
16811
  }),
16191
16812
  options: updateOptions,
16192
16813
  outputPolicy: "agent-only",
@@ -16214,7 +16835,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16214
16835
  if (!c.agent && !c.formatExplicit) {
16215
16836
  let capturedResult = null;
16216
16837
  return renderInteractive(
16217
- /* @__PURE__ */ jsx28(
16838
+ /* @__PURE__ */ jsx32(
16218
16839
  UpdateSpendRequest,
16219
16840
  {
16220
16841
  repository,
@@ -16237,8 +16858,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16237
16858
  });
16238
16859
  cli2.command("request-approval", {
16239
16860
  description: "Request approval for a spend request",
16240
- args: z9.object({
16241
- id: z9.string().describe("Spend request ID")
16861
+ args: z11.object({
16862
+ id: z11.string().describe("Spend request ID")
16242
16863
  }),
16243
16864
  outputPolicy: "agent-only",
16244
16865
  async *run(c) {
@@ -16247,7 +16868,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16247
16868
  if (!c.agent && !c.formatExplicit) {
16248
16869
  let capturedResult = void 0;
16249
16870
  return renderInteractive(
16250
- /* @__PURE__ */ jsx28(
16871
+ /* @__PURE__ */ jsx32(
16251
16872
  RequestApproval,
16252
16873
  {
16253
16874
  repository,
@@ -16292,8 +16913,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16292
16913
  });
16293
16914
  cli2.command("retrieve", {
16294
16915
  description: "Retrieve a spend request",
16295
- args: z9.object({
16296
- id: z9.string().describe("Spend request ID")
16916
+ args: z11.object({
16917
+ id: z11.string().describe("Spend request ID")
16297
16918
  }),
16298
16919
  options: retrieveOptions,
16299
16920
  outputPolicy: "agent-only",
@@ -16311,7 +16932,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16311
16932
  if (!c.agent && !c.formatExplicit) {
16312
16933
  let capturedResult = null;
16313
16934
  return renderInteractive(
16314
- /* @__PURE__ */ jsx28(
16935
+ /* @__PURE__ */ jsx32(
16315
16936
  RetrieveSpendRequest,
16316
16937
  {
16317
16938
  repository,
@@ -16383,8 +17004,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16383
17004
  });
16384
17005
  cli2.command("cancel", {
16385
17006
  description: "Cancel a spend request",
16386
- args: z9.object({
16387
- id: z9.string().describe("Spend request ID")
17007
+ args: z11.object({
17008
+ id: z11.string().describe("Spend request ID")
16388
17009
  }),
16389
17010
  outputPolicy: "agent-only",
16390
17011
  middleware: [requireAuth(authStorage2, envAccessToken2)],
@@ -16393,7 +17014,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16393
17014
  if (!c.agent && !c.formatExplicit) {
16394
17015
  let capturedResult = null;
16395
17016
  return renderInteractive(
16396
- /* @__PURE__ */ jsx28(
17017
+ /* @__PURE__ */ jsx32(
16397
17018
  CancelSpendRequest,
16398
17019
  {
16399
17020
  repository,
@@ -16417,20 +17038,20 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
16417
17038
  }
16418
17039
 
16419
17040
  // src/commands/transactions/index.tsx
16420
- import { Cli as Cli10 } from "incur";
17041
+ import { Cli as Cli12 } from "incur";
16421
17042
 
16422
17043
  // src/commands/transactions/list.tsx
16423
- import { Box as Box21, Text as Text23 } from "ink";
16424
- import Spinner13 from "ink-spinner";
16425
- import { useCallback as useCallback10 } from "react";
16426
- import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
16427
- var COLUMN_GAP = " ";
17044
+ import { Box as Box23, Text as Text25 } from "ink";
17045
+ import Spinner15 from "ink-spinner";
17046
+ import { useCallback as useCallback12 } from "react";
17047
+ import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
17048
+ var COLUMN_GAP3 = " ";
16428
17049
  var DATE_WIDTH = 10;
16429
17050
  var AMOUNT_WIDTH = 13;
16430
17051
  var STATUS_WIDTH = 10;
16431
17052
  var CATEGORY_WIDTH = 16;
16432
17053
  var MIN_DESCRIPTION_WIDTH = 16;
16433
- var HORIZONTAL_PADDING = 4;
17054
+ var HORIZONTAL_PADDING2 = 4;
16434
17055
  function formatAmount(amount, currency) {
16435
17056
  const currencyCode = currency.toUpperCase();
16436
17057
  try {
@@ -16444,7 +17065,7 @@ function formatAmount(amount, currency) {
16444
17065
  return `${amount} ${currency}`;
16445
17066
  }
16446
17067
  }
16447
- function truncateCell(value, width) {
17068
+ function truncateCell3(value, width) {
16448
17069
  if (value.length <= width) {
16449
17070
  return value;
16450
17071
  }
@@ -16453,8 +17074,8 @@ function truncateCell(value, width) {
16453
17074
  }
16454
17075
  return `${value.slice(0, width - 3)}...`;
16455
17076
  }
16456
- function formatCell(value, width, align = "left") {
16457
- const truncated = truncateCell(value, width);
17077
+ function formatCell3(value, width, align = "left") {
17078
+ const truncated = truncateCell3(value, width);
16458
17079
  return align === "right" ? truncated.padStart(width) : truncated.padEnd(width);
16459
17080
  }
16460
17081
  var TransactionsList = ({
@@ -16462,7 +17083,7 @@ var TransactionsList = ({
16462
17083
  params,
16463
17084
  onComplete
16464
17085
  }) => {
16465
- const action = useCallback10(
17086
+ const action = useCallback12(
16466
17087
  () => resource.listTransactions(params),
16467
17088
  [resource, params]
16468
17089
  );
@@ -16472,80 +17093,80 @@ var TransactionsList = ({
16472
17093
  const terminalWidth = process.stdout.columns ?? 100;
16473
17094
  const descriptionWidth = Math.max(
16474
17095
  MIN_DESCRIPTION_WIDTH,
16475
- terminalWidth - HORIZONTAL_PADDING - DATE_WIDTH - AMOUNT_WIDTH - STATUS_WIDTH - CATEGORY_WIDTH - COLUMN_GAP.length * 4
17096
+ terminalWidth - HORIZONTAL_PADDING2 - DATE_WIDTH - AMOUNT_WIDTH - STATUS_WIDTH - CATEGORY_WIDTH - COLUMN_GAP3.length * 4
16476
17097
  );
16477
17098
  const headerRow = [
16478
- formatCell("Date", DATE_WIDTH),
16479
- formatCell("Amount", AMOUNT_WIDTH, "right"),
16480
- formatCell("Status", STATUS_WIDTH),
16481
- formatCell("Category", CATEGORY_WIDTH),
16482
- formatCell("Description", descriptionWidth)
16483
- ].join(COLUMN_GAP);
17099
+ formatCell3("Date", DATE_WIDTH),
17100
+ formatCell3("Amount", AMOUNT_WIDTH, "right"),
17101
+ formatCell3("Status", STATUS_WIDTH),
17102
+ formatCell3("Category", CATEGORY_WIDTH),
17103
+ formatCell3("Description", descriptionWidth)
17104
+ ].join(COLUMN_GAP3);
16484
17105
  const separatorRow = "-".repeat(headerRow.length);
16485
17106
  const rows = transactions.map(
16486
17107
  (txn) => [
16487
- formatCell(txn.created_date, DATE_WIDTH),
16488
- formatCell(formatAmount(txn.amount, txn.currency), AMOUNT_WIDTH, "right"),
16489
- formatCell(txn.status, STATUS_WIDTH),
16490
- formatCell(txn.category ?? "", CATEGORY_WIDTH),
16491
- formatCell(txn.description, descriptionWidth)
16492
- ].join(COLUMN_GAP)
17108
+ formatCell3(txn.created_date, DATE_WIDTH),
17109
+ formatCell3(formatAmount(txn.amount, txn.currency), AMOUNT_WIDTH, "right"),
17110
+ formatCell3(txn.status, STATUS_WIDTH),
17111
+ formatCell3(txn.category ?? "", CATEGORY_WIDTH),
17112
+ formatCell3(txn.description, descriptionWidth)
17113
+ ].join(COLUMN_GAP3)
16493
17114
  );
16494
17115
  if (status === "loading") {
16495
- return /* @__PURE__ */ jsx29(Box21, { children: /* @__PURE__ */ jsxs21(Text23, { color: "cyan", children: [
16496
- /* @__PURE__ */ jsx29(Spinner13, { type: "dots" }),
17116
+ return /* @__PURE__ */ jsx33(Box23, { children: /* @__PURE__ */ jsxs23(Text25, { color: "cyan", children: [
17117
+ /* @__PURE__ */ jsx33(Spinner15, { type: "dots" }),
16497
17118
  " Loading transactions..."
16498
17119
  ] }) });
16499
17120
  }
16500
17121
  if (status === "error") {
16501
- return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16502
- /* @__PURE__ */ jsx29(Text23, { color: "red", children: "Failed to load transactions" }),
16503
- /* @__PURE__ */ jsx29(Text23, { color: "red", children: error })
17122
+ return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", children: [
17123
+ /* @__PURE__ */ jsx33(Text25, { color: "red", children: "Failed to load transactions" }),
17124
+ /* @__PURE__ */ jsx33(Text25, { color: "red", children: error })
16504
17125
  ] });
16505
17126
  }
16506
17127
  if (transactions.length === 0) {
16507
- return /* @__PURE__ */ jsx29(Box21, { children: /* @__PURE__ */ jsx29(Text23, { dimColor: true, children: "No transactions found" }) });
16508
- }
16509
- return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
16510
- /* @__PURE__ */ jsx29(Text23, { bold: true, children: "Transactions" }),
16511
- /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16512
- /* @__PURE__ */ jsx29(Text23, { bold: true, children: headerRow }),
16513
- /* @__PURE__ */ jsx29(Text23, { dimColor: true, children: separatorRow }),
16514
- rows.map((row, index) => /* @__PURE__ */ jsx29(Text23, { children: row }, transactions[index].id))
17128
+ return /* @__PURE__ */ jsx33(Box23, { children: /* @__PURE__ */ jsx33(Text25, { dimColor: true, children: "No transactions found" }) });
17129
+ }
17130
+ return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", children: [
17131
+ /* @__PURE__ */ jsx33(Text25, { bold: true, children: "Transactions" }),
17132
+ /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
17133
+ /* @__PURE__ */ jsx33(Text25, { bold: true, children: headerRow }),
17134
+ /* @__PURE__ */ jsx33(Text25, { dimColor: true, children: separatorRow }),
17135
+ rows.map((row, index) => /* @__PURE__ */ jsx33(Text25, { children: row }, transactions[index].id))
16515
17136
  ] }),
16516
- page?.has_more !== void 0 ? /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
16517
- /* @__PURE__ */ jsxs21(Text23, { dimColor: true, children: [
17137
+ page?.has_more !== void 0 ? /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", marginTop: 1, children: [
17138
+ /* @__PURE__ */ jsxs23(Text25, { dimColor: true, children: [
16518
17139
  "has_more: ",
16519
17140
  String(page.has_more)
16520
17141
  ] }),
16521
- nextCursor ? /* @__PURE__ */ jsx29(Text23, { dimColor: true, children: `next page: --starting-after ${nextCursor}` }) : null
17142
+ nextCursor ? /* @__PURE__ */ jsx33(Text25, { dimColor: true, children: `next page: --starting-after ${nextCursor}` }) : null
16522
17143
  ] }) : null
16523
17144
  ] });
16524
17145
  };
16525
17146
 
16526
17147
  // src/commands/transactions/schema.ts
16527
- import { z as z10 } from "incur";
17148
+ import { z as z12 } from "incur";
16528
17149
  var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
16529
- var listOptions2 = z10.object({
16530
- limit: z10.coerce.number().int().positive().max(100).optional().describe("Maximum number of transactions to return (1-100)."),
16531
- startingAfter: z10.string().optional().describe("Cursor: return transactions after this transaction ID."),
16532
- endingBefore: z10.string().optional().describe("Cursor: return transactions before this transaction ID."),
16533
- startDate: z10.string().regex(ISO_DATE_REGEX, "Date must be in YYYY-MM-DD format.").optional().describe("Only include transactions on or after this YYYY-MM-DD date."),
16534
- endDate: z10.string().regex(ISO_DATE_REGEX, "Date must be in YYYY-MM-DD format.").optional().describe("Only include transactions on or before this YYYY-MM-DD date."),
16535
- category: z10.string().optional().describe("Filter by transaction category."),
16536
- origin: z10.enum(["link", "external_connection"]).optional().describe("Filter by transaction origin: link or external_connection."),
16537
- source: z10.array(z10.string()).default([]).describe("Filter by source ID. Repeat to include multiple sources.")
17150
+ var listOptions4 = z12.object({
17151
+ limit: z12.coerce.number().int().positive().max(100).optional().describe("Maximum number of transactions to return (1-100)."),
17152
+ startingAfter: z12.string().optional().describe("Cursor: return transactions after this transaction ID."),
17153
+ endingBefore: z12.string().optional().describe("Cursor: return transactions before this transaction ID."),
17154
+ startDate: z12.string().regex(ISO_DATE_REGEX, "Date must be in YYYY-MM-DD format.").optional().describe("Only include transactions on or after this YYYY-MM-DD date."),
17155
+ endDate: z12.string().regex(ISO_DATE_REGEX, "Date must be in YYYY-MM-DD format.").optional().describe("Only include transactions on or before this YYYY-MM-DD date."),
17156
+ category: z12.string().optional().describe("Filter by transaction category."),
17157
+ origin: z12.enum(["link", "external_connection"]).optional().describe("Filter by transaction origin: link or external_connection."),
17158
+ source: z12.array(z12.string()).default([]).describe("Filter by source ID. Repeat to include multiple sources.")
16538
17159
  });
16539
17160
 
16540
17161
  // src/commands/transactions/index.tsx
16541
- import { jsx as jsx30 } from "react/jsx-runtime";
17162
+ import { jsx as jsx34 } from "react/jsx-runtime";
16542
17163
  function createTransactionsCli(createResource, authStorage2, envAccessToken2) {
16543
- const cli2 = Cli10.create("transactions", {
17164
+ const cli2 = Cli12.create("transactions", {
16544
17165
  description: "List transactions from Link and external accounts"
16545
17166
  });
16546
17167
  cli2.command("list", {
16547
17168
  description: "List transactions from Link and external accounts, including non-Link activity",
16548
- options: listOptions2,
17169
+ options: listOptions4,
16549
17170
  outputPolicy: "agent-only",
16550
17171
  middleware: [requireAuth(authStorage2, envAccessToken2)],
16551
17172
  async run(c) {
@@ -16564,7 +17185,7 @@ function createTransactionsCli(createResource, authStorage2, envAccessToken2) {
16564
17185
  if (opts.source.length > 0) params.sources = opts.source;
16565
17186
  if (!c.agent && !c.formatExplicit) {
16566
17187
  return renderInteractive(
16567
- /* @__PURE__ */ jsx30(
17188
+ /* @__PURE__ */ jsx34(
16568
17189
  TransactionsList,
16569
17190
  {
16570
17191
  resource,
@@ -16583,54 +17204,54 @@ function createTransactionsCli(createResource, authStorage2, envAccessToken2) {
16583
17204
  }
16584
17205
 
16585
17206
  // src/commands/user-info/index.tsx
16586
- import { Cli as Cli11 } from "incur";
17207
+ import { Cli as Cli13 } from "incur";
16587
17208
 
16588
17209
  // src/commands/user-info/retrieve.tsx
16589
- import { Box as Box22, Text as Text24 } from "ink";
16590
- import Spinner14 from "ink-spinner";
16591
- import { useCallback as useCallback11 } from "react";
16592
- import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
17210
+ import { Box as Box24, Text as Text26 } from "ink";
17211
+ import Spinner16 from "ink-spinner";
17212
+ import { useCallback as useCallback13 } from "react";
17213
+ import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
16593
17214
  var UserInfoRetrieve = ({
16594
17215
  resource,
16595
17216
  onComplete
16596
17217
  }) => {
16597
- const action = useCallback11(() => resource.retrieve(), [resource]);
17218
+ const action = useCallback13(() => resource.retrieve(), [resource]);
16598
17219
  const { status, data: userInfo, error } = useAsyncAction(action, onComplete);
16599
17220
  if (status === "loading") {
16600
- return /* @__PURE__ */ jsx31(Box22, { children: /* @__PURE__ */ jsxs22(Text24, { color: "cyan", children: [
16601
- /* @__PURE__ */ jsx31(Spinner14, { type: "dots" }),
17221
+ return /* @__PURE__ */ jsx35(Box24, { children: /* @__PURE__ */ jsxs24(Text26, { color: "cyan", children: [
17222
+ /* @__PURE__ */ jsx35(Spinner16, { type: "dots" }),
16602
17223
  " Loading user info..."
16603
17224
  ] }) });
16604
17225
  }
16605
17226
  if (status === "error") {
16606
- return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
16607
- /* @__PURE__ */ jsx31(Text24, { color: "red", children: "\u2717 Failed to load user info" }),
16608
- /* @__PURE__ */ jsx31(Text24, { color: "red", children: error })
17227
+ return /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", children: [
17228
+ /* @__PURE__ */ jsx35(Text26, { color: "red", children: "\u2717 Failed to load user info" }),
17229
+ /* @__PURE__ */ jsx35(Text26, { color: "red", children: error })
16609
17230
  ] });
16610
17231
  }
16611
- return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
16612
- /* @__PURE__ */ jsx31(Text24, { bold: true, children: "User Info" }),
16613
- /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
16614
- /* @__PURE__ */ jsxs22(Text24, { children: [
16615
- /* @__PURE__ */ jsx31(Text24, { dimColor: true, children: "Email: " }),
16616
- userInfo?.email ?? /* @__PURE__ */ jsx31(Text24, { dimColor: true, children: "Not set" })
17232
+ return /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", children: [
17233
+ /* @__PURE__ */ jsx35(Text26, { bold: true, children: "User Info" }),
17234
+ /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
17235
+ /* @__PURE__ */ jsxs24(Text26, { children: [
17236
+ /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Email: " }),
17237
+ userInfo?.email ?? /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Not set" })
16617
17238
  ] }),
16618
- /* @__PURE__ */ jsxs22(Text24, { children: [
16619
- /* @__PURE__ */ jsx31(Text24, { dimColor: true, children: "Name: " }),
16620
- userInfo?.name ?? /* @__PURE__ */ jsx31(Text24, { dimColor: true, children: "Not set" })
17239
+ /* @__PURE__ */ jsxs24(Text26, { children: [
17240
+ /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Name: " }),
17241
+ userInfo?.name ?? /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Not set" })
16621
17242
  ] }),
16622
- /* @__PURE__ */ jsxs22(Text24, { children: [
16623
- /* @__PURE__ */ jsx31(Text24, { dimColor: true, children: "Phone: " }),
16624
- userInfo?.phone ?? /* @__PURE__ */ jsx31(Text24, { dimColor: true, children: "Not set" })
17243
+ /* @__PURE__ */ jsxs24(Text26, { children: [
17244
+ /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Phone: " }),
17245
+ userInfo?.phone ?? /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Not set" })
16625
17246
  ] })
16626
17247
  ] })
16627
17248
  ] });
16628
17249
  };
16629
17250
 
16630
17251
  // src/commands/user-info/index.tsx
16631
- import { jsx as jsx32 } from "react/jsx-runtime";
17252
+ import { jsx as jsx36 } from "react/jsx-runtime";
16632
17253
  function createUserInfoCli(createResource, authStorage2, envAccessToken2) {
16633
- const cli2 = Cli11.create("user-info", {
17254
+ const cli2 = Cli13.create("user-info", {
16634
17255
  description: "User information commands"
16635
17256
  });
16636
17257
  cli2.command("retrieve", {
@@ -16641,7 +17262,7 @@ function createUserInfoCli(createResource, authStorage2, envAccessToken2) {
16641
17262
  const resource = createResource();
16642
17263
  if (!c.agent && !c.formatExplicit) {
16643
17264
  return renderInteractive(
16644
- /* @__PURE__ */ jsx32(UserInfoRetrieve, { resource, onComplete: () => {
17265
+ /* @__PURE__ */ jsx36(UserInfoRetrieve, { resource, onComplete: () => {
16645
17266
  } }),
16646
17267
  () => resource.retrieve()
16647
17268
  );
@@ -16692,11 +17313,55 @@ function requireFetchImplementation2(config) {
16692
17313
 
16693
17314
  // src/auth/auth-resource.ts
16694
17315
  var CLIENT_ID = "lwlpk_U7Qy7ThG69STZk";
16695
- var DEFAULT_SCOPE = "userinfo:read payment_methods.agentic";
16696
17316
  function formatOAuthError(prefix, status, data, rawBody) {
16697
17317
  const err = data;
16698
17318
  return `${prefix} (${status}): ${err?.error_description ?? err?.error ?? (rawBody || "unknown error")}`;
16699
17319
  }
17320
+ function appendAuthorizationDetailValue(params, key, value) {
17321
+ if (Array.isArray(value)) {
17322
+ for (const entry of value) {
17323
+ appendAuthorizationDetailValue(params, `${key}[]`, entry);
17324
+ }
17325
+ return;
17326
+ }
17327
+ if (value !== null && typeof value === "object") {
17328
+ for (const [entryKey, entryValue] of Object.entries(value)) {
17329
+ appendAuthorizationDetailValue(params, `${key}[${entryKey}]`, entryValue);
17330
+ }
17331
+ return;
17332
+ }
17333
+ params.append(key, String(value));
17334
+ }
17335
+ function buildDeviceCodeForm(clientName, options) {
17336
+ const connectionLabel = `${clientName} on ${hostname()}`;
17337
+ const params = new URLSearchParams({
17338
+ client_id: CLIENT_ID,
17339
+ scope: options.scope ?? DEFAULT_SCOPE,
17340
+ connection_label: connectionLabel,
17341
+ client_hint: clientName
17342
+ });
17343
+ const authorizationDetails = buildAuthorizationDetails(
17344
+ options.sourceActions,
17345
+ options.authorizationDetails
17346
+ );
17347
+ for (const detail of authorizationDetails) {
17348
+ appendAuthorizationDetailValue(params, "authorization_details[]", detail);
17349
+ }
17350
+ return params;
17351
+ }
17352
+ function serializeFormBody(params) {
17353
+ return params instanceof URLSearchParams ? params.toString() : new URLSearchParams(params).toString();
17354
+ }
17355
+ function serializeRedactedFormBody(params) {
17356
+ const redacted = new URLSearchParams(params);
17357
+ if (redacted.has("device_code")) {
17358
+ redacted.set("device_code", "<redacted>");
17359
+ }
17360
+ if (redacted.has("refresh_token")) {
17361
+ redacted.set("refresh_token", "<redacted>");
17362
+ }
17363
+ return redacted.toString();
17364
+ }
16700
17365
  var LinkAuthResource = class {
16701
17366
  config;
16702
17367
  fetchImpl;
@@ -16706,12 +17371,9 @@ var LinkAuthResource = class {
16706
17371
  }
16707
17372
  async postForm(url, params) {
16708
17373
  if (this.config.verbose) {
16709
- const redacted = { ...params };
16710
- if (redacted.device_code) redacted.device_code = "<redacted>";
16711
- if (redacted.refresh_token) redacted.refresh_token = "<redacted>";
16712
17374
  this.config.logger.debug(
16713
17375
  `> POST ${url}
16714
- ${JSON.stringify(redacted, null, 2)}`
17376
+ ${serializeRedactedFormBody(params)}`
16715
17377
  );
16716
17378
  }
16717
17379
  let response;
@@ -16722,7 +17384,7 @@ ${JSON.stringify(redacted, null, 2)}`
16722
17384
  ...this.config.defaultHeaders,
16723
17385
  "Content-Type": "application/x-www-form-urlencoded"
16724
17386
  },
16725
- body: new URLSearchParams(params).toString()
17387
+ body: serializeFormBody(params)
16726
17388
  });
16727
17389
  } catch (error) {
16728
17390
  throw new LinkTransportError(`Request failed: POST ${url}`, {
@@ -16744,16 +17406,12 @@ ${JSON.stringify(redacted, null, 2)}`
16744
17406
  }
16745
17407
  return { status: response.status, data, rawBody };
16746
17408
  }
16747
- async initiateDeviceAuth(clientName) {
16748
- const effectiveName = clientName ?? this.config.clientName;
17409
+ async initiateDeviceAuth(options = {}) {
17410
+ const effectiveName = options.clientName ?? this.config.clientName;
17411
+ const params = buildDeviceCodeForm(effectiveName, options);
16749
17412
  const { status, data, rawBody } = await this.postForm(
16750
17413
  `${this.config.authBaseUrl}/device/code`,
16751
- {
16752
- client_id: CLIENT_ID,
16753
- scope: DEFAULT_SCOPE,
16754
- connection_label: `${effectiveName} on ${hostname()}`,
16755
- client_hint: effectiveName
16756
- }
17414
+ params
16757
17415
  );
16758
17416
  if (status < 200 || status >= 300) {
16759
17417
  throw new LinkApiError(
@@ -16933,6 +17591,8 @@ var ResourceFactory = class {
16933
17591
  shippingAddressResource;
16934
17592
  userInfoResource;
16935
17593
  transactionsResource;
17594
+ sourcesResource;
17595
+ balancesResource;
16936
17596
  webBotAuthResource;
16937
17597
  reportResource;
16938
17598
  constructor(options = {}) {
@@ -17061,6 +17721,34 @@ var ResourceFactory = class {
17061
17721
  );
17062
17722
  return this.transactionsResource;
17063
17723
  }
17724
+ createSourcesResource() {
17725
+ if (this.sourcesResource) {
17726
+ return this.sourcesResource;
17727
+ }
17728
+ const getAccessToken = this.createSdkAccessTokenProvider();
17729
+ this.sourcesResource = sanitizeResource(
17730
+ new SourcesResource({
17731
+ verbose: this.verbose,
17732
+ defaultHeaders: this.defaultHeaders,
17733
+ getAccessToken
17734
+ })
17735
+ );
17736
+ return this.sourcesResource;
17737
+ }
17738
+ createBalancesResource() {
17739
+ if (this.balancesResource) {
17740
+ return this.balancesResource;
17741
+ }
17742
+ const getAccessToken = this.createSdkAccessTokenProvider();
17743
+ this.balancesResource = sanitizeResource(
17744
+ new BalancesResource({
17745
+ verbose: this.verbose,
17746
+ defaultHeaders: this.defaultHeaders,
17747
+ getAccessToken
17748
+ })
17749
+ );
17750
+ return this.balancesResource;
17751
+ }
17064
17752
  createWebBotAuthResource() {
17065
17753
  if (this.webBotAuthResource) {
17066
17754
  return this.webBotAuthResource;
@@ -17162,7 +17850,7 @@ function cacheUpdateInfo(value, ttlMs = UPDATE_CACHE_TTL_MS) {
17162
17850
  }
17163
17851
 
17164
17852
  // src/cli.tsx
17165
- var cliVersion = "0.8.3";
17853
+ var cliVersion = "0.9.0";
17166
17854
  var cliName = "@stripe/link-cli";
17167
17855
  var defaultHeaders = {
17168
17856
  "User-Agent": `link-cli/${cliVersion}`
@@ -17192,15 +17880,23 @@ var factory = new ResourceFactory({
17192
17880
  var authRepo = factory.createAuthResource();
17193
17881
  var spendRequestRepo = factory.createSpendRequestResource();
17194
17882
  var requestedCommand = process.argv[2];
17195
- var transactionsCli = requestedCommand === "transactions" ? createTransactionsCli(
17883
+ var hiddenCli = requestedCommand === "transactions" ? createTransactionsCli(
17196
17884
  () => factory.createTransactionsResource(),
17197
17885
  authStorage,
17198
17886
  envAccessToken
17887
+ ) : requestedCommand === "sources" ? createSourcesCli(
17888
+ () => factory.createSourcesResource(),
17889
+ authStorage,
17890
+ envAccessToken
17891
+ ) : requestedCommand === "balances" ? createBalancesCli(
17892
+ () => factory.createBalancesResource(),
17893
+ authStorage,
17894
+ envAccessToken
17199
17895
  ) : null;
17200
- if (transactionsCli) {
17896
+ if (hiddenCli) {
17201
17897
  process.argv.splice(2, 1);
17202
17898
  }
17203
- var cli = transactionsCli ?? Cli12.create("link-cli", {
17899
+ var cli = hiddenCli ?? Cli14.create("link-cli", {
17204
17900
  description: "Create a secure, one-time payment credential from a Link wallet to let agents complete purchases on behalf of users.",
17205
17901
  version: cliVersion
17206
17902
  });
@@ -17217,7 +17913,7 @@ if (!isAgent && process.stdout.isTTY) {
17217
17913
  process.stderr.write(renderInteractiveUpdateNotice(updateInfo));
17218
17914
  }
17219
17915
  }
17220
- if (!transactionsCli) {
17916
+ if (!hiddenCli) {
17221
17917
  cli.command(
17222
17918
  createAuthCli(authRepo, getUpdateInfo, authStorage, envAccessToken)
17223
17919
  );