From 92be0b69f74d40bddb2748939d27c5b9f2660f46 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 11:32:39 +0000 Subject: [PATCH 01/11] feat(api): api update --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 349bddd..a5e14f2 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/charmbracelet/bubbletea v1.3.6 github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/x/term v0.2.1 - github.com/context-dot-dev/context-go-sdk/v2 v2.7.0 + github.com/context-dot-dev/context-go-sdk/v2 v2.8.0 github.com/goccy/go-yaml v1.18.0 github.com/itchyny/json2yaml v0.1.4 github.com/muesli/reflow v0.3.0 diff --git a/go.sum b/go.sum index b30c4e4..738ff27 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payR github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= -github.com/context-dot-dev/context-go-sdk/v2 v2.7.0 h1:zc4xevss1ms1jge3wTn0qgynanmORhvFJav8eLfaiIY= -github.com/context-dot-dev/context-go-sdk/v2 v2.7.0/go.mod h1:CvRANWLP0FHj5XyUwzEVX79ujdwr/2Jy375UVzKNQm8= +github.com/context-dot-dev/context-go-sdk/v2 v2.8.0 h1:K7a/NQIXa4C3VLiF+1cCDyAMGIEnsva2CdkKaYqzC5Q= +github.com/context-dot-dev/context-go-sdk/v2 v2.8.0/go.mod h1:CvRANWLP0FHj5XyUwzEVX79ujdwr/2Jy375UVzKNQm8= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= From feaa96cadeaebcfcbff2f0bc023a296b3332cbea Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 18:49:28 +0000 Subject: [PATCH 02/11] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 74e73bc..9ea03e0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-155e4761d62255841349c0f8a01b0a9c463ea1d1f2d6c4fd8d1a75c8bef6f226.yml -openapi_spec_hash: ab91f77e7c9d992400cbc7fc8a9e76c1 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-8a92cb064637006331b2910caedca8512290c1d8cc75eb91218393cc1581e59c.yml +openapi_spec_hash: c811ec47143ad01cdbcbd8324caa4eda config_hash: bff282047fafdad771fb7ec685f56944 From 4ca42b8b8bdbe6750a50db1bc39b4ff098346f65 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 03:09:13 +0000 Subject: [PATCH 03/11] feat(api): api update --- .stats.yml | 4 ++-- pkg/cmd/web.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9ea03e0..9a1a53d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-8a92cb064637006331b2910caedca8512290c1d8cc75eb91218393cc1581e59c.yml -openapi_spec_hash: c811ec47143ad01cdbcbd8324caa4eda +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-e6a3365124af52952a85c8af5a09d6fdc02a686db7949985d0a6313dfad8dee5.yml +openapi_spec_hash: d7d0e17252f6f5665fb1698e37e09fe2 config_hash: bff282047fafdad771fb7ec685f56944 diff --git a/pkg/cmd/web.go b/pkg/cmd/web.go index 9f5b105..86de982 100644 --- a/pkg/cmd/web.go +++ b/pkg/cmd/web.go @@ -703,7 +703,7 @@ var webWebScrapeHTML = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.InnerFlag[any]{ Name: "pdf.should-parse", - Usage: "When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.", + Usage: "When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned.", InnerField: "shouldParse", }, &requestflag.InnerFlag[int64]{ @@ -917,7 +917,7 @@ var webWebScrapeMd = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.InnerFlag[any]{ Name: "pdf.should-parse", - Usage: "When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.", + Usage: "When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED is returned.", InnerField: "shouldParse", }, &requestflag.InnerFlag[int64]{ From 5650e87248bd4d1dabd6027007f510650684d511 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 05:46:27 +0000 Subject: [PATCH 04/11] feat(api): api update --- .stats.yml | 4 ++-- pkg/cmd/parse.go | 2 +- pkg/cmd/web.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.stats.yml b/.stats.yml index 9a1a53d..f57748b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-e6a3365124af52952a85c8af5a09d6fdc02a686db7949985d0a6313dfad8dee5.yml -openapi_spec_hash: d7d0e17252f6f5665fb1698e37e09fe2 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-b73de7a5f87b3bed7d9e4259bd109cd62f4eb5f61fa082f31fc22d5bf8e69bcc.yml +openapi_spec_hash: 5dcb5ba9b8487329adc2f89eeb4df7c4 config_hash: bff282047fafdad771fb7ec685f56944 diff --git a/pkg/cmd/parse.go b/pkg/cmd/parse.go index 5403297..92f2356 100644 --- a/pkg/cmd/parse.go +++ b/pkg/cmd/parse.go @@ -51,7 +51,7 @@ var parseHandle = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[any]{ Name: "ocr", - Usage: "When true for PDF inputs, detect and OCR images embedded in the selected pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. pdf.start/pdf.end limit the inclusive page range. When false, all OCR is disabled, including the automatic scanned-PDF fallback.", + Usage: "When true for PDF inputs, detect and OCR images embedded in the selected pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. pdf.start/pdf.end limit the inclusive page range. When false, no OCR runs.", Default: false, QueryPath: "ocr", }, diff --git a/pkg/cmd/web.go b/pkg/cmd/web.go index 86de982..a8c8e03 100644 --- a/pkg/cmd/web.go +++ b/pkg/cmd/web.go @@ -698,7 +698,7 @@ var webWebScrapeHTML = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.InnerFlag[any]{ Name: "pdf.ocr", - Usage: "When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.", + Usage: "When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. When false, no OCR runs.", InnerField: "ocr", }, &requestflag.InnerFlag[any]{ @@ -912,7 +912,7 @@ var webWebScrapeMd = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.InnerFlag[any]{ Name: "pdf.ocr", - Usage: "When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.", + Usage: "When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. When false, no OCR runs.", InnerField: "ocr", }, &requestflag.InnerFlag[any]{ From ad502925051676385440177ba5a4113631ff2dfa Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 07:45:58 +0000 Subject: [PATCH 05/11] feat(api): api update --- .stats.yml | 4 ++-- pkg/cmd/web.go | 7 ++++++- pkg/cmd/web_test.go | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index f57748b..15a2673 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-b73de7a5f87b3bed7d9e4259bd109cd62f4eb5f61fa082f31fc22d5bf8e69bcc.yml -openapi_spec_hash: 5dcb5ba9b8487329adc2f89eeb4df7c4 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-b5a46cf886759797353b250da971e46cf66804b825ded9c51609f34d72d1169c.yml +openapi_spec_hash: 1947de2a731ddab05bfb781f37cd42b6 config_hash: bff282047fafdad771fb7ec685f56944 diff --git a/pkg/cmd/web.go b/pkg/cmd/web.go index a8c8e03..7b1229e 100644 --- a/pkg/cmd/web.go +++ b/pkg/cmd/web.go @@ -930,7 +930,7 @@ var webWebScrapeMd = requestflag.WithInnerFlags(cli.Command{ var webWebScrapeSitemap = cli.Command{ Name: "web-scrape-sitemap", - Usage: "Crawl an entire website's sitemap and return all discovered page URLs.", + Usage: "Crawl an entire website's sitemap and return all discovered page URLs. Pass\n`search` to have the crawled sitemap filtered down to the pages about a phrase\n(for example `pricing and plans` or `api authentication docs`), most relevant\nfirst — a searched crawl scans the whole sitemap and costs 2 credits instead\nof 1.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[string]{ @@ -950,6 +950,11 @@ var webWebScrapeSitemap = cli.Command{ Default: 10000, QueryPath: "maxLinks", }, + &requestflag.Flag[string]{ + Name: "search", + Usage: "Optional search phrase. When provided, the crawled sitemap is filtered to the pages whose URLs are about that phrase, most relevant first, and the request costs 2 credits instead of 1.", + QueryPath: "search", + }, &requestflag.Flag[string]{ Name: "sitemap-url", Usage: "Optional explicit sitemap URL. When provided, exactly this sitemap is crawled instead of discovering the domain's sitemaps.", diff --git a/pkg/cmd/web_test.go b/pkg/cmd/web_test.go index 8eda947..3505637 100644 --- a/pkg/cmd/web_test.go +++ b/pkg/cmd/web_test.go @@ -583,6 +583,7 @@ func TestWebWebScrapeSitemap(t *testing.T) { "--domain", "xxx", "--headers", "{foo: J!}", "--max-links", "1", + "--search", "help center and troubleshooting articles", "--sitemap-url", "https://example.com", "--tag", "production", "--tag", "team-alpha", From 48a68cb9ad422157ee55deef66773a161e320f44 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 20:23:50 +0000 Subject: [PATCH 06/11] feat(api): api update --- .stats.yml | 4 ++-- pkg/cmd/brand.go | 2 +- pkg/cmd/parse.go | 2 +- pkg/cmd/web.go | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.stats.yml b/.stats.yml index 15a2673..3eddd36 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-b5a46cf886759797353b250da971e46cf66804b825ded9c51609f34d72d1169c.yml -openapi_spec_hash: 1947de2a731ddab05bfb781f37cd42b6 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-3ecc6285243f60f7619d543cac59991015fbb0a156648741e7e42e619e0cbc5c.yml +openapi_spec_hash: 0130f29a501366c63cbd3a446c5eb109 config_hash: bff282047fafdad771fb7ec685f56944 diff --git a/pkg/cmd/brand.go b/pkg/cmd/brand.go index 742bfe7..ba05fd9 100644 --- a/pkg/cmd/brand.go +++ b/pkg/cmd/brand.go @@ -154,7 +154,7 @@ var brandRetrieveSimplified = cli.Command{ var brandSearch = cli.Command{ Name: "search", - Usage: "Search brands by name or domain and get back up to 10 lightweight matches\n(domain, name, logo), most popular first: by Tranco rank, then market cap for\nbrands outside the Tranco list, with text relevance breaking ties. Matching is\nprefix-based with no typo tolerance, so it is suited to autocomplete. Only\nbrands already in the Context.dev index are returned — use /brand/retrieve to\nfetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit\nper request on the Free and Starter plans.", + Usage: "Search brands by name or domain and get back up to 10 lightweight matches\n(domain, name, logo). Name matches rank ahead of domain matches; within each\ngroup the most popular brands come first: by Tranco rank, then market cap for\nbrands outside the Tranco list, with text relevance breaking ties. Matching is\nprefix-based with no typo tolerance, so it is suited to autocomplete. Only\nbrands already in the Context.dev index are returned — use /brand/retrieve to\nfetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit\nper request on the Free and Starter plans.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[string]{ diff --git a/pkg/cmd/parse.go b/pkg/cmd/parse.go index 92f2356..c047893 100644 --- a/pkg/cmd/parse.go +++ b/pkg/cmd/parse.go @@ -51,7 +51,7 @@ var parseHandle = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.Flag[any]{ Name: "ocr", - Usage: "When true for PDF inputs, detect and OCR images embedded in the selected pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. pdf.start/pdf.end limit the inclusive page range. When false, no OCR runs.", + Usage: "When true for PDF inputs, OCR the selected pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real text layer keep it. pdf.start/pdf.end limit the inclusive page range. Billed at 1 credit per page OCR actually recovered, on top of the base request cost. When false, no OCR runs.", Default: false, QueryPath: "ocr", }, diff --git a/pkg/cmd/web.go b/pkg/cmd/web.go index 7b1229e..04af894 100644 --- a/pkg/cmd/web.go +++ b/pkg/cmd/web.go @@ -583,7 +583,7 @@ var webWebCrawlMd = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.InnerFlag[bool]{ Name: "pdf.ocr", - Usage: "When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.", + Usage: "When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real text layer keep it. Billed at 1 credit per page OCR actually recovered, on top of the base request cost.", InnerField: "ocr", }, &requestflag.InnerFlag[bool]{ @@ -698,7 +698,7 @@ var webWebScrapeHTML = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.InnerFlag[any]{ Name: "pdf.ocr", - Usage: "When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. When false, no OCR runs.", + Usage: "When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real text layer keep it. Billed at 1 credit per page OCR actually recovered, on top of the base request cost. When false, no OCR runs.", InnerField: "ocr", }, &requestflag.InnerFlag[any]{ @@ -912,7 +912,7 @@ var webWebScrapeMd = requestflag.WithInnerFlags(cli.Command{ }, &requestflag.InnerFlag[any]{ Name: "pdf.ocr", - Usage: "When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. When false, no OCR runs.", + Usage: "When true, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real text layer keep it. Billed at 1 credit per page OCR actually recovered, on top of the base request cost. When false, no OCR runs.", InnerField: "ocr", }, &requestflag.InnerFlag[any]{ From 4f0ee9af80ade4dc0bf8fe3c78ecead9a207117d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 23:35:59 +0000 Subject: [PATCH 07/11] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3eddd36..2c6e57f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-3ecc6285243f60f7619d543cac59991015fbb0a156648741e7e42e619e0cbc5c.yml -openapi_spec_hash: 0130f29a501366c63cbd3a446c5eb109 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-2f28cd1bf5b88305989d68dc55037fe25bdba2800d61c071a848cc1eb1ccb225.yml +openapi_spec_hash: 6dd2807c7804e08c1d49479c0ff82e47 config_hash: bff282047fafdad771fb7ec685f56944 From 2f06be9390f1e9fa30c677d427681cba6c959c54 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 23:45:51 +0000 Subject: [PATCH 08/11] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2c6e57f..b90c8da 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-2f28cd1bf5b88305989d68dc55037fe25bdba2800d61c071a848cc1eb1ccb225.yml -openapi_spec_hash: 6dd2807c7804e08c1d49479c0ff82e47 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-c1b6ca84f9bec1b1936cebb61f058924c3d7a5f6977e4cd76cf0544c4c7d8737.yml +openapi_spec_hash: 141bfa8430ddccfb5a37c4bd703d163b config_hash: bff282047fafdad771fb7ec685f56944 From 35e256a85572f24f11f89dbc452a7fa81640cef3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 00:28:32 +0000 Subject: [PATCH 09/11] feat(api): manual updates --- .stats.yml | 6 +- pkg/cmd/batch.go | 93 ++++++++++++++++++++----- pkg/cmd/batch_test.go | 78 ++++++++++++++------- pkg/cmd/cmd.go | 9 +++ pkg/cmd/person.go | 153 +++++++++++++++++++++++++++++++++++++++++ pkg/cmd/person_test.go | 92 +++++++++++++++++++++++++ 6 files changed, 383 insertions(+), 48 deletions(-) create mode 100644 pkg/cmd/person.go create mode 100644 pkg/cmd/person_test.go diff --git a/.stats.yml b/.stats.yml index b90c8da..ca57822 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-c1b6ca84f9bec1b1936cebb61f058924c3d7a5f6977e4cd76cf0544c4c7d8737.yml +configured_endpoints: 40 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-e2ba5381de3010ee53f27388aa6727ad567eb18e4b0b4eb1c4c66402bfea64cc.yml openapi_spec_hash: 141bfa8430ddccfb5a37c4bd703d163b -config_hash: bff282047fafdad771fb7ec685f56944 +config_hash: 920678668dd2da6f8966fbf1b8fde4e2 diff --git a/pkg/cmd/batch.go b/pkg/cmd/batch.go index 74c4a5b..1eff5c6 100644 --- a/pkg/cmd/batch.go +++ b/pkg/cmd/batch.go @@ -70,6 +70,22 @@ var batchList = cli.Command{ HideHelpCommand: true, } +var batchDelete = cli.Command{ + Name: "delete", + Usage: "Permanently delete a finished batch and its stored results. Active batches must\nsettle first.", + Suggest: true, + Flags: []cli.Flag{ + &requestflag.Flag[string]{ + Name: "batch-id", + Usage: "ID of the batch to retrieve or cancel.", + Required: true, + PathParam: "batch_id", + }, + }, + Action: handleBatchDelete, + HideHelpCommand: true, +} + var batchCancel = cli.Command{ Name: "cancel", Usage: "Stop a batch from starting new pages. In-progress pages finish, and unused\ncredits are refunded.", @@ -112,39 +128,36 @@ var batchGetResults = cli.Command{ HideHelpCommand: true, } -var batchSubmit = requestflag.WithInnerFlags(cli.Command{ +var batchSubmit = cli.Command{ Name: "submit", - Usage: "Retrieve and normalize a person profile from identifiers.", + Usage: "Scrape 25K URLs or crawl large websites asynchronously.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[map[string]any]{ - Name: "identifiers", - Usage: "Known identifiers for the person. At least one identifier is required.", + Name: "input", + Usage: "Choose a URL list or a site crawl.", Required: true, - BodyPath: "identifiers", + BodyPath: "input", }, &requestflag.Flag[[]string]{ Name: "tag", - Usage: "Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.", + Usage: "Tags stored on the batch. Filter the batch list by them later.", BodyPath: "tags", }, - &requestflag.Flag[int64]{ - Name: "timeout-ms", - Usage: "Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).", - BodyPath: "timeoutMS", + &requestflag.Flag[string]{ + Name: "webhook-url", + Usage: "URL notified when the batch finishes.", + BodyPath: "webhookUrl", + }, + &requestflag.Flag[string]{ + Name: "idempotency-key", + Usage: "Any string unique to this submission. Retries with the same key return the original batch.", + HeaderPath: "Idempotency-Key", }, }, Action: handleBatchSubmit, HideHelpCommand: true, -}, map[string][]requestflag.HasOuterFlag{ - "identifiers": { - &requestflag.InnerFlag[string]{ - Name: "identifiers.linkedin-url", - Usage: "LinkedIn profile URL, e.g. https://www.linkedin.com/in/yahia-bakour/.", - InnerField: "linkedinUrl", - }, - }, -}) +} func handleBatchRetrieve(ctx context.Context, cmd *cli.Command) error { client := contextdev.NewClient(getDefaultRequestOptions(cmd)...) @@ -229,6 +242,48 @@ func handleBatchList(ctx context.Context, cmd *cli.Command) error { }) } +func handleBatchDelete(ctx context.Context, cmd *cli.Command) error { + client := contextdev.NewClient(getDefaultRequestOptions(cmd)...) + unusedArgs := cmd.Args().Slice() + if !cmd.IsSet("batch-id") && len(unusedArgs) > 0 { + cmd.Set("batch-id", unusedArgs[0]) + unusedArgs = unusedArgs[1:] + } + if len(unusedArgs) > 0 { + return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs) + } + + options, err := flagOptions( + cmd, + apiquery.NestedQueryFormatBrackets, + apiquery.ArrayQueryFormatComma, + EmptyBody, + false, + ) + if err != nil { + return err + } + + var res []byte + options = append(options, option.WithResponseBodyInto(&res)) + _, err = client.Batch.Delete(ctx, cmd.Value("batch-id").(string), options...) + if err != nil { + return err + } + + obj := gjson.ParseBytes(res) + format := cmd.Root().String("format") + explicitFormat := cmd.Root().IsSet("format") + transform := cmd.Root().String("transform") + return ShowJSON(obj, ShowJSONOpts{ + ExplicitFormat: explicitFormat, + Format: format, + RawOutput: cmd.Root().Bool("raw-output"), + Title: "batch delete", + Transform: transform, + }) +} + func handleBatchCancel(ctx context.Context, cmd *cli.Command) error { client := contextdev.NewClient(getDefaultRequestOptions(cmd)...) unusedArgs := cmd.Args().Slice() diff --git a/pkg/cmd/batch_test.go b/pkg/cmd/batch_test.go index a14073e..123f80d 100644 --- a/pkg/cmd/batch_test.go +++ b/pkg/cmd/batch_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/context-dot-dev/context-dev-cli/internal/mocktest" - "github.com/context-dot-dev/context-dev-cli/internal/requestflag" ) func TestBatchRetrieve(t *testing.T) { @@ -38,6 +37,18 @@ func TestBatchList(t *testing.T) { }) } +func TestBatchDelete(t *testing.T) { + t.Skip("Mock server tests are disabled") + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, + "--api-key", "string", + "batch", "delete", + "--batch-id", "batch_9f2c8a", + ) + }) +} + func TestBatchCancel(t *testing.T) { t.Skip("Mock server tests are disabled") t.Run("regular flags", func(t *testing.T) { @@ -71,42 +82,57 @@ func TestBatchSubmit(t *testing.T) { t, "--api-key", "string", "batch", "submit", - "--identifiers", "{linkedinUrl: https://www.linkedin.com/in/yahia-bakour/}", - "--tag", "production", - "--tag", "team-alpha", - "--timeout-ms", "1000", - ) - }) - - t.Run("inner flags", func(t *testing.T) { - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(batchSubmit) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "--api-key", "string", - "batch", "submit", - "--identifiers.linkedin-url", "https://www.linkedin.com/in/yahia-bakour/", - "--tag", "production", - "--tag", "team-alpha", - "--timeout-ms", "1000", + "--input", "{data: {format: markdown, urls: [{url: https://example.com/products/anvil, itemId: sku-1, meta: {category: bar}}, {url: https://example.com/products/hammer, itemId: sku-2, meta: {foo: bar}}], options: {country: de, excludeSelectors: [x], includeImages: true, includeLinks: true, includeSelectors: [x], maxAgeMs: 0, pdf: {end: 1, ocr: 'true', shouldParse: 'true', start: 1}, settleAnimations: true, shortenBase64Images: true, useMainContentOnly: true, waitForMs: 0}}, mode: scrape}", + "--tag", "docs", + "--tag", "competitor", + "--webhook-url", "webhookUrl", + "--idempotency-key", "Idempotency-Key", ) }) t.Run("piping data", func(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("" + - "identifiers:\n" + - " linkedinUrl: https://www.linkedin.com/in/yahia-bakour/\n" + + "input:\n" + + " data:\n" + + " format: markdown\n" + + " urls:\n" + + " - url: https://example.com/products/anvil\n" + + " itemId: sku-1\n" + + " meta:\n" + + " category: bar\n" + + " - url: https://example.com/products/hammer\n" + + " itemId: sku-2\n" + + " meta:\n" + + " foo: bar\n" + + " options:\n" + + " country: de\n" + + " excludeSelectors:\n" + + " - x\n" + + " includeImages: true\n" + + " includeLinks: true\n" + + " includeSelectors:\n" + + " - x\n" + + " maxAgeMs: 0\n" + + " pdf:\n" + + " end: 1\n" + + " ocr: 'true'\n" + + " shouldParse: 'true'\n" + + " start: 1\n" + + " settleAnimations: true\n" + + " shortenBase64Images: true\n" + + " useMainContentOnly: true\n" + + " waitForMs: 0\n" + + " mode: scrape\n" + "tags:\n" + - " - production\n" + - " - team-alpha\n" + - "timeoutMS: 1000\n") + " - docs\n" + + " - competitor\n" + + "webhookUrl: webhookUrl\n") mocktest.TestRunMockTestWithPipeAndFlags( t, pipeData, "--api-key", "string", "batch", "submit", + "--idempotency-key", "Idempotency-Key", ) }) } diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 4db4f54..c2f399f 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -173,11 +173,20 @@ func init() { Commands: []*cli.Command{ &batchRetrieve, &batchList, + &batchDelete, &batchCancel, &batchGetResults, &batchSubmit, }, }, + { + Name: "people", + Category: "API RESOURCE", + Suggest: true, + Commands: []*cli.Command{ + &peopleEnrich, + }, + }, { Name: "@manpages", Usage: "Generate documentation for 'man'", diff --git a/pkg/cmd/person.go b/pkg/cmd/person.go new file mode 100644 index 0000000..a677477 --- /dev/null +++ b/pkg/cmd/person.go @@ -0,0 +1,153 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package cmd + +import ( + "context" + "fmt" + + "github.com/context-dot-dev/context-dev-cli/internal/apiquery" + "github.com/context-dot-dev/context-dev-cli/internal/requestflag" + "github.com/context-dot-dev/context-go-sdk/v2" + "github.com/context-dot-dev/context-go-sdk/v2/option" + "github.com/tidwall/gjson" + "github.com/urfave/cli/v3" +) + +var peopleEnrich = requestflag.WithInnerFlags(cli.Command{ + Name: "enrich", + Usage: "Finds and normalizes the best available person candidate from additive identity\nclues, then assigns an identity match score from 0 to 100. Available on Pro and\nScale plans. Successful requests cost 20 credits. Disposable and free email\naddresses (like gmail.com, yahoo.com) will throw a 422 error.", + Suggest: true, + Flags: []cli.Flag{ + &requestflag.Flag[map[string]any]{ + Name: "company", + BodyPath: "company", + }, + &requestflag.Flag[[]map[string]any]{ + Name: "education", + BodyPath: "education", + }, + &requestflag.Flag[string]{ + Name: "email", + BodyPath: "email", + }, + &requestflag.Flag[map[string]any]{ + Name: "location", + BodyPath: "location", + }, + &requestflag.Flag[map[string]any]{ + Name: "name", + BodyPath: "name", + }, + &requestflag.Flag[[]string]{ + Name: "social-url", + BodyPath: "social_urls", + }, + &requestflag.Flag[[]string]{ + Name: "tag", + Usage: "Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.", + BodyPath: "tags", + }, + &requestflag.Flag[int64]{ + Name: "timeout-ms", + Usage: "Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).", + BodyPath: "timeoutMS", + }, + }, + Action: handlePeopleEnrich, + HideHelpCommand: true, +}, map[string][]requestflag.HasOuterFlag{ + "company": { + &requestflag.InnerFlag[string]{ + Name: "company.domain", + InnerField: "domain", + }, + &requestflag.InnerFlag[string]{ + Name: "company.name", + InnerField: "name", + }, + }, + "education": { + &requestflag.InnerFlag[string]{ + Name: "education.degree", + InnerField: "degree", + }, + &requestflag.InnerFlag[string]{ + Name: "education.field-of-study", + InnerField: "field_of_study", + }, + &requestflag.InnerFlag[int64]{ + Name: "education.graduation-year", + InnerField: "graduation_year", + }, + &requestflag.InnerFlag[map[string]any]{ + Name: "education.institution", + InnerField: "institution", + }, + }, + "location": { + &requestflag.InnerFlag[string]{ + Name: "location.city", + InnerField: "city", + }, + &requestflag.InnerFlag[string]{ + Name: "location.country", + InnerField: "country", + }, + &requestflag.InnerFlag[string]{ + Name: "location.region", + InnerField: "region", + }, + }, + "name": { + &requestflag.InnerFlag[string]{ + Name: "name.first", + InnerField: "first", + }, + &requestflag.InnerFlag[string]{ + Name: "name.last", + InnerField: "last", + }, + }, +}) + +func handlePeopleEnrich(ctx context.Context, cmd *cli.Command) error { + client := contextdev.NewClient(getDefaultRequestOptions(cmd)...) + unusedArgs := cmd.Args().Slice() + + if len(unusedArgs) > 0 { + return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs) + } + + options, err := flagOptions( + cmd, + apiquery.NestedQueryFormatBrackets, + apiquery.ArrayQueryFormatComma, + ApplicationJSON, + false, + ) + if err != nil { + return err + } + + params := contextdev.PersonEnrichParams{} + + var res []byte + options = append(options, option.WithResponseBodyInto(&res)) + _, err = client.People.Enrich(ctx, params, options...) + if err != nil { + return err + } + + obj := gjson.ParseBytes(res) + format := cmd.Root().String("format") + explicitFormat := cmd.Root().IsSet("format") + transform := cmd.Root().String("transform") + return ShowJSON(obj, ShowJSONOpts{ + ExplicitFormat: explicitFormat, + Format: format, + RawOutput: cmd.Root().Bool("raw-output"), + Title: "people enrich", + Transform: transform, + }) +} diff --git a/pkg/cmd/person_test.go b/pkg/cmd/person_test.go new file mode 100644 index 0000000..2a1a4b1 --- /dev/null +++ b/pkg/cmd/person_test.go @@ -0,0 +1,92 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package cmd + +import ( + "testing" + + "github.com/context-dot-dev/context-dev-cli/internal/mocktest" + "github.com/context-dot-dev/context-dev-cli/internal/requestflag" +) + +func TestPeopleEnrich(t *testing.T) { + t.Skip("Mock server tests are disabled") + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, + "--api-key", "string", + "people", "enrich", + "--company", "{domain: analyticalengines.example, name: Analytical Engines}", + "--education", "{degree: x, field_of_study: x, graduation_year: 1900, institution: {domain: x, name: x}}", + "--email", "dev@stainless.com", + "--location", "{city: x, country: x, region: x}", + "--name", "{first: Ada, last: Lovelace}", + "--social-url", "https://www.linkedin.com/in/ada-lovelace/", + "--tag", "production", + "--tag", "team-alpha", + "--timeout-ms", "1000", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(peopleEnrich) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, + "--api-key", "string", + "people", "enrich", + "--company.domain", "analyticalengines.example", + "--company.name", "Analytical Engines", + "--education.degree", "x", + "--education.field-of-study", "x", + "--education.graduation-year", "1900", + "--education.institution", "{domain: x, name: x}", + "--email", "dev@stainless.com", + "--location.city", "x", + "--location.country", "x", + "--location.region", "x", + "--name.first", "Ada", + "--name.last", "Lovelace", + "--social-url", "https://www.linkedin.com/in/ada-lovelace/", + "--tag", "production", + "--tag", "team-alpha", + "--timeout-ms", "1000", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "company:\n" + + " domain: analyticalengines.example\n" + + " name: Analytical Engines\n" + + "education:\n" + + " - degree: x\n" + + " field_of_study: x\n" + + " graduation_year: 1900\n" + + " institution:\n" + + " domain: x\n" + + " name: x\n" + + "email: dev@stainless.com\n" + + "location:\n" + + " city: x\n" + + " country: x\n" + + " region: x\n" + + "name:\n" + + " first: Ada\n" + + " last: Lovelace\n" + + "social_urls:\n" + + " - https://www.linkedin.com/in/ada-lovelace/\n" + + "tags:\n" + + " - production\n" + + " - team-alpha\n" + + "timeoutMS: 1000\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, + "--api-key", "string", + "people", "enrich", + ) + }) +} From e21a8ff46d495a59b9c751965bb9d980a0765c78 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 01:03:17 +0000 Subject: [PATCH 10/11] feat(api): api update --- .stats.yml | 4 ++-- pkg/cmd/person.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index ca57822..97db86d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 40 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-e2ba5381de3010ee53f27388aa6727ad567eb18e4b0b4eb1c4c66402bfea64cc.yml -openapi_spec_hash: 141bfa8430ddccfb5a37c4bd703d163b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-a0dda03bbb600917cfb9add468cc4c8c84351a8dbbf61644dbc353263ca1748f.yml +openapi_spec_hash: c24264f32a46d9317aac5af9d6a396f7 config_hash: 920678668dd2da6f8966fbf1b8fde4e2 diff --git a/pkg/cmd/person.go b/pkg/cmd/person.go index a677477..efc6e30 100644 --- a/pkg/cmd/person.go +++ b/pkg/cmd/person.go @@ -16,7 +16,7 @@ import ( var peopleEnrich = requestflag.WithInnerFlags(cli.Command{ Name: "enrich", - Usage: "Finds and normalizes the best available person candidate from additive identity\nclues, then assigns an identity match score from 0 to 100. Available on Pro and\nScale plans. Successful requests cost 20 credits. Disposable and free email\naddresses (like gmail.com, yahoo.com) will throw a 422 error.", + Usage: "Finds and normalizes the best available person candidate from additive identity\nclues, then assigns an identity match score from 0 to 100. Available on all paid\nplans. Successful requests cost 20 credits. Disposable and free email addresses\n(like gmail.com, yahoo.com) will throw a 422 error.", Suggest: true, Flags: []cli.Flag{ &requestflag.Flag[map[string]any]{ From 943665e1d88777308a09ac2d0e47782b5ed52351 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 01:03:39 +0000 Subject: [PATCH 11/11] release: 1.5.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 14 ++++++++++++++ pkg/cmd/version.go | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3e9af1b..fbd9082 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.4.0" + ".": "1.5.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8156589..89cdc76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 1.5.0 (2026-08-07) + +Full Changelog: [v1.4.0...v1.5.0](https://github.com/context-dot-dev/context-dev-cli/compare/v1.4.0...v1.5.0) + +### Features + +* **api:** api update ([e21a8ff](https://github.com/context-dot-dev/context-dev-cli/commit/e21a8ff46d495a59b9c751965bb9d980a0765c78)) +* **api:** api update ([48a68cb](https://github.com/context-dot-dev/context-dev-cli/commit/48a68cb9ad422157ee55deef66773a161e320f44)) +* **api:** api update ([ad50292](https://github.com/context-dot-dev/context-dev-cli/commit/ad502925051676385440177ba5a4113631ff2dfa)) +* **api:** api update ([5650e87](https://github.com/context-dot-dev/context-dev-cli/commit/5650e87248bd4d1dabd6027007f510650684d511)) +* **api:** api update ([4ca42b8](https://github.com/context-dot-dev/context-dev-cli/commit/4ca42b8b8bdbe6750a50db1bc39b4ff098346f65)) +* **api:** api update ([92be0b6](https://github.com/context-dot-dev/context-dev-cli/commit/92be0b69f74d40bddb2748939d27c5b9f2660f46)) +* **api:** manual updates ([35e256a](https://github.com/context-dot-dev/context-dev-cli/commit/35e256a85572f24f11f89dbc452a7fa81640cef3)) + ## 1.4.0 (2026-08-05) Full Changelog: [v1.3.0...v1.4.0](https://github.com/context-dot-dev/context-dev-cli/compare/v1.3.0...v1.4.0) diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index a2e6c7d..cf77cd0 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "1.4.0" // x-release-please-version +const Version = "1.5.0" // x-release-please-version