@koda-sl/baker-cli 0.418.0-dev.6af3f5093 → 0.418.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 (30) hide show
  1. package/README.md +25 -56
  2. package/dist/{chunk-HTPY7G2Y.js → chunk-3BDBEN4C.js} +11 -7
  3. package/dist/chunk-3BDBEN4C.js.map +1 -0
  4. package/dist/{chunk-OEI3NLGH.js → chunk-BWG6FK2K.js} +3 -11
  5. package/dist/chunk-BWG6FK2K.js.map +1 -0
  6. package/dist/{chunk-AKX7S6ZW.js → chunk-D76DSHL2.js} +28 -15
  7. package/dist/chunk-D76DSHL2.js.map +1 -0
  8. package/dist/{chunk-LMMZ3FAC.js → chunk-DUKZOH6P.js} +3 -3
  9. package/dist/{chunk-6V6B7RPR.js → chunk-F4R4AEI4.js} +4 -4
  10. package/dist/{chunk-3FJU7BNQ.js → chunk-KQBSLWB2.js} +43 -4
  11. package/dist/chunk-KQBSLWB2.js.map +1 -0
  12. package/dist/cli.js +8185 -9217
  13. package/dist/cli.js.map +1 -1
  14. package/dist/{client-6CLQVK65.js → client-JRQD7KHG.js} +4 -4
  15. package/dist/engine/index.js +3 -3
  16. package/dist/{env-ZJLFGNH5.js → env-Q5FUIVIJ.js} +2 -4
  17. package/dist/output-FJND5UZ3.js +18 -0
  18. package/dist/{shared-C5EZVLDS.js → shared-WUMBSQPX.js} +6 -6
  19. package/package.json +1 -1
  20. package/dist/chunk-3FJU7BNQ.js.map +0 -1
  21. package/dist/chunk-AKX7S6ZW.js.map +0 -1
  22. package/dist/chunk-HTPY7G2Y.js.map +0 -1
  23. package/dist/chunk-OEI3NLGH.js.map +0 -1
  24. package/dist/output-BTVIL27G.js +0 -22
  25. /package/dist/{chunk-LMMZ3FAC.js.map → chunk-DUKZOH6P.js.map} +0 -0
  26. /package/dist/{chunk-6V6B7RPR.js.map → chunk-F4R4AEI4.js.map} +0 -0
  27. /package/dist/{client-6CLQVK65.js.map → client-JRQD7KHG.js.map} +0 -0
  28. /package/dist/{env-ZJLFGNH5.js.map → env-Q5FUIVIJ.js.map} +0 -0
  29. /package/dist/{output-BTVIL27G.js.map → output-FJND5UZ3.js.map} +0 -0
  30. /package/dist/{shared-C5EZVLDS.js.map → shared-WUMBSQPX.js.map} +0 -0
package/README.md CHANGED
@@ -865,7 +865,7 @@ baker ads x targeting-constants --constant tv_shows --locale en-US
865
865
 
866
866
  ### ChatGPT Ads (`baker ads chatgpt`)
867
867
 
868
- Read the company's ChatGPT Ads account (OpenAI's ads inside ChatGPT conversations) and how it performs, and stage changes to it that apply when the chat is published. The company connects one account in the dashboard (Brain → Integrations → ChatGPT Ads) with an API key from its Ads Manager; the key stays in Baker and never reaches the CLI, so there is no account id to pass.
868
+ Read the company's ChatGPT Ads account (OpenAI's ads inside ChatGPT conversations) and how it performs, and stage changes to it that apply when the chat is published. The company connects one account with an API key from its Ads Manager, pasted in the chat's connect card (`request_connection` `{ platform: "chatgpt-ads" }`) or in Brain → Integrations → ChatGPT Ads; the key stays in Baker and never reaches the CLI, so there is no account id to pass.
869
869
 
870
870
  | Subcommand | What it returns |
