image-skill 0.1.60 → 0.1.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ This changelog tracks the public `image-skill` CLI package and public skill
4
4
  mirror. The npm package metadata remains the authority for tarball integrity and
5
5
  provenance; this file is the human- and agent-readable release map.
6
6
 
7
+ ## 0.1.62 - 2026-06-17
8
+
9
+ - Release (activation/self-fund): make `usage quota --json` top-up handoffs
10
+ copy-runnable from ephemeral `npx image-skill@latest` runs. Quota
11
+ `top_up`, generated `next_actions.self_fund`, and create-guide embedded
12
+ quota top-up commands now carry the public handoff prefix instead of bare
13
+ `image-skill ...` commands.
14
+
15
+ ## 0.1.61 - 2026-06-17
16
+
17
+ - Release (activation/self-fund): add payment-attempt continuation actions.
18
+ `credits status --quote-id ...` now repeats the exact
19
+ `data.next_actions.recommended_buy` command for open x402/Checkout quotes,
20
+ and Stripe x402 buy/status responses expose
21
+ `data.next_actions.recommended_settlement` with exact payable-instruction
22
+ paths, status/quota commands, and wallet-settlement safety flags.
23
+
7
24
  ## 0.1.60 - 2026-06-17
8
25
 
9
26
  - Release (activation/self-fund): add `credits quote --json`
@@ -15,7 +15,7 @@ import { Readable } from "node:stream";
15
15
  import { pipeline } from "node:stream/promises";
16
16
  import os from "node:os";
17
17
 
18
- const VERSION = "0.1.60";
18
+ const VERSION = "0.1.62";
19
19
  const PACKAGE_NAME = "image-skill";
20
20
  const DEFAULT_API_BASE_URL = "https://api.image-skill.com";
21
21
  const DEFAULT_DOCS_BASE_URL = "https://image-skill.com";
@@ -1296,7 +1296,10 @@ async function credits(argv) {
1296
1296
  idempotency_key: idempotency.value,
1297
1297
  },
1298
1298
  });
1299
- return withStripeCheckoutCopyFallback(result);
1299
+ return withCopyRunnablePaymentNextActionCommands(
1300
+ withStripeCheckoutCopyFallback(result),
1301
+ createGuideCommandPrefix(),
1302
+ );
1300
1303
  }
1301
1304
  if (subcommand === "status") {
1302
1305
  const args = parseArgs(rest);
@@ -1316,7 +1319,10 @@ async function credits(argv) {
1316
1319
  path: `/v1/credit-purchases/status?${query.toString()}`,
1317
1320
  token: token.token,
1318
1321
  });
1319
- return withStripeCheckoutCopyFallback(result);
1322
+ return withCopyRunnablePaymentNextActionCommands(
1323
+ withStripeCheckoutCopyFallback(result),
1324
+ createGuideCommandPrefix(),
1325
+ );
1320
1326
  }
