@cleanslop/cli 0.1.0-beta.2 → 0.1.0-beta.21

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 (66) hide show
  1. package/README.md +5 -4
  2. package/assets/skill-core.md +25 -7
  3. package/dist/action.d.ts +4 -1
  4. package/dist/action.js +24 -0
  5. package/dist/action.js.map +1 -1
  6. package/dist/args.d.ts +1 -1
  7. package/dist/args.js +31 -9
  8. package/dist/args.js.map +1 -1
  9. package/dist/commands/credits.d.ts +30 -1
  10. package/dist/commands/credits.js +320 -43
  11. package/dist/commands/credits.js.map +1 -1
  12. package/dist/commands/email.js +22 -0
  13. package/dist/commands/email.js.map +1 -1
  14. package/dist/commands/link-login.js +4 -4
  15. package/dist/commands/link-login.js.map +1 -1
  16. package/dist/commands/login.d.ts +1 -0
  17. package/dist/commands/login.js +22 -8
  18. package/dist/commands/login.js.map +1 -1
  19. package/dist/commands/logout.d.ts +2 -1
  20. package/dist/commands/logout.js +48 -23
  21. package/dist/commands/logout.js.map +1 -1
  22. package/dist/commands/redeem.d.ts +7 -0
  23. package/dist/commands/redeem.js +33 -0
  24. package/dist/commands/redeem.js.map +1 -0
  25. package/dist/commands/scan-upload.js +48 -27
  26. package/dist/commands/scan-upload.js.map +1 -1
  27. package/dist/commands/scan.js +45 -4
  28. package/dist/commands/scan.js.map +1 -1
  29. package/dist/config.d.ts +3 -3
  30. package/dist/config.js +2 -2
  31. package/dist/config.js.map +1 -1
  32. package/dist/connect.d.ts +15 -0
  33. package/dist/connect.js +100 -0
  34. package/dist/connect.js.map +1 -0
  35. package/dist/credentials.d.ts +14 -0
  36. package/dist/credentials.js +25 -7
  37. package/dist/credentials.js.map +1 -1
  38. package/dist/done-question.d.ts +20 -0
  39. package/dist/done-question.js +25 -0
  40. package/dist/done-question.js.map +1 -0
  41. package/dist/exit.d.ts +29 -0
  42. package/dist/exit.js +12 -0
  43. package/dist/exit.js.map +1 -1
  44. package/dist/git.d.ts +8 -1
  45. package/dist/git.js +35 -1
  46. package/dist/git.js.map +1 -1
  47. package/dist/http.js +74 -4
  48. package/dist/http.js.map +1 -1
  49. package/dist/link.d.ts +52 -11
  50. package/dist/link.js +169 -43
  51. package/dist/link.js.map +1 -1
  52. package/dist/main.js +8 -3
  53. package/dist/main.js.map +1 -1
  54. package/dist/output.js +6 -1
  55. package/dist/output.js.map +1 -1
  56. package/dist/pack.d.ts +19 -3
  57. package/dist/pack.js +30 -2
  58. package/dist/pack.js.map +1 -1
  59. package/dist/skill.d.ts +1 -1
  60. package/dist/skill.js +2 -1
  61. package/dist/skill.js.map +1 -1
  62. package/dist/top-up.d.ts +8 -0
  63. package/dist/top-up.js +35 -0
  64. package/dist/top-up.js.map +1 -0
  65. package/dist/types.d.ts +18 -1
  66. package/package.json +1 -1
@@ -1,8 +1,10 @@
1
1
  import { writeAction } from "../action.js";
2
+ import { doneQuestion } from "../done-question.js";
2
3
  import { asRecord, httpRequest, requireOk } from "../http.js";
3
- import { createLinkSpendRequest, ensureLinkPaymentScope, retrieveLinkSpendRequest, retrieveSharedPaymentToken, } from "../link.js";
4
+ import { createLinkSpendRequest, ensureLinkPaymentScope, grantLinkPayments, linkAuthMode, linkPaymentStep, linkSpendRequestTestMode, retrieveLinkSpendRequest, retrieveSharedPaymentToken, } from "../link.js";
4
5
  import { deletePendingSpend, readPendingSpend, requireToken, resolveOrigin, writePendingSpend, } from "../credentials.js";
5
6
  import { actionError, CliError, EXIT_OK, EXIT_PAYMENT, usageError, } from "../exit.js";