871
871
  |---|---|
@@ -1109,23 +1109,10 @@ baker ads linkedin analytics --level campaign --campaign-id 1234 \
1109
1109
  # "Top companies seeing this campaign" (ABM feedback loop) — org names auto-resolved
1110
1110
  baker ads linkedin top-companies --campaign-id 1234 --last-days 30
1111
1111
 
1112
- # "Which companies are our ads reaching?" — one row per company over the whole period,
1113
- # most engaged first ({org, name, impressions, clicks, engagements, costLocal}).
1114
- # Defaults: last 12 calendar months, the only selected ad account, top 100 (--full for all).
1115
- baker ads linkedin companies --account-id 1234
1116
- baker ads linkedin companies --by month --min-impressions 50 # months[] per company
1117
- baker ads linkedin companies --campaign-id 1,2 --by campaign # campaigns[] per company
1118
- baker ads linkedin companies --with-domains --stats --output csv # + domain/domainSource; read-quality stats
1119
-
1120
1112
  # "Who are these org URNs?" — resolve org URNs to company names (probe leakage)
1121
1113
  baker ads linkedin resolve --urns urn:li:organization:17719,urn:li:organization:19022
1122
1114
  baker ads linkedin resolve --ids 17719,19022 --output csv
1123
1115
 
1124
- # "What are these companies' website domains?" — for matching against CRM companies.
1125
- # Per org: vanityName (LinkedIn page), website, domain, domainSource (website | subdomain | none);
1126
- # ids LinkedIn doesn't know land in `errors`. Shortlinks are never followed.
1127
- baker ads linkedin resolve --ids 1035,1337 --with-domains
1128
-
1129
1116
  # "Who is in our audience by industry/seniority/function/title — all at once?"
1130
1117
  baker ads linkedin demographics --campaign-id 1234 --last-days 30
1131
1118
 
@@ -1194,7 +1181,6 @@ creatives # default ACTIVE intended-status
1194
1181
 
1195
1182
  analytics # see "Smart defaults" above (3-axis: level × intent × pivot)
1196
1183
  demographics # sweep all firmographic pivots in one call
1197
- companies # which companies the ads reached, one row per company (--by month|campaign, --with-domains)
1198
1184
  top-companies # pivot=MEMBER_COMPANY shortcut (ABM)
1199
1185
  conversation # pivot=CONVERSATION_NODE_BUTTON shortcut (Sponsored Messaging)
1200
1186
 
@@ -1214,7 +1200,6 @@ audit --format md # deliverable-ready markdown table
1214
1200
  campaign-groups create|update|pause|resume|duplicate # staged writes (see below)
1215
1201
  campaigns create|update|pause|resume|archive|duplicate
1216
1202
  campaigns url-params <ad-set-id> # UTMs for every ad in the ad set
1217
- campaigns exclude-companies <ad-set-id> --org <ids> # stop an ad set reaching these companies
1218
1203
  account url-params # UTMs for every ad in the whole account
1219
1204
  url-params [--ad-sets] # read what is tagged now, and what lands twice
1220
1205
  creatives create|update|pause|resume|duplicate
@@ -1255,16 +1240,9 @@ baker ads linkedin account url-params --param "utm_source=linkedin&utm_medium=pa
1255
1240
  baker ads linkedin campaigns update 123456 --audience-expansion off --lan off
1256
1241
  baker ads linkedin campaigns update 123456 --bid 7.50 --daily-budget 100 --currency USD
1257
1242
 
1258
- # Matched audiences (CSV with header; email columns SHA-256 hashed locally).
1259
- # Company lists take companyName,domain,organizationUrn — organizationUrn matches the company page exactly
1243
+ # Matched audiences (CSV with header; email columns SHA-256 hashed locally)
1260
1244
  baker ads linkedin audiences create --name "ABM Tier-1" --type company-list --list-file accounts.csv
1261
1245
 