1321
1327
  return invalid(
1322
1328
  "image-skill credits",
@@ -1740,16 +1746,22 @@ async function createGuide(args, options = {}) {
1740
1746
  maxEstimatedUsdPerImage ??
1741
1747
  estimatedDebitUsdPerImage ??
1742
1748
  (estimatedCredits === null ? 0.07 : estimatedCredits / 100);
1749
+ const quotaCommandPrefix = createGuideCommandPrefix({
1750
+ configPath: configuredImageSkillConfigPath(),
1751
+ });
1743
1752
  const quota =
1744
1753
  token.token === null
1745
1754
  ? null
1746
- : await apiRequest({
1747
- command: "image-skill create --guide",
1748
- method: "GET",
1749
- apiBaseUrl,
1750
- path: "/v1/quota",
1751
- token: token.token,
1752
- });
1755
+ : withQuotaNextActions(
1756
+ await apiRequest({
1757
+ command: "image-skill create --guide",
1758
+ method: "GET",
1759
+ apiBaseUrl,
1760
+ path: "/v1/quota",
1761
+ token: token.token,
1762
+ }),
1763
+ quotaCommandPrefix,
1764
+ );
1753
1765
  const authenticated = quota?.envelope.data?.authenticated === true;
1754
1766
  const publicTokenSource =
1755
1767
  token.source === "anonymous" ? "none" : token.source;
@@ -2781,6 +2793,115 @@ function withCopyRunnableCreditQuoteCommands(result, commandPrefix) {
2781
2793
  };
2782
2794
  }
2783
2795
 
2796
+ function withCopyRunnablePaymentNextActionCommands(result, commandPrefix) {
2797
+ const data = result.envelope.data;
2798
+ if (
2799
+ !result.envelope.ok ||
2800
+ data === null ||
2801
+ typeof data !== "object" ||
2802
+ Array.isArray(data)
2803
+ ) {
2804
+ return result;
2805
+ }
2806
+ const updated = paymentNextActionsWithCopyRunnableCommands(
2807
+ data,
2808
+ commandPrefix,
2809
+ );
2810
+ if (updated === data) {
2811
+ return result;
2812
+ }
2813
+ return {
2814
+ ...result,
2815
+ envelope: {
2816
+ ...result.envelope,
2817
+ data: updated,
2818
+ },
2819
+ };
2820
+ }
2821
+
2822
+ function paymentNextActionsWithCopyRunnableCommands(data, commandPrefix) {
2823
+ if (
2824
+ data.next_actions === null ||
2825
+ typeof data.next_actions !== "object" ||
2826
+ Array.isArray(data.next_actions)
2827
+ ) {
2828
+ return data;
2829
+ }
2830
+ let changed = false;
2831
+ const nextActions = { ...data.next_actions };
2832
+
2833
+ if (
2834
+ nextActions.recommended_buy !== null &&
2835
+ typeof nextActions.recommended_buy === "object" &&
2836
+ !Array.isArray(nextActions.recommended_buy)
2837
+ ) {
2838
+ const recommendedBuy = { ...nextActions.recommended_buy };
2839
+ changed =
2840
+ renderPaymentActionCommandField(
2841
+ recommendedBuy,
2842
+ "command",
2843
+ commandPrefix,
2844
+ ) || changed;
2845
+ changed =
2846
+ renderPaymentActionCommandField(
2847
+ recommendedBuy,
2848
+ "buy_command",
2849
+ commandPrefix,
2850
+ ) || changed;
2851
+ changed =
2852
+ renderPaymentActionCommandField(
2853
+ recommendedBuy,
2854
+ "status_command",
2855
+ commandPrefix,
2856
+ ) || changed;
2857
+ changed =
2858
+ renderPaymentActionCommandField(
2859
+ recommendedBuy,
2860
+ "status_command_after_payment",
2861
+ commandPrefix,
2862
+ ) || changed;
2863
+ nextActions.recommended_buy = recommendedBuy;
2864
+ }
2865
+
2866
+ if (
2867
+ nextActions.recommended_settlement !== null &&
2868
+ typeof nextActions.recommended_settlement === "object" &&
2869
+ !Array.isArray(nextActions.recommended_settlement)
2870
+ ) {
2871
+ const recommendedSettlement = { ...nextActions.recommended_settlement };
2872
+ changed =
2873
+ renderPaymentActionCommandField(
2874
+ recommendedSettlement,
2875
+ "status_command",
2876
+ commandPrefix,
2877
+ ) || changed;
2878
+ changed =
2879
+ renderPaymentActionCommandField(
2880
+ recommendedSettlement,
2881
+ "quota_command",
2882
+ commandPrefix,
2883
+ ) || changed;
2884
+ nextActions.recommended_settlement = recommendedSettlement;
2885
+ }
2886
+
2887
+ return changed ? { ...data, next_actions: nextActions } : data;
2888
+ }
2889
+
2890
+ function renderPaymentActionCommandField(record, field, commandPrefix) {
2891
+ if (typeof record[field] !== "string") {
2892
+ return false;
2893
+ }
2894
+ const rendered = renderCopyRunnablePaymentCommand(
2895
+ commandPrefix,
2896
+ record[field],
2897
+ );
2898
+ if (rendered === record[field]) {
2899
+ return false;
2900
+ }
2901
+ record[field] = rendered;
2902
+ return true;
2903
+ }
2904
+
2784
2905
  function creditQuoteWithCopyRunnableCommands(quote, commandPrefix) {
2785
2906
  const recommendedBuy =
2786
2907
  quote.next_actions?.recommended_buy !== null &&
@@ -6226,7 +6347,10 @@ function withCommand(result, command) {
6226
6347
  };
6227
6348
  }
6228
6349
 
6229
- function withQuotaNextActions(result) {
6350
+ function withQuotaNextActions(
6351
+ result,
6352
+ commandPrefix = createGuideCommandPrefix(),
6353
+ ) {
6230
6354
  const data = result.envelope?.data;
6231
6355
  if (
6232
6356
  result.envelope?.ok !== true ||
@@ -6235,22 +6359,84 @@ function withQuotaNextActions(result) {
6235
6359
  ) {
6236
6360
  return result;
6237
6361
  }
6238
- const nextActions = quotaTopUpNextActions(data.top_up);
6362
+ const quotaData = quotaDataWithCopyRunnableTopUpCommands(data, commandPrefix);
6363
+ const nextActions = quotaTopUpNextActions(quotaData.top_up);
6239
6364
  if (nextActions === null) {
6240
- return result;
6365
+ return quotaData === data
6366
+ ? result
6367
+ : {
6368
+ ...result,
6369
+ envelope: {
6370
+ ...result.envelope,
6371
+ data: quotaData,
6372
+ },
6373
+ };
6241
6374
  }
6242
6375
  return {
6243
6376
  ...result,
6244
6377
  envelope: {
6245
6378
  ...result.envelope,
6246
6379
  data: {
6247
- ...data,
6380
+ ...quotaData,
6248
6381
  next_actions: nextActions,
6249
6382
  },
6250
6383
  },
6251
6384
  };
6252
6385
  }
6253
6386
 
6387
+ function quotaDataWithCopyRunnableTopUpCommands(data, commandPrefix) {
6388
+ if (data.top_up === undefined || data.top_up === null) {
6389
+ return data;
6390
+ }
6391
+ const topUp = quotaTopUpWithCopyRunnableCommands(data.top_up, commandPrefix);
6392
+ return topUp === data.top_up ? data : { ...data, top_up: topUp };
6393
+ }
6394
+
6395
+ function quotaTopUpWithCopyRunnableCommands(topUp, commandPrefix) {
6396
+ const commands = topUp.commands;
6397
+ const workflow = topUp.workflow;
6398
+ if (topUp === null || typeof topUp !== "object") {
6399
+ return topUp;
6400
+ }
6401
+ const render = (command) =>
6402
+ renderCopyRunnablePaymentCommand(commandPrefix, command);
6403
+ const renderIfString = (value) =>
6404
+ typeof value === "string" ? render(value) : value;
6405
+ return {
6406
+ ...topUp,
6407
+ first_command: renderIfString(topUp.first_command),
6408
+ quote_command: renderIfString(topUp.quote_command),
6409
+ commands:
6410
+ commands !== null && typeof commands === "object"
6411
+ ? {
6412
+ ...commands,
6413
+ inspect_methods: renderIfString(commands.inspect_methods),
6414
+ inspect_packs: renderIfString(commands.inspect_packs),
6415
+ quote: renderIfString(commands.quote),
6416
+ buy: renderIfString(commands.buy),
6417
+ status: renderIfString(commands.status),
6418
+ fallback_quote: renderIfString(commands.fallback_quote),
6419
+ fallback_buy: renderIfString(commands.fallback_buy),
6420
+ }
6421
+ : commands,
6422
+ workflow:
6423
+ workflow !== null &&
6424
+ typeof workflow === "object" &&
6425
+ Array.isArray(workflow.steps)
6426
+ ? {
6427
+ ...workflow,
6428
+ steps: workflow.steps.map((step) =>
6429
+ step !== null &&
6430
+ typeof step === "object" &&
6431
+ typeof step.command === "string"
6432
+ ? { ...step, command: render(step.command) }
6433
+ : step,
6434
+ ),
6435
+ }
6436
+ : workflow,
6437
+ };
6438
+ }
6439
+
6254
6440
  function quotaTopUpNextActions(topUp) {
6255
6441
  const commands = topUp?.commands;
6256
6442
  if (
package/cli.md CHANGED
@@ -665,6 +665,12 @@ Use `data.next_actions.recommended_buy.status_command` to inspect the quote or
665
665
  payment state by `quote_id`; after buy returns a `payment_attempt_id`, prefer
666
666
  `status_command_after_payment`.
667
667
 
668
+ When `credits status --quote-id quote_... --json` sees an open
669
+ `stripe_x402.exact.usdc` or `stripe_checkout` quote, it repeats the exact
670
+ `data.next_actions.recommended_buy` command with the real `quote_id` and
671
+ `purchase:quote_...` idempotency key so agents do not need to reconstruct the
672
+ buy step from placeholders.
673
+
668
674
  Hosted API equivalent:
669
675
 
670
676
  ```bash
@@ -743,6 +749,22 @@ Minimum x402 action-required data:
743
749
  "client_secret": "[redacted-stripe-client-secret]"
744
750
  }
745
751
  },
752
+ "next_actions": {
753
+ "recommended_settlement": {
754
+ "purpose": "settle_stripe_x402_credit_top_up",
755
+ "quote_id": "quote_...",
756
+ "payment_attempt_id": "payatt_...",
757
+ "method_id": "stripe_x402.exact.usdc",
758
+ "payable_instructions_path": "data.stripe_x402.payable_instructions",
759
+ "status_command": "image-skill credits status --payment-attempt-id payatt_... --json",
760
+ "quota_command": "image-skill usage quota --json",
761
+ "command_effect": {
762
+ "wallet_settlement": true,
763
+ "credit_debit": false,
764
+ "media_write": false
765
+ }
766
+ }
767
+ },
746
768
  "next": {
747
769
  "agent_action": "pay_stripe_crypto_deposit",
748
770
  "suggested_commands": [
@@ -842,6 +864,12 @@ At most one reference flag is allowed: `--quote-id`,
842
864
  `--payment-attempt-id`, `--checkout-session-id`, or `--receipt-id`. Passing no
843
865
  reference returns the balance/quota state.
844
866
 
867
+ For Stripe x402 attempts that are still `action_required`, status responses
868
+ include `data.next_actions.recommended_settlement` with the same exact Base/USDC
869
+ payable instructions, a copy-runnable status command for the real
870
+ `payment_attempt_id`, and explicit effect flags showing this is wallet
871
+ settlement, not credit debit, media write, or provider generation work.
872
+
845
873
  Minimum action-required data:
846
874
 
847
875
  ```json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "image-skill",
3
- "version": "0.1.60",
3
+ "version": "0.1.62",
4
4
  "description": "Zero-setup durable creative-media CLI for agents (image + video + audio + 3D): guide-first creation, model and cost inspection, owned URLs, JSON recovery, payments, reusable assets, and feedback.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -665,6 +665,12 @@ Use `data.next_actions.recommended_buy.status_command` to inspect the quote or
665
665
  payment state by `quote_id`; after buy returns a `payment_attempt_id`, prefer
666
666
  `status_command_after_payment`.
667
667
 
668
+ When `credits status --quote-id quote_... --json` sees an open
669
+ `stripe_x402.exact.usdc` or `stripe_checkout` quote, it repeats the exact
670
+ `data.next_actions.recommended_buy` command with the real `quote_id` and
671
+ `purchase:quote_...` idempotency key so agents do not need to reconstruct the
672
+ buy step from placeholders.
673
+
668
674
  Hosted API equivalent:
669
675
 
670
676
  ```bash
@@ -743,6 +749,22 @@ Minimum x402 action-required data:
743
749
  "client_secret": "[redacted-stripe-client-secret]"
744
750
  }
745
751
  },
752
+ "next_actions": {
753
+ "recommended_settlement": {
754
+ "purpose": "settle_stripe_x402_credit_top_up",
755
+ "quote_id": "quote_...",
756
+ "payment_attempt_id": "payatt_...",
757
+ "method_id": "stripe_x402.exact.usdc",
758
+ "payable_instructions_path": "data.stripe_x402.payable_instructions",
759
+ "status_command": "image-skill credits status --payment-attempt-id payatt_... --json",
760
+ "quota_command": "image-skill usage quota --json",
761
+ "command_effect": {
762
+ "wallet_settlement": true,
763
+ "credit_debit": false,
764
+ "media_write": false
765
+ }
766
+ }
767
+ },
746
768
  "next": {
747
769
  "agent_action": "pay_stripe_crypto_deposit",
748
770
  "suggested_commands": [
@@ -842,6 +864,12 @@ At most one reference flag is allowed: `--quote-id`,
842
864
  `--payment-attempt-id`, `--checkout-session-id`, or `--receipt-id`. Passing no
843
865
  reference returns the balance/quota state.
844
866
 
867
+ For Stripe x402 attempts that are still `action_required`, status responses
868
+ include `data.next_actions.recommended_settlement` with the same exact Base/USDC
869
+ payable instructions, a copy-runnable status command for the real
870
+ `payment_attempt_id`, and explicit effect flags showing this is wallet
871
+ settlement, not credit debit, media write, or provider generation work.
872
+
845
873
  Minimum action-required data:
846
874
 
847
875
  ```json