7
+ import { NOT_NOW, promoOffered, topUpQuestion, withPromoHint } from "../top-up.js";
6
8
  const CREDIT_PACKS = {
7
9
  p5: 5,
8
10
  p15: 15,
@@ -17,10 +19,116 @@ function spendRequestContext(pack, scans) {
17
19
  }
18
20
  /** Fixed Link approval budget. Auto-buy ignores `scan --wait`. */
19
21
  export const LINK_APPROVAL_WAIT_MS = 10 * 60 * 1000;
22
+ /**
23
+ * `--resume` budget. The human has usually approved already; anything longer
24
+ * would outlast an agent's foreground shell call.
25
+ */
26
+ export const LINK_RESUME_WAIT_MS = 60 * 1000;
27
+ const BUY_COMMAND = "cleanslop credits buy --link";
28
+ /**
29
+ * How long to poll Link for approval. `--no-wait` checks once, `--resume`
30
+ * polls briefly, and the default (a human at a terminal) waits 10 minutes.
31
+ */
20
32
  export function linkApprovalWaitMs(args, opts = {}) {
21
33
  if (opts.autoBuy)
22
34
  return LINK_APPROVAL_WAIT_MS;
23
- return args.wait ? args.waitMs : LINK_APPROVAL_WAIT_MS;
35
+ switch (linkAuthMode(args)) {
36
+ case "no-wait":
37
+ return 0;
38
+ case "resume":
39
+ return LINK_RESUME_WAIT_MS;
40
+ case "wait":
41
+ return args.wait ? args.waitMs : LINK_APPROVAL_WAIT_MS;
42
+ }
43
+ }
44
+ /** Cents to a display price, e.g. `5.00 USD`. */
45
+ export function formatPackPrice(amount, currency) {
46
+ return `${(amount / 100).toFixed(2)} ${currency.toUpperCase()}`;
47
+ }
48
+ /** `p15 (15 scans, 25.00 USD, 1.67 USD per scan, best value)`. */
49
+ export function describePackOffer(offer) {
50
+ const scans = CREDIT_PACKS[offer.pack];
51
+ const parts = [
52
+ `${scans} scans`,
53
+ formatPackPrice(offer.amount, offer.currency),
54
+ `${formatPackPrice(Math.round(offer.amount / scans), offer.currency)} per scan`,
55
+ ];
56
+ if (offer.best)
57
+ parts.push("best value");
58
+ return `${offer.pack} (${parts.join(", ")})`;
59
+ }
60
+ const APPROVE_THEN_RESUME = `relay its approval prompt (Link notifies their Link app; there is usually no link), and after they approve run \`${BUY_COMMAND} --resume\`.`;
61
+ /** Asks the human to pick from every pack CleanSlop offers. */
62
+ function choosePackPrompt(offers, tail = "") {
63
+ const list = new Intl.ListFormat("en", { type: "disjunction" }).format(offers.map(describePackOffer));
64
+ return `Ask the human which CleanSlop credit pack to buy with Link: ${list}. If they pick one, run \`${BUY_COMMAND} --pack <pack> --no-wait\`, ${APPROVE_THEN_RESUME}${tail}`;
65
+ }
66
+ function buyCommand(pack) {
67
+ return `${BUY_COMMAND} --pack ${pack} --no-wait`;
68
+ }
69
+ function packOption(offer) {
70
+ const scans = CREDIT_PACKS[offer.pack];
71
+ const perScan = formatPackPrice(Math.round(offer.amount / scans), offer.currency);
72
+ return {
73
+ value: offer.pack,
74
+ label: `${scans} scans · ${formatPackPrice(offer.amount, offer.currency)}`,
75
+ description: `${perScan} per scan${offer.best ? ", best value" : ""}`,
76
+ run: buyCommand(offer.pack),
77
+ };
78
+ }
79
+ /** What the human approves, in order: a one-time Link permission (or sign-in) first when Link needs it. */
80
+ function approvalNote(step) {
81
+ switch (step) {
82
+ case "sign-in":
83
+ return "Link first asks you to sign in and allow CleanSlop to request Link payments (nothing is charged), then you approve the payment in your Link app.";
84
+ case "permission":
85
+ return "Link first asks you to allow CleanSlop to request Link payments (one time; nothing is charged), then you approve the payment in your Link app.";
86
+ default:
87
+ return "You approve the payment in your Link app.";
88
+ }
89
+ }
90
+ /** The agent's prompt says it too, so the permission step is not relayed as the purchase. */
91
+ function approvalPromptTail(step) {
92
+ return step === "approve" ? "" : ` Tell the human: ${approvalNote(step)}`;
93
+ }
94
+ /** Every offered pack plus "Not now": at most four options. */
95
+ function packQuestion(offers, step, lead = "") {
96
+ return {
97
+ id: "link_credit_pack",
98
+ header: "Credits",
99
+ question: `${lead}Which CleanSlop credit pack should I buy with Link? ${approvalNote(step)}`,
100
+ options: [...offers.map(packOption), NOT_NOW],
101
+ };
102
+ }
103
+ /**
104
+ * The "buy" answer beside a promo code: one named pack buys it; several run
105
+ * `credits buy` again with `--no-promo` so it asks only which pack.
106
+ */
107
+ function buyOption(offers) {
108
+ const [only] = offers;
109
+ if (offers.length === 1 && only) {
110
+ return {
111
+ value: only.pack,
112
+ label: `Buy ${only.pack}`,
113
+ description: describePackOffer(only),
114
+ run: buyCommand(only.pack),
115
+ };
116
+ }
117
+ return {
118
+ value: "buy",
119
+ label: "Buy with Link",
120
+ description: offers.map(describePackOffer).join("; "),
121
+ run: `${BUY_COMMAND} --no-promo --no-wait`,
122
+ };
123
+ }
124
+ /** Yes/no for one pack the human or the CLI already named. */
125
+ function buyPackQuestion(id, question, pack, label = `Buy ${pack}`) {
126
+ return {
127
+ id,
128
+ header: "Credits",
129
+ question,
130
+ options: [{ value: pack, label, run: buyCommand(pack) }, NOT_NOW],
131
+ };
24
132
  }
25
133
  function purchaseUrlFor(origin) {
26
134
  return `${origin}/api/agent/v1/credits/purchases`;
@@ -47,15 +155,20 @@ function asStripeSptOffer(value) {
47
155
  : "usd",
48
156
  networkId,
49
157
  purchaseUrl,
158
+ ...(rec.best === true ? { best: true } : {}),
50
159
  };
51
160
  }
52
- /** Read a matching `stripe_spt` offer from a 402 `out_of_scans` body. */
53
- export function stripeSptOfferFromErrorBody(json, packHint) {
161
+ /** Every `stripe_spt` offer in a 402 `out_of_scans` body, in server order. */
162
+ export function stripeSptOffersFromErrorBody(json) {
54
163
  const payment = asRecord(asRecord(json)?.payment);
55
164
  const methods = Array.isArray(payment?.methods) ? payment.methods : [];
56
- const offers = methods
165
+ return methods
57
166
  .map(asStripeSptOffer)
58
167
  .filter((offer) => offer != null);
168
+ }
169
+ /** Read a matching `stripe_spt` offer from a 402 `out_of_scans` body. */
170
+ export function stripeSptOfferFromErrorBody(json, packHint) {
171
+ const offers = stripeSptOffersFromErrorBody(json);
59
172
  if (offers.length === 0)
60
173
  return null;
61
174
  const wanted = packHint && isCreditPackId(packHint) ? packHint : "p5";
@@ -71,26 +184,84 @@ function tokenMissingAction(spendRequestId) {
71
184
  async function persistPending(deps, pending) {
72
185
  await writePendingSpend(deps, pending);
73
186
  }
74
- async function pollUntilApproved(deps, pending, waitMs) {
187
+ /**
188
+ * Tells the server (billing Slack) about a spend-request transition it cannot
189
+ * see. Once per event per request; a network error or an older server that
190
+ * 404s never blocks the purchase. Call before deleting the pending file.
191
+ */
192
+ async function reportSpendRequest(deps, token, pending, event) {
193
+ if (pending.reported?.includes(event))
194
+ return;
195
+ try {
196
+ await httpRequest(deps, pending.origin, "POST", "/api/agent/v1/credits/spend-requests", {
197
+ token,
198
+ body: {
199
+ event,
200
+ spendRequestId: pending.spendRequestId,
201
+ pack: pending.pack,
202
+ amount: pending.amount,
203
+ currency: pending.currency,
204
+ testMode: pending.testMode === true,
205
+ ageMs: Math.max(0, deps.clock.now() - pending.createdAt),
206
+ },
207
+ });
208
+ }
209
+ catch {
210
+ return;
211
+ }
212
+ pending.reported = [...(pending.reported ?? []), event];
213
+ await persistPending(deps, pending);
214
+ }
215
+ /** link-cli 0.27 prints no approval page for live requests; Link notifies the app. */
216
+ const IN_LINK_APP = "in their Link app (Link sends them a notification; there is no link to open)";
217
+ /** Approving in Link, then `--resume`; "Not now" leaves the request pending. */
218
+ function paymentApprovalQuestion(what, approvalUrl) {
219
+ const where = approvalUrl
220
+ ? `Open ${approvalUrl} and approve ${what}.`
221
+ : `Approve ${what} in your Link app (Link sends you a notification).`;
222
+ return doneQuestion({
223
+ id: "link_payment_approval",
224
+ header: "Approve",
225
+ question: `${where} Done?`,
226
+ then: { run: `${BUY_COMMAND} --resume` },
227
+ notNow: "Nothing is charged unless you approve",
228
+ });
229
+ }
230
+ function notApprovedYet(pending) {
231
+ const where = pending.approvalUrl ? "in Link" : IN_LINK_APP;
232
+ return actionError("The Link payment is not approved yet.", {
233
+ kind: "approve",
234
+ humanPrompt: `Ask the human to approve this CleanSlop credit pack (${pending.pack}) ${where}. After they approve, run \`${BUY_COMMAND} --resume\`. Do not start a new purchase.`,
235
+ ...(pending.approvalUrl ? { url: pending.approvalUrl } : {}),
236
+ question: paymentApprovalQuestion(`the CleanSlop credit pack (${pending.pack})`, pending.approvalUrl),
237
+ });
238
+ }
239
+ /** Checks the spend request at least once, then polls until `waitMs` runs out. */
240
+ async function pollUntilApproved(deps, token, pending, waitMs, onMissingScope) {
75
241
  const deadline = deps.clock.now() + waitMs;
76
- while (deps.clock.now() < deadline) {
77
- const snap = await retrieveLinkSpendRequest(deps, pending.spendRequestId);
242
+ for (;;) {
243
+ const snap = await retrieveLinkSpendRequest(deps, pending.spendRequestId, {
244
+ testMode: pending.testMode,
245
+ onMissingScope,
246
+ });
78
247
  switch (snap.status) {
79
248
  case "approved":
249
+ await reportSpendRequest(deps, token, pending, "approved");
80
250
  return;
81
251
  case "denied":
82
252
  case "expired":
83
253
  case "canceled":
254
+ await reportSpendRequest(deps, token, pending, snap.status);
84
255
  deletePendingSpend(deps);
85
256
  throw actionError(`The Link spend request was ${snap.status}.`, {
86
257
  kind: "ask_human",
87
- humanPrompt: `The Link payment was ${snap.status}. Ask the person to approve a new spend request, then retry.`,
258
+ humanPrompt: `The Link payment was ${snap.status}. Ask the person whether to try again; if yes, run \`${BUY_COMMAND} --pack ${pending.pack} --no-wait\` for a new spend request.`,
259
+ question: buyPackQuestion("link_payment_retry", `The Link payment for ${pending.pack} was ${snap.status}. Try again with a new payment?`, pending.pack, "Try again"),
88
260
  });
89
261
  case "requires_action":
90
- if (snap.resolution === "auto_resume") {
91
- await deps.clock.sleep(2000);
262
+ if (snap.resolution === "auto_resume")
92
263
  break;
93
- }
264
+ await reportSpendRequest(deps, token, pending, "requires_action");
94
265
  deletePendingSpend(deps);
95
266
  throw actionError(snap.displayMessage ?? "This spend request needs another approval step.", {
96
267
  kind: "ask_human",
@@ -99,19 +270,16 @@ async function pollUntilApproved(deps, pending, waitMs) {
99
270
  });
100
271
  case "pending":
101
272
  case "unknown":
102
- await deps.clock.sleep(2000);
103
273
  break;
104
274
  default: {
105
275
  const _exhaustive = snap.status;
106
276
  throw _exhaustive;
107
277
  }
108
278
  }
279
+ if (deps.clock.now() >= deadline)
280
+ throw notApprovedYet(pending);
281
+ await deps.clock.sleep(2000);
109
282
  }
110
- throw actionError("Timed out waiting for Link payment approval.", {
111
- kind: "ask_human",
112
- humanPrompt: "The person has not approved the Link payment yet. Run `cleanslop credits buy --link --resume` after they approve it.",
113
- code: pending.spendRequestId,
114
- });
115
283
  }
116
284
  async function postPurchase(deps, origin, pending, token, sharedPaymentToken) {
117
285
  const result = await httpRequest(deps, origin, "POST", "/api/agent/v1/credits/purchases", {
@@ -137,7 +305,51 @@ async function postPurchase(deps, origin, pending, token, sharedPaymentToken) {
137
305
  const paymentIntentId = typeof rec?.paymentIntentId === "string" ? rec.paymentIntentId : null;
138
306
  return { credits, pack, paymentIntentId };
139
307
  }
308
+ /** Reads this grant's Link packs from `GET /credits/offers` (same shape as a 402). */
309
+ async function fetchStripeSptOffer(deps, origin, token, args) {
310
+ const packHint = args.pack;
311
+ const result = await httpRequest(deps, origin, "GET", "/api/agent/v1/credits/offers", {
312
+ token,
313
+ });
314
+ requireOk(result);
315
+ // An agent shell must not pick a pack for the human; a terminal keeps p5.
316
+ const offers = stripeSptOffersFromErrorBody(result.json);
317
+ const agentPicks = !packHint && !deps.io.stdinIsTTY;
318
+ // While a promo code is possible, ask buy-or-promo first (packs plus
319
+ // "Not now" already fill a question); "Buy" reruns with --no-promo.
320
+ if (agentPicks && !args.noPromo && offers.length > 0 && promoOffered(result.json)) {
321
+ throw actionError("Choose how to add scans.", {
322
+ kind: "ask_human",
323
+ humanPrompt: withPromoHint(choosePackPrompt(offers), true),
324
+ question: topUpQuestion(buyOption(offers), "This account can still use a CleanSlop promo code. How do you want to add scans?"),
325
+ });
326
+ }
327
+ if (agentPicks && offers.length > 1) {
328
+ const step = await linkPaymentStep(deps);
329
+ throw actionError("Choose a Link credit pack.", {
330
+ kind: "ask_human",
331
+ humanPrompt: choosePackPrompt(offers) + approvalPromptTail(step),
332
+ question: packQuestion(offers, step),
333
+ });
334
+ }
335
+ const offer = stripeSptOfferFromErrorBody(result.json, packHint);
336
+ if (offer)
337
+ return offer;
338
+ const message = asRecord(asRecord(result.json)?.payment)?.message;
339
+ const text = typeof message === "string" && message.trim()
340
+ ? message.trim()
341
+ : "Link credit packs are not available for this account.";
342
+ throw new CliError(text, EXIT_PAYMENT, { kind: "ask_human", humanPrompt: text });
343
+ }
344
+ /**
345
+ * Buys a Link credit pack. Default mode (a human at a terminal) creates the
346
+ * spend request and waits up to 10 minutes. `--no-wait` creates it (or checks
347
+ * the saved one), prints the approve block, and exits 10; `--resume` finishes
348
+ * the saved request. A saved request for this origin is always reused rather
349
+ * than replaced, so retries never send the person a second approval.
350
+ */
140
351
  export async function buyLinkCredits(deps, args, offer = null, opts = {}) {
352
+ const mode = linkAuthMode(args);
141
353
  const origin = resolveOrigin(deps);
142
354
  const stored = requireToken(deps, origin);
143
355
  const storedPending = readPendingSpend(deps);
@@ -149,12 +361,6 @@ export async function buyLinkCredits(deps, args, offer = null, opts = {}) {
149
361
  });
150
362
  }
151
363
  const resumeId = args.spendRequestId?.trim() || existing?.spendRequestId || null;
152
- if (args.resume && !resumeId) {
153
- throw actionError("No pending Link spend request to resume.", {
154
- kind: "ask_human",
155
- humanPrompt: "There is no pending spend request. Run `cleanslop credits buy --link --pack p5` after a scan 402, or resume the saved spend request.",
156
- });
157
- }
158
364
  let pending;
159
365
  if (resumeId) {
160
366
  const fromStore = existing && existing.spendRequestId === resumeId ? existing : null;
@@ -174,30 +380,57 @@ export async function buyLinkCredits(deps, args, offer = null, opts = {}) {
174
380
  "",
175
381
  purchaseUrl: purchaseUrlFor(origin),
176
382
  createdAt: fromStore?.createdAt ?? deps.clock.now(),
383
+ ...(fromStore?.approvalUrl ? { approvalUrl: fromStore.approvalUrl } : {}),
384
+ ...(Array.isArray(fromStore?.reported) ? { reported: fromStore.reported } : {}),
177
385
  };
178
386
  if (!pending.amount || !pending.networkId) {
179
387
  throw usageError("Resuming a spend request still needs the saved pack price and network id.");
180
388
  }
389
+ const testMode = linkSpendRequestTestMode(deps, pending.networkId);
390
+ // Older CLIs created live requests against test profiles. Link approves
391
+ // those but never issues a token, so --resume would wait forever.
392
+ const savedTestMode = fromStore?.testMode ??
393
+ (fromStore ? deps.env.get("CLEANSLOP_LINK_TEST")?.trim() === "1" : testMode);
394
+ if (savedTestMode !== testMode) {
395
+ deletePendingSpend(deps);
396
+ throw actionError("This Link spend request cannot be completed.", {
397
+ kind: "ask_human",
398
+ humanPrompt: `This Link payment was created in ${savedTestMode ? "test" : "live"} mode, but CleanSlop at ${origin} takes ${testMode ? "test" : "live"}-mode payments, so Link will never issue its token and no charge can go through. Tell the human they can cancel it in their Link app. Then run \`${BUY_COMMAND} --pack ${pending.pack} --no-wait\` for a new spend request.`,
399
+ question: buyPackQuestion("link_payment_restart", `Your earlier Link payment for ${pending.pack} cannot finish. After cancelling it in your Link app, start a new one?`, pending.pack, "Start a new payment"),
400
+ });
401
+ }
402
+ pending.testMode = testMode;
181
403
  await persistPending(deps, pending);
404
+ // The session may have changed since the request was made (a new
405
+ // `login --link`, or `link-cli auth logout`), and retrieve needs payments.
406
+ await ensureLinkPaymentScope(deps, { mode, command: BUY_COMMAND });
182
407
  }
183
408
  else {
409
+ const chosen = offer ??
410
+ (args.amount == null
411
+ ? await fetchStripeSptOffer(deps, origin, stored.token, args)
412
+ : null);
184
413
  const pack = isCreditPackId(args.pack)
185
414
  ? args.pack
186
- : offer?.pack ?? "p5";
187
- const amount = args.amount ?? offer?.amount ?? null;
415
+ : chosen?.pack ?? "p5";
416
+ const amount = args.amount ?? chosen?.amount ?? null;
188
417
  const networkId = args.networkId?.trim() ||
189
418
  deps.env.get("CLEANSLOP_STRIPE_PROFILE_ID")?.trim() ||
190
- offer?.networkId ||
419
+ chosen?.networkId ||
191
420
  "";
192
421
  if (!amount) {
193
- throw usageError("credits buy --link needs a 402 stripe_spt offer (from scan) or a test --amount");
422
+ throw usageError("credits buy --link needs a pack price from CleanSlop or a test --amount");
194
423
  }
195
424
  if (!networkId) {
196
- throw usageError("credits buy --link needs a 402 stripe_spt networkId or CLEANSLOP_STRIPE_PROFILE_ID");
425
+ throw usageError("credits buy --link needs a Stripe network id from CleanSlop or CLEANSLOP_STRIPE_PROFILE_ID");
197
426
  }
198
427
  const scans = CREDIT_PACKS[pack];
199
- const currency = offer?.currency ?? "usd";
200
- await ensureLinkPaymentScope(deps);
428
+ const currency = chosen?.currency ?? "usd";
429
+ const testMode = linkSpendRequestTestMode(deps, networkId);
430
+ await ensureLinkPaymentScope(deps, {
431
+ mode,
432
+ command: `${BUY_COMMAND} --pack ${pack}`,
433
+ });
201
434
  const created = await createLinkSpendRequest(deps, {
202
435
  networkId,
203
436
  amount,
@@ -206,6 +439,7 @@ export async function buyLinkCredits(deps, args, offer = null, opts = {}) {
206
439
  lineItem: `name:CleanSlop ${scans} scan credits,unit_amount:${amount},quantity:1`,
207
440
  total: `type:total,display_text:Total,amount:${amount}`,
208
441
  idempotencyKey: deps.randomId(),
442
+ testMode,
209
443
  });
210
444
  pending = {
211
445
  version: 1,
@@ -217,24 +451,40 @@ export async function buyLinkCredits(deps, args, offer = null, opts = {}) {
217
451
  networkId,
218
452
  purchaseUrl: purchaseUrlFor(origin),
219
453
  createdAt: deps.clock.now(),
454
+ ...(created.approvalUrl ? { approvalUrl: created.approvalUrl } : {}),
455
+ testMode,
220
456
  };
221
457
  await persistPending(deps, pending);
222
- const packLine = `Approve this CleanSlop credit pack in your Link app (${pack}, ${amount} usd).`;
223
- if (created.approvalUrl) {
224
- writeAction(deps, {
458
+ await reportSpendRequest(deps, stored.token, pending, "created");
459
+ const price = formatPackPrice(amount, currency);
460
+ const ask = created.approvalUrl
461
+ ? `Ask the human to open this link and approve this CleanSlop credit pack (${pack}: ${scans} scans for ${price}). Link may also send a notification.`
462
+ : `Ask the human to approve this CleanSlop credit pack (${pack}: ${scans} scans for ${price}) ${IN_LINK_APP}.`;
463
+ const url = created.approvalUrl ? { url: created.approvalUrl } : {};
464
+ if (mode !== "wait") {
465
+ throw actionError("Link payment approval pending.", {
225
466
  kind: "approve",
226
- humanPrompt: `Ask the human to open this link and approve this CleanSlop credit pack (${pack}, ${amount} usd). Link may also send a notification.`,
227
- url: created.approvalUrl,
467
+ humanPrompt: `${ask} After they approve, run \`${BUY_COMMAND} --resume\`.`,
468
+ ...url,
469
+ question: paymentApprovalQuestion(`the CleanSlop credit pack (${pack}: ${scans} scans for ${price})`, created.approvalUrl),
228
470
  });
229
471
  }
230
- else {
231
- deps.io.stderr(`${packLine}\n`);
232
- }
472
+ writeAction(deps, { kind: "approve", humanPrompt: `${ask} Waiting for approval.`, ...url });
233
473
  }
234
- const waitMs = linkApprovalWaitMs(args, opts);
235
- await pollUntilApproved(deps, pending, waitMs);
236
- const sharedPaymentToken = await retrieveSharedPaymentToken(deps, pending.spendRequestId);
474
+ // Link refuses retrieve without the payment scope even when `auth status`
475
+ // did not report the session's scopes: upgrade once, then retry.
476
+ let regranted = false;
477
+ const onMissingScope = async () => {
478
+ if (regranted)
479
+ return false;
480
+ regranted = true;
481
+ await grantLinkPayments(deps, { mode, command: BUY_COMMAND });
482
+ return true;
483
+ };
484
+ await pollUntilApproved(deps, stored.token, pending, linkApprovalWaitMs(args, opts), onMissingScope);
485
+ const sharedPaymentToken = await retrieveSharedPaymentToken(deps, pending.spendRequestId, { testMode: pending.testMode, onMissingScope });
237
486
  if (!sharedPaymentToken) {
487
+ await reportSpendRequest(deps, stored.token, pending, "token_missing");
238
488
  tokenMissingAction(pending.spendRequestId);
239
489
  }
240
490
  const paid = await postPurchase(deps, origin, pending, stored.token, sharedPaymentToken);
@@ -254,13 +504,40 @@ export async function runCredits(deps, args) {
254
504
  }
255
505
  return buyLinkCredits(deps, args);
256
506
  }
257
- /** If a scan 402 offers `stripe_spt`, buy that pack and retry the scan once. */
507
+ /**
508
+ * If a scan 402 offers `stripe_spt`: a human at a terminal buys that pack in
509
+ * place and the scan retries once. An agent (no TTY) gets a top-up block that
510
+ * sends it through `credits buy --link --no-wait` / `--resume`, because a
511
+ * 10-minute approval wait outlasts its shell call.
512
+ */
258
513
  export async function recoverOutOfScansIfOffered(deps, args, result, retry) {
259
514
  if (result.status !== 402)
260
515
  return result;
261
516
  const offer = stripeSptOfferFromErrorBody(result.json, args.pack);
262
517
  if (!offer)
263
518
  return result;
519
+ if (!deps.io.stdinIsTTY) {
520
+ const tail = " Then rerun the scan.";
521
+ // An explicit --pack is the human's choice; otherwise offer every pack.
522
+ const named = args.pack === offer.pack;
523
+ const offers = stripeSptOffersFromErrorBody(result.json);
524
+ const promo = promoOffered(result.json);
525
+ // Promo first: the pack question (and what Link asks) comes from `credits buy`.
526
+ const step = promo ? "approve" : await linkPaymentStep(deps);
527
+ throw new CliError("This account is out of scans.", EXIT_PAYMENT, {
528
+ kind: "top-up",
529
+ humanPrompt: withPromoHint((named
530
+ ? `Ask the human whether to buy CleanSlop credit pack ${describePackOffer(offer)} with Link. If yes, run \`${BUY_COMMAND} --pack ${offer.pack} --no-wait\`, ${APPROVE_THEN_RESUME}${tail}`
531
+ : choosePackPrompt(offers, tail)) + approvalPromptTail(step), promo),
532
+ // Three packs plus "Not now" already fill a question, so a possible
533
+ // promo code asks buy-or-promo first and `credits buy` asks the pack.
534
+ question: promo
535
+ ? topUpQuestion(buyOption(named ? [offer] : offers))
536
+ : named
537
+ ? buyPackQuestion("link_credit_pack", `This account is out of scans. Buy CleanSlop credit pack ${describePackOffer(offer)} with Link? ${approvalNote(step)}`, offer.pack)
538
+ : packQuestion(offers, step, "This account is out of scans. "),
539
+ });
540
+ }
264
541
  await buyLinkCredits(deps, args, offer, { autoBuy: true });
265
542
  return retry();
266
543
  }
@@ -1 +1 @@
1
- {"version":3,"file":"credits.js","sourceRoot":"","sources":["../../src/commands/credits.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credits.js","sourceRoot":"","sources":["../../src/commands/credits.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,26 @@ import { requireToken, resolveOrigin, peekStoredCreds } from "../credentials.js"
2
2
  import { CliError, EXIT_ACTION, EXIT_OK, usageError } from "../exit.js";
3
3
  import { httpRequest, requireOk } from "../http.js";
4
4
  import { writeJson } from "../output.js";
5
+ function shellQuote(text) {
6
+ return `'${text.replace(/'/g, `'\\''`)}'`;
7
+ }
8
+ /** Yes runs `--consent` with the exact question; no stops. */
9
+ function emailQuestion(scanId, prompt) {
10
+ return {
11
+ id: "scan_email",
12
+ header: "Email",
13
+ question: prompt,
14
+ options: [
15
+ {
16
+ value: "granted",
17
+ label: "Yes",
18
+ description: "Email the report",
19
+ run: `cleanslop email ${scanId} --consent ${shellQuote(prompt)} --reply yes`,
20
+ },
21
+ { value: "declined", label: "No", description: "Do not email it" },
22
+ ],
23
+ };
24
+ }
5
25
  function resolveScanId(deps, origin, id) {
6
26
  if (id)
7
27
  return id;
@@ -27,6 +47,8 @@ export async function runEmail(deps, args) {
27
47
  throw new CliError("Ask the human the exact question above. If they agree, rerun with --consent quoting it.", EXIT_ACTION, {
28
48
  kind: "ask_human",
29
49
  humanPrompt: prompt,
50
+ // The server's question names a recipient; the fallback is not a question.
51
+ ...(body.prompt ? { question: emailQuestion(scanId, body.prompt) } : {}),
30
52
  });
31
53
  }
32
54
  const result = await httpRequest(deps, origin, "POST", `/api/agent/v1/scans/${encodeURIComponent(scanId)}/email`, {
@@ -1 +1 @@
1
- {"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/commands/email.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/commands/email.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import { CLIENT_ID, TERMS_UPDATED_ON } from "../config.js";
2
+ import { offerGithubAfterLinkFailure } from "../connect.js";
2
3
  import { resolveOrigin, storeToken } from "../credentials.js";
3
4
  import { CliError, EXIT_OK, EXIT_POLICY, EXIT_UNEXPECTED } from "../exit.js";
4
5
  import { asErrorBody, hasIdentityPresentationChallenge, httpRequest, throwHttpError, } from "../http.js";
5
- import { ensureLinkAuth, linkAuthMode, linkSignupBody, popAttestation, presentLinkIdentity, readLinkClaimsChallenge, requireLinkSignupConsent, } from "../link.js";
6
+ import { linkAttestation, linkAuthMode, linkSignupBody, presentLinkIdentity, readLinkClaimsChallenge, requireLinkSignupConsent, } from "../link.js";
6
7
  export async function runLinkLogin(deps, args) {
7
8
  const authMode = linkAuthMode(args);
8
9
  const origin = resolveOrigin(deps);
9
10
  const consentSource = await requireLinkSignupConsent(deps, args, origin);
10
- await ensureLinkAuth(deps, { mode: authMode });
11
- const attestation = await popAttestation(deps);
11
+ const attestation = await linkAttestation(deps, { mode: authMode }).catch(offerGithubAfterLinkFailure);
12
12
  const started = await httpRequest(deps, origin, "POST", "/oauth/link", {
13
13
  headers: { Authorization: attestation.authorization },
14
14
  body: linkSignupBody(deps, TERMS_UPDATED_ON, consentSource),
@@ -20,7 +20,7 @@ export async function runLinkLogin(deps, args) {
20
20
  const presented = await presentLinkIdentity(deps, {
21
21
  aud: challenge.aud,
22
22
  nonce: challenge.nonce,
23
- });
23
+ }).catch(offerGithubAfterLinkFailure);
24
24
  const completed = await httpRequest(deps, origin, "POST", "/oauth/link", {
25
25
  headers: {
26
26
  Authorization: attestation.authorization,