1262
- # Stop an ad set reaching customers / open deals — add-only; at publish Baker re-reads the ad set
1263
- # and merges into its targeting as it stands then. --org takes company ids, ≤200 per call;
1264
- # a longer list goes into a company-list audience passed as --segment
1265
- baker ads linkedin campaigns exclude-companies 123456 --org 1035,1441
1266
- baker ads linkedin campaigns exclude-companies 123456 --segment urn:li:dmpSegment:42
1267
-
1268
1246
  # Conversions with playbook-default windows
1269
1247
  baker ads linkedin conversions create --name "Demo booked" --type LEAD --method INSIGHT_TAG \
1270
1248
  --post-click-window 30 --view-window 7
@@ -1326,7 +1304,7 @@ Each finding: `{id, area, check, status, severity, evidence, fix: {explanation,
1326
1304
  - OAuth tokens auto-refresh server-side. On 401, reconnect LinkedIn from dashboard → integrations.
1327
1305
  - Account scoping: backend rejects calls against an account not in the picker selection.
1328
1306
  - Pinned API version: `Linkedin-Version: 202606` (declared in `oauth/constants.ts`). Bump as a coordinated change — LinkedIn deprecates monthly with a ~12-month support window. The floor is `TRACKING_PARAM_DYNAMIC_MIN_API_VERSION` (`CREATIVE_NAME` needs 202606), asserted in `ads/linkedin/utils.test.ts`.
1329
- - Cache TTLs: accounts/account-detail 1h, listings 30m, analytics 15m–6h (depends on date range), facets 7d, urn-resolve 1h, org domains 7d, bid-pricing/forecast 6h, audience-size 1h.
1307
+ - Cache TTLs: accounts/account-detail 1h, listings 30m, analytics 15m–6h (depends on date range), facets 7d, urn-resolve 1h, bid-pricing/forecast 6h, audience-size 1h.
1330
1308
  - `--no-cache` on any command skips both cache layers (the CLI's own and the server's).
1331
1309
 
1332
1310
  #### LinkedIn-specific gotchas
@@ -3752,12 +3730,13 @@ Permissions enforced server-side:
3752
3730
 
3753
3731
  ---
3754
3732
 
3755
- ### `baker mcp connected | list | add | remove`
3733
+ ### `baker mcp connected | catalog | list | add | remove`
3756
3734
 
3757
3735
  See everything a chat can reach — managed integrations, custom servers, and connected platforms — and manage **custom MCP servers** by pointing the agent at any remote HTTPS MCP endpoint. Registered tools appear as `mcp__<name>__*` on the next chat message.
3758
3736
 
3759
3737
  ```bash
3760
3738
  baker mcp connected
3739
+ baker mcp catalog --search notion
3761
3740
  baker mcp list
3762
3741
  baker mcp add --name weather --url https://mcp.example.com/mcp
3763
3742
  baker mcp add --name acme --url https://acme.dev/mcp --header "Authorization: Bearer sk-…"
@@ -3766,6 +3745,7 @@ baker mcp remove --name weather
3766
3745
  ```
3767
3746
 
3768
3747
  - `connected` returns three lists. `managed` and `custom` are MCP tools the agent calls directly; `platforms` are the accounts the company signed in to (HubSpot, Google Ads, GA4, Search Console, Tag Manager, LinkedIn Ads), each with its login and the resources it may read. A platform has **no** `mcp__*` tools — it is read through its own command family — so it is listed here to keep the agent from concluding a working connection is missing.
3748
+ - `catalog --search <name> [--limit 1-20]` searches the managed apps a user can connect when a vendor has no MCP server of its own. Each app reports its slug (`app`), how the user connects it (`sign-in` or `key`; apps that need no sign-in cannot be connected and are left out) — never a managed copy of one of Baker's own connections: those come back under `platforms`, to ask for with `{ platform }` and whether this chat already reaches it (`connected`).
3769
3749
  - `--url` must be the **full MCP endpoint** (commonly ending in `/mcp`), HTTPS and public; loopback / private / cloud-metadata hosts are rejected. A bare domain frequently accepts the OAuth sign-in and then serves no tools, so every address is handshake-checked after it changes: `connected` and `list` report `usable: false` plus a `problem` (and a `suggestedAddress` when the server advertises a better endpoint) for a server that isn't serving tools, or `lastCheck: failed` when the last check only hit an outage — that one may work anyway, and a later turn re-checks it automatically. Repointing a server at a different host clears its saved sign-in: a token belongs to the host that issued it, so the server has to be connected again.
3770
3750
  - Scope is two independent choices — audience (just you / everyone) × level (this company / whole org):
3771
3751
  - `--scope company` (default) — everyone in this company.
@@ -3812,7 +3792,24 @@ baker history list --category ads --full # ad writes with raw metadata
3812
3792
 
3813
3793
  ---
3814
3794
 
3815
- ### `baker hubspot forms list | view | submissions` · `baker hubspot workflows list | view` · `baker hubspot pipelines list` · `baker hubspot contacts summary | lookup | properties | fields` · `baker hubspot companies search` · `baker hubspot deals list | properties | fields` · `baker hubspot meetings list | view`
3795
+ ### `baker credentials list | put | delete`
3796
+
3797
+ Credentials are a company's stored API keys, tokens and passwords. The CLI never returns a value: each credential has a placeholder, `{{credential:NAME}}`, that a request inside a Baker Session can carry in any header, URL or body. The Session's HTTPS proxy fills in the value only for the hosts the credential is bound to, and puts the placeholder back in responses.
3798
+
3799
+ ```bash
3800
+ baker credentials list # name, placeholder, allowedHosts, label
3801
+ baker credentials list --full # + source, lastUsedAt
3802
+ printf %s "$KEY" | baker credentials put stripe-key --host api.stripe.com --label "Stripe key"
3803
+ baker credentials delete stripe-key
3804
+ ```
3805
+
3806
+ - `put` reads the value from **stdin only** — a `--value` flag or a positional value is refused, because argv is visible to other processes. One trailing newline is trimmed; empty stdin is refused. `--host` is repeatable (or comma-separated) and accepts `*.example.com` wildcards.
3807
+ - `put` and `delete` act only on credentials the agent created. Credentials a person added are managed in the dashboard (Settings → Credentials).
3808
+ - The company must have credentials switched on; otherwise every command answers `FORBIDDEN`.
3809
+
3810
+ ---
3811
+
3812
+ ### `baker hubspot forms list | view | submissions` · `baker hubspot workflows list | view` · `baker hubspot pipelines list` · `baker hubspot contacts summary | lookup | properties | fields` · `baker hubspot deals properties | fields` · `baker hubspot meetings list | view`
3816
3813
 
3817
3814
  Read-only view of the company's **connected HubSpot account** — the forms and meeting links (calendars) that live there, the leads those forms received, and the workflows, deal pipelines, and contact records a lead runs through afterwards. Fetched from HubSpot live on every call; nothing is cached and nothing is ever written back.
3818
3815
 
@@ -3834,8 +3831,6 @@ baker hubspot pipelines list # where a lead lands, and the st
3834
3831
  baker hubspot contacts summary --days 30 # are recent leads being worked? (counts only)
3835
3832
  baker hubspot contacts lookup lead@example.com # was this one lead picked up?
3836
3833
  baker hubspot contacts properties # what a HubSpot-read source can watch, with each value
3837
- baker hubspot companies search --domains acme.com,globex.io --with-deals # CRM accounts by domain, with their deals
3838
- baker hubspot deals list --pipeline default --modified-since 2026-01-01 # deals: amount, stage, closed won
3839
3834
  baker hubspot meetings list # every calendar + whether booking redirects
3840
3835
  baker hubspot meetings view <slug> # booking-form fields for one calendar
3841
3836
  baker hubspot meetings view <slug> --as-node # the form.external blob for a flow node
@@ -3846,9 +3841,7 @@ baker hubspot meetings view <slug> --as-node # the form.external blob for a f
3846
3841
  **`forms submissions`:** positional `<formId>`; `--days <1-365>` (default 30) sets the window; `--full` adds each submission's field values. The default response is counts and dates only — `total`, `inWindow`, `lastSubmittedAt`, and per-day counts — because submissions carry the lead's own contact details. `truncated: true` means the page budget ran out before the window was covered, so `inWindow` is a floor rather than an exact count.
3847
3842
  **`workflows list` flags:** `--search <text>`, `--enabled-only`. Disabled workflows are listed too — a form wired to one that is off looks connected and does nothing.
3848
3843
  **`workflows view`:** positional `<workflowId>` (the id from `workflows list`, and the one in HubSpot's own URL — the command translates it to HubSpot's separate internal flow id for you). Returns the enrolment criteria and whether it re-enrols (`null` = HubSpot does not report it for that criteria type, so it is unknown rather than off), plus every step with the property it writes. On a `LIST_BRANCH` step, branches come back in **evaluation order** (`order: 1` wins over `order: 2`) — a broad branch above a narrower one silently swallows the records the narrow one was written for, and HubSpot reports nothing. A `STATIC_BRANCH` matches on a value rather than top down, so its `order` is display only. `steps` is **not** in execution order; follow `nextActionId`. `--full` adds the raw payload, the only place the branch filter criteria (which property is compared to which value) can be read.
3849
- **`pipelines list`:** no flags; stages come back in the order they run in HubSpot, each with `isClosed` and `isWon` (closed with probability 1).
3850
- **`companies search` flags:** `--domains <a.com,b.com>` (up to 100; a URL or `www.` is reduced to the bare domain), `--names <"Acme, Inc.;Globex">` (semicolon-separated), `--with-deals`, `--limit <1-500>` (default 100), `--output json|csv|jsonl|md`. Rows: `{ id, name, domain, linkedinPage, deals? }`; `notFound` lists the searched domains no CRM company carries; `truncated: true` means more matched than `--limit`.
3851
- **`deals list` flags:** `--pipeline <id,id>`, `--modified-since <YYYY-MM-DD>`, `--limit <1-1000>` (default 200), `--after <cursor>`, `--output json|csv|jsonl|md`. Rows, oldest change first: `{ id, name, amount, currency, pipelineId, stageId, stageLabel, isClosed, isWon, createdAt, closedAt, modifiedAt, companyIds }` — `amount: null` is none entered. `next` is the `--after` for the following page; `restartFrom` appears when HubSpot's 10,000-result search ceiling is reached (read on with `--modified-since <restartFrom>`); `companiesReadable: false` means the connection cannot read companies, so no deal carries `companyIds`.
3844
+ **`pipelines list`:** no flags; stages come back in the order they run in HubSpot.
3852
3845
  **`contacts summary` flags:** `--days <1-365>` (default 30) over contact creation date. Returns counts only — total contacts, how many have an owner, and the lifecycle-stage split — never a name or an email. `truncated: true` means the page budget ran out, so the counts are floors.
3853
3846
  **`contacts lookup`:** positional `<email>`; returns that contact's lifecycle stage, owner, the account (company) it was filed under, and associated deals with their stage. `dealsReadable: false` / `companyReadable: false` mean the connection does not cover deals or accounts, so an empty `deals` or a null `company` is unknown rather than absent. `found: false` means no contact with that email — the lead never reached the CRM, which is a finding rather than an error.
3854
3847
  **`contacts properties`:** no flags; returns every contact property with a closed list of values — `{ name, label, groupName, options: [{ value, label }] }` — the ones a HubSpot-read source can watch. Names are HubSpot's internal ones; hand them to `baker analytics sources --create-hubspot --property <name> --value <value>` as printed. No personal data.
@@ -3880,30 +3873,6 @@ No write surface against HubSpot itself — a form's fields, redirect, or consen
3880
3873
 
3881
3874
  ---
3882
3875
 
3883
- ### `baker accounts influenced | engagement | warm | company | campaigns | crm`
3884
-
3885
- Account insights: which companies the LinkedIn ads are warming, and which CRM deals they influenced. Reads Baker's nightly copy of LinkedIn and the CRM, so it is fast and covers up to 24 months; nothing is changed anywhere. Only for companies with Account insights switched on — otherwise every command exits 1 with `ACCOUNTS_NOT_ENABLED` and an `error.fix` pointing at the live read (`baker ads linkedin companies`, plus `baker hubspot companies search`). `--start`/`--end` must be real calendar days within 24 calendar months; a bad flag or an unsupported `--output` exits 1 with `INVALID_ARGS`.
3886
-
3887
- ```bash
3888
- baker accounts influenced # influenced pipeline, last 12 calendar months
3889
- baker accounts influenced --basis revenue --start 2026-01-01 --end 2026-06-30
3890
- baker accounts influenced --full # every deal in the period, influenced or not
3891
- baker accounts engagement --last-months 3 --limit 50 # companies reached, New/Rising, CRM match and deals
3892
- baker accounts engagement --campaign-id 123456 --output csv
3893
- baker accounts warm --output csv > warm.csv # companyName,domain,organizationUrn
3894
- baker accounts company acme.com # or a LinkedIn company id / urn:li:organization:N
3895
- baker accounts campaigns --last-months 6 --output md # per campaign: reached, engaged, influenced pipeline (--basis revenue)
3896
- baker accounts influenced --model awareness --threshold 10 --output csv # another rule, this call only
3897
- baker accounts warm --min 0 # every New/Rising company, below the threshold too
3898
- baker accounts crm status # deals from HubSpot or sent by the client; what arrived, linked Google Sheets
3899
- baker accounts crm check --file deals.csv # judge a deals or company CSV offline, nothing sent
3900
- baker accounts crm contract # the send-your-CRM contract, as Markdown for a developer
3901
- ```
3902
-
3903
- A deal is **influenced** when its company reached the company's influence rule — by default 3+ LinkedIn ad engagements (Awareness: 7+ impressions; Intent: 3+ clicks) — in the 12 months up to and including the month the deal was created (`--basis pipeline`, deals not won) or closed won (`--basis revenue`). It is a labelled rule, not credit: campaign rows overlap, and money is reported per currency, never summed across currencies. Deals whose company match is only a guess come back under `lowConfidence` and stay out of `summary` until the match is confirmed in Measure → Accounts. Without the deals set up there — HubSpot's pipelines and won/lost stages, or Another CRM — `influenced` and `campaigns` exit 1 with `ACCOUNTS_NOT_SET_UP`. A CRM Baker cannot read sends its companies and deals to `POST /v1/accounts/crm` (a `crm_ingest` key, `X-Baker-Mode: test` to rehearse, up to 500 records per request, records naming a person refused), is uploaded as a CSV in Measure → Accounts, or lives in a Google Sheet linked there that Baker reads every night (a row deleted from the sheet leaves Baker). A file is a deals export or a company list — a company needs only its website or LinkedIn page; `crm check` runs the same rules offline and `crm contract` prints the whole contract. The CLI never sends deals or links a sheet. `--model engagement|awareness|intent` and `--threshold N` on `influenced`, `campaigns` and `warm` read with another rule for that call only; the saved setting is unchanged. A **warm** account is New or Rising, reached the company's influence threshold this period on the rule's metric (`--min N` overrides, `--min 0` drops it), and has no open deal, no won deal and no deal lost in the last 6 months; `engagement` and `warm` rows carry `dealStatus` (`won` > `open` > `lost` > `none`), `engagement --output csv` adds `lastMonth` and `previousImpressions/Clicks/Engagements`, and `campaigns` / `company` carry each campaign's `campaignName` (null when LinkedIn could not name it). `company` returns `months` (the company's totals), `byCampaign` (the same numbers per campaign — overlapping, never add them) and its `deals` with `touchValue` and `influenced`. `warm --output csv` is the file `baker ads linkedin audiences create --type company-list --list-file` takes.
3904
-
3905
- ---
3906
-
3907
3876
  ### `baker chats list | view | transcript | diff`
3908
3877
 
3909
3878
  Read-only inspection of **other Sessions (chats) on the same account** — so an agent can reuse prior work ("like we did in that other chat, but for X"). Same-account only; never crosses a company boundary and has no write surface.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  debugLogHttp,
3
3
  readBodyForLog
4
- } from "./chunk-3FJU7BNQ.js";
4
+ } from "./chunk-KQBSLWB2.js";
5
5
  import {
6
6
  API_KEY_FORMAT_MESSAGE,
7
7
  DIRECT_ROUTE,
@@ -14,15 +14,16 @@ import {
14
14
  isChallengeBody,
15
15
  isPrivateAddress,
16
16
  isProxyFailure,
17
+ nextPlannedRoute,
17
18
  plannedRoutes,
18
19
  refuseNonPublicUrl,
19
20
  requireConnection,
20
21
  shouldEscalate
21
- } from "./chunk-AKX7S6ZW.js";
22
+ } from "./chunk-D76DSHL2.js";
22
23
 
23
- // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/index.js
24
+ // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
24
25
  var require_safe_stable_stringify = __commonJS({
25
- "../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/index.js"(exports, module) {
26
+ "../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
26
27
  "use strict";
27
28
  var { hasOwnProperty } = Object.prototype;
28
29
  var stringify = configure2();
@@ -1144,7 +1145,7 @@ function resolveAdaptFormats(params) {
1144
1145
  return params.formats ?? [];
1145
1146
  }
1146
1147
 
1147
- // ../../.pnpm-store/v10/links/@/safe-stable-stringify/2.5.0/766ad107c42df28eeadaf0ac2f9089c8a9e200f6ba0b2b1a817b8d536cbdcc49/node_modules/safe-stable-stringify/esm/wrapper.js
1148
+ // ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
1148
1149
  var import__ = __toESM(require_safe_stable_stringify(), 1);
1149
1150
  var configure = import__.default.configure;
1150
1151
  var wrapper_default = import__.default;
@@ -6818,9 +6819,12 @@ async function fetchWithEscalation(url, init, options) {
6818
6819
  let originResponse = null;
6819
6820
  let originTier = "direct";
6820
6821
  let lastError;
6821
- for (const route of plannedRoutes(url, options.credentials, options.routeOptions)) {
6822
+ const routes = plannedRoutes(url, options.credentials, options.routeOptions);
6823
+ const tried = [];
6824
+ for (let route = routes[0] ?? null; route !== null; route = nextPlannedRoute(routes, tried)) {
6822
6825
  const rung = await attemptRoute(url, init, route, options);
6823
6826
  attempts.push(rung.attempt);
6827
+ tried.push({ tier: rung.attempt.tier, proxyFailure: rung.attempt.outcome === "proxy_unavailable" });
6824
6828
  if (rung.response !== null) {
6825
6829
  originResponse = rung.response;
6826
6830
  originTier = rung.attempt.tier;
@@ -11630,4 +11634,4 @@ export {
11630
11634
  defaultRegistry,
11631
11635
  createEngineFromEnv
11632
11636
  };
11633
- //# sourceMappingURL=chunk-HTPY7G2Y.js.map
11637
+ //# sourceMappingURL=chunk-3BDBEN4C.js.map