scaledthought 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +530 -24
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -54,6 +54,7 @@ npx -y scaledthought@0.3 chat -m <id> "Reply with OK" # one real completion (an
54
54
  npx -y scaledthought@0.3 mcp # `claude mcp add …` command + JSON config
55
55
  npx -y scaledthought@0.3 account # plan, region, spend, owner_email
56
56
  npx -y scaledthought@0.3 account email set <address> # your human's email owns the account once they confirm
57
+ npx -y scaledthought@0.3 account rename "<name>" # the account's name on the dashboard ("" = the default)
57
58
  npx -y scaledthought@0.3 account ad-measurement off # opt out of ad measurement
58
59
  ```
59
60
 
package/dist/index.js CHANGED
@@ -1,4 +1,32 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+
17
+ // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/iso.js
18
+ var exports_iso = {};
19
+ __export(exports_iso, {
20
+ ZodISODate: () => ZodISODate,
21
+ ZodISODateTime: () => ZodISODateTime,
22
+ ZodISODuration: () => ZodISODuration,
23
+ ZodISOTime: () => ZodISOTime,
24
+ date: () => date2,
25
+ datetime: () => datetime2,
26
+ duration: () => duration2,
27
+ time: () => time2
28
+ });
29
+
2
30
  // ../../node_modules/.pnpm/citty@0.2.2/node_modules/citty/dist/_chunks/libs/scule.mjs
3
31
  var NUMBER_CHAR_RE = /\d/;
4
32
  var STR_SPLITTERS = [
@@ -553,7 +581,7 @@ import { join } from "node:path";
553
581
  // package.json
554
582
  var package_default = {
555
583
  name: "scaledthought",
556
- version: "0.3.3",
584
+ version: "0.3.4",
557
585
  description: "OpenAI-compatible inference for open-weight models, set up by your coding agent. Prepaid, pay per token, no subscription. US live; Canada coming soon.",
558
586
  license: "MIT",
559
587
  keywords: [
@@ -6825,6 +6853,19 @@ function refine(fn, _params = {}) {
6825
6853
  function superRefine(fn, params) {
6826
6854
  return _superRefine(fn, params);
6827
6855
  }
6856
+ // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/iso.js
6857
+ function datetime2(params) {
6858
+ return _isoDateTime(ZodISODateTime, params);
6859
+ }
6860
+ function date2(params) {
6861
+ return _isoDate(ZodISODate, params);
6862
+ }
6863
+ function time2(params) {
6864
+ return _isoTime(ZodISOTime, params);
6865
+ }
6866
+ function duration2(params) {
6867
+ return _isoDuration(ZodISODuration, params);
6868
+ }
6828
6869
  // ../../packages/growth/src/codes.ts
6829
6870
  var CODE_RE = /^[a-z0-9]{1,3}(-[a-z0-9]{1,12}){1,2}$/;
6830
6871
  function normalizeCode(raw) {
@@ -6847,6 +6888,7 @@ var CHANNELS = [
6847
6888
  "organic"
6848
6889
  ];
6849
6890
  var Channel = _enum(CHANNELS);
6891
+ var SITE_ORIGIN = "https://scaledthought.com";
6850
6892
 
6851
6893
  // ../../packages/growth/src/ad-click.ts
6852
6894
  var AD_CLICK_PLATFORMS = ["google", "reddit", "x", "microsoft"];
@@ -7972,6 +8014,171 @@ var AD_WRITE_CREDENTIAL_ENV = {
7972
8014
  microsoft: "AD_WRITE_MICROSOFT_CREDENTIALS"
7973
8015
  };
7974
8016
  var AD_WRITE_CREDENTIAL_ENV_NAMES = Object.values(AD_WRITE_CREDENTIAL_ENV);
8017
+ // ../../packages/growth/src/campaign-google.ts
8018
+ var CAMPAIGN_CHANNELS = ["search", "display"];
8019
+ var GOOGLE_ASSET_LIMITS = {
8020
+ callout: 25,
8021
+ callouts: 20,
8022
+ sitelinkText: 25,
8023
+ sitelinkLine: 35,
8024
+ sitelinks: 20,
8025
+ snippetValue: 25,
8026
+ snippetValuesMin: 3,
8027
+ snippetValuesMax: 10,
8028
+ snippets: 10,
8029
+ businessName: 25,
8030
+ images: 20,
8031
+ customAudiences: 10,
8032
+ audienceMembers: 200,
8033
+ audienceKeyword: 80,
8034
+ exclusions: 5000
8035
+ };
8036
+ var CENT_MICROS = 1e4;
8037
+ var MAX_BID_MICROS = 1e8;
8038
+ var Line = (max, what) => string2().trim().min(1).refine((s) => [...s].length <= max, `${what}: at most ${max} characters`);
8039
+ var BidMicros = number2().int().positive().max(MAX_BID_MICROS).refine((n) => n % CENT_MICROS === 0, "whole cents (a multiple of 10,000 micros)");
8040
+ var CampaignBidding = discriminatedUnion("strategy", [
8041
+ object({ strategy: literal("maximize_clicks"), max_cpc_micros: BidMicros.nullable().default(null) }).strict(),
8042
+ object({ strategy: literal("maximize_conversions"), target_cpa_micros: BidMicros.nullable().default(null) }).strict(),
8043
+ object({ strategy: literal("manual_cpc"), default_cpc_micros: BidMicros }).strict()
8044
+ ]);
8045
+ var DeviceAdjustment = number2().int().refine((n) => n === -100 || n >= -90 && n <= 900, "−100 (excluded) or −90 … +900 percent");
8046
+ var CampaignDevices = object({
8047
+ desktop: DeviceAdjustment.default(0),
8048
+ mobile: DeviceAdjustment.default(0),
8049
+ tablet: DeviceAdjustment.default(0),
8050
+ tv: DeviceAdjustment.default(0)
8051
+ }).strict();
8052
+ var noDeviceAdjustments = () => ({ desktop: 0, mobile: 0, tablet: 0, tv: 0 });
8053
+ var SiteUrl = string2().trim().max(200).refine((s) => {
8054
+ if (!s.startsWith(`${SITE_ORIGIN}/`) && s !== SITE_ORIGIN)
8055
+ return false;
8056
+ try {
8057
+ const u = new URL(s);
8058
+ return u.origin === SITE_ORIGIN && !u.search && !u.hash && !u.username && !u.password;
8059
+ } catch {
8060
+ return false;
8061
+ }
8062
+ }, `a page on ${SITE_ORIGIN} (https, no query string or fragment)`);
8063
+ var Sitelink = object({
8064
+ text: Line(GOOGLE_ASSET_LIMITS.sitelinkText, "sitelink text"),
8065
+ line1: Line(GOOGLE_ASSET_LIMITS.sitelinkLine, "sitelink line").nullable().default(null),
8066
+ line2: Line(GOOGLE_ASSET_LIMITS.sitelinkLine, "sitelink line").nullable().default(null),
8067
+ final_url: SiteUrl
8068
+ }).strict().refine((s) => s.line1 == null === (s.line2 == null), "sitelink lines: both or neither");
8069
+ var SNIPPET_HEADERS = [
8070
+ "Amenities",
8071
+ "Brands",
8072
+ "Courses",
8073
+ "Degree programs",
8074
+ "Destinations",
8075
+ "Featured hotels",
8076
+ "Insurance coverage",
8077
+ "Models",
8078
+ "Neighborhoods",
8079
+ "Service catalog",
8080
+ "Shows",
8081
+ "Styles",
8082
+ "Types"
8083
+ ];
8084
+ var StructuredSnippet = object({
8085
+ header: _enum(SNIPPET_HEADERS),
8086
+ values: array(Line(GOOGLE_ASSET_LIMITS.snippetValue, "snippet value")).min(GOOGLE_ASSET_LIMITS.snippetValuesMin).max(GOOGLE_ASSET_LIMITS.snippetValuesMax)
8087
+ }).strict();
8088
+ var AssetId = string2().regex(/^\d{1,20}$/, "a Google Ads asset id");
8089
+ var emptyAssets = () => ({
8090
+ callouts: [],
8091
+ sitelinks: [],
8092
+ structured_snippets: [],
8093
+ business_name: null,
8094
+ logo_asset_id: null,
8095
+ image_asset_ids: []
8096
+ });
8097
+ var CampaignAssets = object({
8098
+ callouts: array(Line(GOOGLE_ASSET_LIMITS.callout, "callout")).max(GOOGLE_ASSET_LIMITS.callouts).default([]),
8099
+ sitelinks: array(Sitelink).max(GOOGLE_ASSET_LIMITS.sitelinks).default([]),
8100
+ structured_snippets: array(StructuredSnippet).max(GOOGLE_ASSET_LIMITS.snippets).default([]),
8101
+ business_name: Line(GOOGLE_ASSET_LIMITS.businessName, "business name").nullable().default(null),
8102
+ logo_asset_id: AssetId.nullable().default(null),
8103
+ image_asset_ids: array(AssetId).max(GOOGLE_ASSET_LIMITS.images).default([])
8104
+ }).strict();
8105
+ var CONTENT_LABELS = [
8106
+ "BELOW_THE_FOLD",
8107
+ "BRAND_SUITABILITY_CONTENT_FOR_FAMILIES",
8108
+ "BRAND_SUITABILITY_GAMES_FIGHTING",
8109
+ "BRAND_SUITABILITY_GAMES_MATURE",
8110
+ "BRAND_SUITABILITY_HEALTH_SENSITIVE",
8111
+ "BRAND_SUITABILITY_HEALTH_SOURCE_UNDETERMINED",
8112
+ "BRAND_SUITABILITY_NEWS_RECENT",
8113
+ "BRAND_SUITABILITY_NEWS_SENSITIVE",
8114
+ "BRAND_SUITABILITY_NEWS_SOURCE_NOT_FEATURED",
8115
+ "BRAND_SUITABILITY_POLITICS",
8116
+ "BRAND_SUITABILITY_RELIGION",
8117
+ "EMBEDDED_VIDEO",
8118
+ "JUVENILE",
8119
+ "LIVE_STREAMING_VIDEO",
8120
+ "PARKED_DOMAIN",
8121
+ "PROFANITY",
8122
+ "SEXUALLY_SUGGESTIVE",
8123
+ "SOCIAL_ISSUES",
8124
+ "TRAGEDY",
8125
+ "VIDEO",
8126
+ "VIDEO_NOT_YET_RATED",
8127
+ "VIDEO_RATING_DV_G",
8128
+ "VIDEO_RATING_DV_MA",
8129
+ "VIDEO_RATING_DV_PG",
8130
+ "VIDEO_RATING_DV_T"
8131
+ ];
8132
+ var Placement = string2().trim().min(1).max(2048);
8133
+ var AppCategory = string2().regex(/^\d{1,12}$/, "a mobile app category id, e.g. 60008");
8134
+ var uniq = (xs) => new Set(xs).size === xs.length;
8135
+ var CampaignExclusions = object({
8136
+ placements: array(Placement).max(GOOGLE_ASSET_LIMITS.exclusions).default([]),
8137
+ mobile_app_categories: array(AppCategory).max(GOOGLE_ASSET_LIMITS.exclusions).default([]),
8138
+ content_labels: array(_enum(CONTENT_LABELS)).max(CONTENT_LABELS.length).default([])
8139
+ }).strict().refine((e) => uniq(e.placements) && uniq(e.mobile_app_categories) && uniq(e.content_labels), "exclusions are listed once");
8140
+ var noExclusions = () => ({
8141
+ placements: [],
8142
+ mobile_app_categories: [],
8143
+ content_labels: []
8144
+ });
8145
+ var CUSTOM_AUDIENCE_TYPES = ["search", "auto"];
8146
+ var CustomAudience = object({
8147
+ name: string2().trim().min(1).max(255),
8148
+ type: _enum(CUSTOM_AUDIENCE_TYPES),
8149
+ keywords: array(Line(GOOGLE_ASSET_LIMITS.audienceKeyword, "audience keyword").refine((s) => s.split(/\s+/).length <= 10, "audience keyword: at most 10 words")).max(GOOGLE_ASSET_LIMITS.audienceMembers).default([]),
8150
+ urls: array(string2().trim().url().max(2048)).max(GOOGLE_ASSET_LIMITS.audienceMembers).default([])
8151
+ }).strict().refine((a) => a.keywords.length + a.urls.length > 0, "an audience has at least one keyword or URL").refine((a) => a.type === "auto" || a.urls.length === 0, "a search audience has keywords only").refine((a) => a.keywords.length + a.urls.length <= GOOGLE_ASSET_LIMITS.audienceMembers, "at most 200 members");
8152
+ var emptyDisplay = () => ({
8153
+ optimized_targeting: false,
8154
+ custom_audiences: [],
8155
+ exclusions: noExclusions()
8156
+ });
8157
+ var CampaignDisplay = object({
8158
+ optimized_targeting: boolean2().default(false),
8159
+ custom_audiences: array(CustomAudience).max(GOOGLE_ASSET_LIMITS.customAudiences).default([]),
8160
+ exclusions: CampaignExclusions.default(() => noExclusions())
8161
+ }).strict();
8162
+ var AdAccountExclusions = object({
8163
+ placements: array(Placement).max(GOOGLE_ASSET_LIMITS.exclusions).default([]),
8164
+ mobile_app_categories: array(AppCategory).max(GOOGLE_ASSET_LIMITS.exclusions).default([]),
8165
+ content_labels: array(_enum(CONTENT_LABELS)).max(CONTENT_LABELS.length).default([]),
8166
+ mobile_applications: array(string2().trim().min(1).max(255)).max(GOOGLE_ASSET_LIMITS.exclusions).default([]),
8167
+ youtube_channels: array(string2().trim().min(1).max(128)).max(GOOGLE_ASSET_LIMITS.exclusions).default([]),
8168
+ youtube_videos: array(string2().trim().min(1).max(64)).max(GOOGLE_ASSET_LIMITS.exclusions).default([])
8169
+ }).strict().refine((e) => uniq(e.placements) && uniq(e.mobile_app_categories) && uniq(e.content_labels) && uniq(e.mobile_applications) && uniq(e.youtube_channels) && uniq(e.youtube_videos), "exclusions are listed once");
8170
+ var GOOGLE_AD_ACCOUNT_RE = /^\d{3}-\d{3}-\d{4}$/;
8171
+ var GoogleAdAccountId = string2().regex(GOOGLE_AD_ACCOUNT_RE, "a Google Ads account id, 123-456-7890");
8172
+ var AdAccountSettings = object({
8173
+ exclusions: AdAccountExclusions.default(() => ({
8174
+ placements: [],
8175
+ mobile_app_categories: [],
8176
+ content_labels: [],
8177
+ mobile_applications: [],
8178
+ youtube_channels: [],
8179
+ youtube_videos: []
8180
+ }))
8181
+ }).strict();
7975
8182
  // ../../packages/growth/src/portfolio.ts
7976
8183
  var PORTFOLIO_LIMITS = {
7977
8184
  weeklyBudgetMicros: 1500000000,
@@ -8001,6 +8208,7 @@ var EXPERIMENT_METRICS = [
8001
8208
  "agent_fetches",
8002
8209
  "human_visits",
8003
8210
  "signups",
8211
+ "landing_signup_rate",
8004
8212
  "activation_rate",
8005
8213
  "paid_rate",
8006
8214
  "topup_request_rate",
@@ -8092,22 +8300,23 @@ var GOOGLE_AD_LIMITS = {
8092
8300
  negativeKeywords: 500
8093
8301
  };
8094
8302
  var CampaignId = string2().regex(CAMPAIGN_ID_RE, "a campaign id, gcm_<ulid>");
8095
- var Line = (max, what) => string2().trim().min(1).refine((s) => [...s].length <= max, `${what}: at most ${max} characters`);
8303
+ var Line2 = (max, what) => string2().trim().min(1).refine((s) => [...s].length <= max, `${what}: at most ${max} characters`);
8096
8304
  var Keyword = object({
8097
- text: Line(GOOGLE_AD_LIMITS.keyword, "keyword").refine((s) => s.split(/\s+/).length <= GOOGLE_AD_LIMITS.keywordWords, `keyword: at most ${GOOGLE_AD_LIMITS.keywordWords} words`),
8305
+ text: Line2(GOOGLE_AD_LIMITS.keyword, "keyword").refine((s) => s.split(/\s+/).length <= GOOGLE_AD_LIMITS.keywordWords, `keyword: at most ${GOOGLE_AD_LIMITS.keywordWords} words`),
8098
8306
  match: _enum(KEYWORD_MATCH_TYPES)
8099
8307
  }).strict();
8100
8308
  var SearchAd = object({
8101
- headlines: array(Line(GOOGLE_AD_LIMITS.headline, "headline")).min(GOOGLE_AD_LIMITS.headlinesMin).max(GOOGLE_AD_LIMITS.headlinesMax),
8102
- descriptions: array(Line(GOOGLE_AD_LIMITS.description, "description")).min(GOOGLE_AD_LIMITS.descriptionsMin).max(GOOGLE_AD_LIMITS.descriptionsMax),
8103
- path1: Line(GOOGLE_AD_LIMITS.path, "path").optional(),
8104
- path2: Line(GOOGLE_AD_LIMITS.path, "path").optional()
8309
+ headlines: array(Line2(GOOGLE_AD_LIMITS.headline, "headline")).min(GOOGLE_AD_LIMITS.headlinesMin).max(GOOGLE_AD_LIMITS.headlinesMax),
8310
+ descriptions: array(Line2(GOOGLE_AD_LIMITS.description, "description")).min(GOOGLE_AD_LIMITS.descriptionsMin).max(GOOGLE_AD_LIMITS.descriptionsMax),
8311
+ path1: Line2(GOOGLE_AD_LIMITS.path, "path").optional(),
8312
+ path2: Line2(GOOGLE_AD_LIMITS.path, "path").optional()
8105
8313
  }).strict().refine((a) => !a.path2 || a.path1, "path2 needs path1");
8106
8314
  var AdGroup2 = object({
8107
8315
  name: string2().trim().min(1).max(255),
8108
- keywords: array(Keyword).min(1).max(GOOGLE_AD_LIMITS.keywordsPerAdGroup),
8109
- ads: array(SearchAd).min(1).max(GOOGLE_AD_LIMITS.adsPerAdGroup),
8110
- negative_keywords: array(Keyword).max(GOOGLE_AD_LIMITS.negativeKeywords).default([])
8316
+ keywords: array(Keyword).max(GOOGLE_AD_LIMITS.keywordsPerAdGroup),
8317
+ ads: array(SearchAd).max(GOOGLE_AD_LIMITS.adsPerAdGroup),
8318
+ negative_keywords: array(Keyword).max(GOOGLE_AD_LIMITS.negativeKeywords).default([]),
8319
+ audiences: array(string2().trim().min(1).max(255)).max(10).default([])
8111
8320
  }).strict();
8112
8321
  var CampaignContent = object({
8113
8322
  ad_groups: array(AdGroup2).min(1).max(GOOGLE_AD_LIMITS.adGroups),
@@ -8134,7 +8343,12 @@ var CAMPAIGN_FIELD_SHAPE = {
8134
8343
  run_to: Day2,
8135
8344
  targeting: CampaignTargeting,
8136
8345
  content: CampaignContent,
8137
- notes: string2().trim().max(4000).nullable()
8346
+ notes: string2().trim().max(4000).nullable(),
8347
+ channel: _enum(CAMPAIGN_CHANNELS),
8348
+ bidding: CampaignBidding.nullable(),
8349
+ devices: CampaignDevices,
8350
+ assets: CampaignAssets,
8351
+ display: CampaignDisplay
8138
8352
  };
8139
8353
  var CampaignFields = object({
8140
8354
  ...CAMPAIGN_FIELD_SHAPE,
@@ -8142,7 +8356,12 @@ var CampaignFields = object({
8142
8356
  ad_account_id: CAMPAIGN_FIELD_SHAPE.ad_account_id.default(null),
8143
8357
  daily_budget_micros: CAMPAIGN_FIELD_SHAPE.daily_budget_micros.default(null),
8144
8358
  weekly_budget_micros: CAMPAIGN_FIELD_SHAPE.weekly_budget_micros.default(null),
8145
- notes: CAMPAIGN_FIELD_SHAPE.notes.default(null)
8359
+ notes: CAMPAIGN_FIELD_SHAPE.notes.default(null),
8360
+ channel: CAMPAIGN_FIELD_SHAPE.channel.default("search"),
8361
+ bidding: CAMPAIGN_FIELD_SHAPE.bidding.default(null),
8362
+ devices: CAMPAIGN_FIELD_SHAPE.devices.default(noDeviceAdjustments),
8363
+ assets: CAMPAIGN_FIELD_SHAPE.assets.default(emptyAssets),
8364
+ display: CAMPAIGN_FIELD_SHAPE.display.default(emptyDisplay)
8146
8365
  }).strict();
8147
8366
  var CampaignFieldsPatch = object(CAMPAIGN_FIELD_SHAPE).partial().strict();
8148
8367
  // ../../packages/growth/src/sinks/google.ts
@@ -8576,6 +8795,278 @@ var GoHit = object({
8576
8795
  }).strict();
8577
8796
  // ../../packages/growth/src/go-pages.ts
8578
8797
  var AD_CLICK_TOKEN_RE = /^[A-Za-z0-9_-]{16,2000}\.[A-Za-z0-9_-]{43}$/;
8798
+ // ../../packages/growth/src/google-ads/reconcile.ts
8799
+ var MANAGED_ASSET_TYPES = new Set(["CALLOUT", "SITELINK", "STRUCTURED_SNIPPET"]);
8800
+
8801
+ // ../../packages/growth/src/google-ads/client.ts
8802
+ var MutateResponse2 = object({
8803
+ mutateOperationResponses: array(record(string2(), object({ resourceName: string2().optional() }).passthrough())).optional()
8804
+ });
8805
+ var AudienceResponse = object({ results: array(object({ resourceName: string2().optional() })).optional() });
8806
+ var Id4 = union([string2(), number2()]).transform(String);
8807
+ var Int = union([string2(), number2()]).optional().nullable().transform((v) => v == null || v === "" ? null : Number(v));
8808
+ var Str = string2().optional().nullable();
8809
+ var Bool = boolean2().optional().nullable();
8810
+ var loose = (shape) => object(shape).passthrough();
8811
+ var CampaignRow2 = loose({
8812
+ customer: loose({ currencyCode: Str, timeZone: Str }).optional(),
8813
+ campaign: loose({
8814
+ resourceName: string2(),
8815
+ id: Id4,
8816
+ name: string2().default(""),
8817
+ status: string2().default("UNKNOWN"),
8818
+ advertisingChannelType: string2().default("UNKNOWN"),
8819
+ biddingStrategyType: string2().default("UNKNOWN"),
8820
+ campaignBudget: Str,
8821
+ startDateTime: Str,
8822
+ endDateTime: Str,
8823
+ targetSpend: loose({ cpcBidCeilingMicros: Int }).optional(),
8824
+ maximizeConversions: loose({ targetCpaMicros: Int }).optional(),
8825
+ networkSettings: loose({
8826
+ targetGoogleSearch: Bool,
8827
+ targetSearchNetwork: Bool,
8828
+ targetContentNetwork: Bool
8829
+ }).optional(),
8830
+ geoTargetTypeSetting: loose({ positiveGeoTargetType: Str }).optional()
8831
+ }),
8832
+ campaignBudget: loose({
8833
+ resourceName: Str,
8834
+ amountMicros: Int,
8835
+ explicitlyShared: Bool,
8836
+ period: Str
8837
+ }).optional()
8838
+ });
8839
+ var Keyword2 = loose({ text: string2(), matchType: string2() }).optional();
8840
+ var CampaignCriterionRow = loose({
8841
+ campaignCriterion: loose({
8842
+ resourceName: string2(),
8843
+ type: string2().default("UNKNOWN"),
8844
+ status: Str,
8845
+ negative: Bool,
8846
+ bidModifier: number2().optional().nullable(),
8847
+ location: loose({ geoTargetConstant: string2() }).optional(),
8848
+ language: loose({ languageConstant: string2() }).optional(),
8849
+ device: loose({ type: string2() }).optional(),
8850
+ keyword: Keyword2,
8851
+ placement: loose({ url: string2() }).optional(),
8852
+ mobileAppCategory: loose({ mobileAppCategoryConstant: string2() }).optional(),
8853
+ contentLabel: loose({ type: string2() }).optional(),
8854
+ customAudience: loose({ customAudience: string2() }).optional()
8855
+ })
8856
+ });
8857
+ var AdGroupRow2 = loose({
8858
+ adGroup: loose({
8859
+ resourceName: string2(),
8860
+ id: Id4,
8861
+ name: string2().default(""),
8862
+ status: string2().default("UNKNOWN"),
8863
+ type: string2().default("UNKNOWN"),
8864
+ cpcBidMicros: Int,
8865
+ optimizedTargetingEnabled: Bool
8866
+ })
8867
+ });
8868
+ var AdGroupCriterionRow = loose({
8869
+ adGroup: loose({ resourceName: string2() }),
8870
+ adGroupCriterion: loose({
8871
+ resourceName: string2(),
8872
+ type: string2().default("UNKNOWN"),
8873
+ status: Str,
8874
+ negative: Bool,
8875
+ keyword: Keyword2,
8876
+ customAudience: loose({ customAudience: string2() }).optional()
8877
+ })
8878
+ });
8879
+ var AdText = array(loose({ text: string2().default("") })).optional();
8880
+ var AdRow = loose({
8881
+ adGroup: loose({ resourceName: string2() }),
8882
+ adGroupAd: loose({
8883
+ resourceName: string2(),
8884
+ status: string2().default("UNKNOWN"),
8885
+ ad: loose({
8886
+ type: string2().default("UNKNOWN"),
8887
+ finalUrls: array(string2()).optional(),
8888
+ responsiveSearchAd: loose({ headlines: AdText, descriptions: AdText, path1: Str, path2: Str }).optional()
8889
+ })
8890
+ })
8891
+ });
8892
+ var CampaignAssetRow = loose({
8893
+ campaignAsset: loose({ resourceName: string2(), status: string2().default("UNKNOWN"), fieldType: string2() }),
8894
+ asset: loose({
8895
+ resourceName: string2(),
8896
+ finalUrls: array(string2()).optional(),
8897
+ calloutAsset: loose({ calloutText: string2() }).optional(),
8898
+ sitelinkAsset: loose({ linkText: string2(), description1: Str, description2: Str }).optional(),
8899
+ structuredSnippetAsset: loose({ header: string2(), values: array(string2()).default([]) }).optional()
8900
+ })
8901
+ });
8902
+ var AudienceRow = loose({
8903
+ customAudience: loose({
8904
+ resourceName: string2(),
8905
+ name: string2().default(""),
8906
+ type: string2().default("UNKNOWN"),
8907
+ status: Str,
8908
+ members: array(loose({
8909
+ memberType: string2().default("UNKNOWN"),
8910
+ keyword: Str,
8911
+ url: Str,
8912
+ app: Str,
8913
+ placeCategory: union([string2(), number2()]).optional().nullable()
8914
+ })).optional()
8915
+ })
8916
+ });
8917
+ var NegativeRow = loose({
8918
+ customerNegativeCriterion: loose({
8919
+ resourceName: string2(),
8920
+ type: string2().default("UNKNOWN"),
8921
+ placement: loose({ url: string2() }).optional(),
8922
+ mobileAppCategory: loose({ mobileAppCategoryConstant: string2() }).optional(),
8923
+ contentLabel: loose({ type: string2() }).optional(),
8924
+ mobileApplication: loose({ appId: string2() }).optional(),
8925
+ youtubeChannel: loose({ channelId: string2() }).optional(),
8926
+ youtubeVideo: loose({ videoId: string2() }).optional()
8927
+ })
8928
+ });
8929
+ var CurrencyRow = loose({ customer: loose({ currencyCode: Str, timeZone: Str }).optional() });
8930
+ var NEG_TYPES = new Set([
8931
+ "PLACEMENT",
8932
+ "MOBILE_APP_CATEGORY",
8933
+ "CONTENT_LABEL",
8934
+ "MOBILE_APPLICATION",
8935
+ "YOUTUBE_CHANNEL",
8936
+ "YOUTUBE_VIDEO"
8937
+ ]);
8938
+ // ../../packages/growth/src/insights-core.ts
8939
+ var VISITOR_COOKIE_MAX_AGE_S = 395 * 24 * 3600;
8940
+ var SESSION_IDLE_S = 30 * 60;
8941
+ var INSIGHTS_ID_RE = /^[A-Za-z0-9_-]{22}$/;
8942
+ var INSIGHTS_MAX_EVENTS_PER_BATCH = 50;
8943
+ var REPLAY_CHUNK_MAX_BYTES = 400000;
8944
+ var REPLAY_MAX_CHUNKS_PER_SEGMENT = 360;
8945
+
8946
+ // ../../packages/growth/src/insights.ts
8947
+ var TRACKED_COUNTRIES = ["US", "CA"];
8948
+ var Ms = number2().int().nonnegative();
8949
+ var Path = string2().regex(/^\/[^\s?#]{0,199}$/);
8950
+ var Selector = string2().min(1).max(200);
8951
+ var Px = number2().int().min(0).max(1e5);
8952
+ var Tag = string2().regex(/^[A-Za-z0-9._-]{1,60}$/).optional();
8953
+ var Variant = string2().regex(/^[a-z0-9][a-z0-9-]{0,39}$/).optional();
8954
+ var Base = { t: Ms, p: Path };
8955
+ var Pointer = {
8956
+ ...Base,
8957
+ s: Selector,
8958
+ x: number2().int().min(0).max(1e4),
8959
+ y: Px,
8960
+ vw: Px,
8961
+ vh: Px,
8962
+ dh: Px
8963
+ };
8964
+ var BrowserEvent = discriminatedUnion("k", [
8965
+ object({
8966
+ k: literal("pageview"),
8967
+ ...Base,
8968
+ r: string2().regex(/^[a-z0-9.-]{1,100}$/).optional(),
8969
+ q: object({ source: Tag, utm_source: Tag, utm_medium: Tag, utm_campaign: Tag }).strict().optional(),
8970
+ vw: Px,
8971
+ vh: Px,
8972
+ v: Variant
8973
+ }).strict(),
8974
+ object({ k: literal("click"), ...Pointer }).strict(),
8975
+ object({ k: literal("rage_click"), ...Pointer }).strict(),
8976
+ object({ k: literal("dead_click"), ...Pointer }).strict(),
8977
+ object({ k: literal("scroll"), ...Base, d: number2().int().min(0).max(100), dh: Px }).strict(),
8978
+ object({ k: literal("leave"), ...Base, ms: number2().int().min(0).max(86400000) }).strict()
8979
+ ]);
8980
+ var INSIGHTS_EVENT_KINDS = ["pageview", "click", "rage_click", "dead_click", "scroll", "leave"];
8981
+ var BrowserBatch = object({
8982
+ v: literal(1),
8983
+ h: _enum(["site", "dashboard"]),
8984
+ e: array(BrowserEvent).min(1).max(INSIGHTS_MAX_EVENTS_PER_BATCH)
8985
+ }).strict();
8986
+ var DEVICE_CLASSES = ["desktop", "mobile", "tablet"];
8987
+ var BROWSER_FAMILIES = ["chrome", "safari", "firefox", "edge", "opera", "samsung", "other"];
8988
+ var InsightsEvent = object({
8989
+ kind: _enum(INSIGHTS_EVENT_KINDS),
8990
+ at: exports_iso.datetime(),
8991
+ path: Path,
8992
+ selector: Selector.optional(),
8993
+ x: number2().int().min(0).max(1e4).optional(),
8994
+ y: Px.optional(),
8995
+ vw: Px.optional(),
8996
+ vh: Px.optional(),
8997
+ doc_h: Px.optional(),
8998
+ scroll_pct: number2().int().min(0).max(100).optional(),
8999
+ duration_ms: number2().int().min(0).max(86400000).optional(),
9000
+ source: string2().max(110).optional(),
9001
+ code: string2().regex(CODE_RE).optional(),
9002
+ variant: Variant
9003
+ }).strict();
9004
+ var InsightsHit = object({
9005
+ insights: object({
9006
+ visitor: string2().regex(INSIGHTS_ID_RE),
9007
+ session: string2().regex(INSIGHTS_ID_RE),
9008
+ surface: _enum(["site", "dashboard"]),
9009
+ country: _enum(TRACKED_COUNTRIES),
9010
+ device: _enum(DEVICE_CLASSES),
9011
+ browser: _enum(BROWSER_FAMILIES),
9012
+ ip: string2().regex(/^[0-9a-fA-F:.]{2,45}$/).optional(),
9013
+ events: array(InsightsEvent).min(1).max(INSIGHTS_MAX_EVENTS_PER_BATCH)
9014
+ }).strict()
9015
+ }).strict();
9016
+ var InsightsForgetHit = object({ insights_forget: object({ visitor: string2().regex(INSIGHTS_ID_RE) }).strict() }).strict();
9017
+ var ReplayHit = object({
9018
+ replay: object({
9019
+ visitor: string2().regex(INSIGHTS_ID_RE),
9020
+ session: string2().regex(INSIGHTS_ID_RE),
9021
+ segment: string2().regex(INSIGHTS_ID_RE),
9022
+ seq: number2().int().min(0).max(REPLAY_MAX_CHUNKS_PER_SEGMENT - 1),
9023
+ surface: _enum(["site", "dashboard"]),
9024
+ country: _enum(TRACKED_COUNTRIES),
9025
+ device: _enum(DEVICE_CLASSES),
9026
+ browser: _enum(BROWSER_FAMILIES),
9027
+ path: Path,
9028
+ data: string2().regex(/^[A-Za-z0-9+/]+={0,2}$/).max(Math.ceil(REPLAY_CHUNK_MAX_BYTES / 3) * 4)
9029
+ }).strict()
9030
+ }).strict();
9031
+ // ../../packages/growth/src/landing.ts
9032
+ var LANDING_VARIANT_ID_RE = /^glv_[0-9A-HJKMNP-TV-Z]{26}$/;
9033
+ var LandingVariantId = string2().regex(LANDING_VARIANT_ID_RE, "a landing variant id, glv_<ulid>");
9034
+ var LANDING_CTAS = ["agent_prompt", "cli_command", "browser_signup"];
9035
+ var LANDING_SNIPPETS = ["curl", "openai_sdk"];
9036
+ var LANDING_MOBILE_ORDERS = ["browser_signup_first", "same_as_desktop"];
9037
+ var LANDING_LIMITS = { name: 80, headline: 90, subhead: 240, bullet: 120, bullets: 4, trust: 240 };
9038
+ var LANDING_WEIGHT_MAX = 1000;
9039
+ var UNSAFE_TEXT = /[<>`*_[\]{}|\\#~^]|:\/\/|www\.|[\u0000-\u001f\u007f-\u009f­​-‏‪-‮⁠-⁩]/i;
9040
+ var plain = (min, max) => string2().trim().min(min).max(max).refine((s) => !UNSAFE_TEXT.test(s), "plain text only: no markup, links, templates or control characters");
9041
+ var LANDING_MODEL_ID_RE = /^[a-z0-9]+(-[a-z0-9]+){0,8}$/;
9042
+ var LandingContent = object({
9043
+ headline: plain(8, LANDING_LIMITS.headline),
9044
+ subhead: plain(1, LANDING_LIMITS.subhead).nullable().default(null),
9045
+ bullets: array(plain(3, LANDING_LIMITS.bullet)).max(LANDING_LIMITS.bullets).default([]),
9046
+ primary_cta: _enum(LANDING_CTAS).default("agent_prompt"),
9047
+ mobile_cta_order: _enum(LANDING_MOBILE_ORDERS).default("browser_signup_first"),
9048
+ snippet: _enum(LANDING_SNIPPETS).nullable().default(null),
9049
+ price_model_id: string2().regex(LANDING_MODEL_ID_RE).max(64).nullable().default(null),
9050
+ trust_line: plain(1, LANDING_LIMITS.trust).nullable().default(null)
9051
+ }).strict();
9052
+ var NOT_USAGE = String.raw`(?![\s-]+(?:for|credits?|tokens?|tiers?|trials?|usage|plans?|access|calls?|requests?|inference|api|models?|allowance|minutes?|hours?|days?|weeks?|months?)\b)`;
9053
+ var SIGN_UP = "(?:sign(?:ing)?[- ]?up)";
9054
+ var SIGNUP_FREE_RE = new RegExp([
9055
+ String.raw`\b${SIGN_UP}\s+(?:for\s+)?free\b${NOT_USAGE}`,
9056
+ String.raw`\bfree\s+to\s+(?:${SIGN_UP}|create\s+an\s+account)\b`,
9057
+ String.raw`\b(?:${SIGN_UP}|creating\s+an\s+account)\s+is\s+free\b${NOT_USAGE}`
9058
+ ].join("|"), "gi");
9059
+ var LandingServeVariant = object({
9060
+ code: string2().regex(CODE_RE),
9061
+ weight: number2().int().min(1).max(LANDING_WEIGHT_MAX),
9062
+ sha256: string2().regex(/^[0-9a-f]{64}$/),
9063
+ content: LandingContent
9064
+ }).strict();
9065
+ var LandingServe = object({
9066
+ code: string2().regex(CODE_RE),
9067
+ parent: string2().regex(CODE_RE).nullable(),
9068
+ variants: array(LandingServeVariant).max(20)
9069
+ }).strict();
8579
9070
  // ../../packages/growth/src/platforms/carbon.ts
8580
9071
  var carbonAds = defineCsvSource({
8581
9072
  platform: "carbon",
@@ -9506,7 +9997,7 @@ var SiteTouch = object({
9506
9997
  }).strict();
9507
9998
  var SiteTouchHit = object({ touch: SiteTouch }).strict();
9508
9999
  // ../../packages/schemas/src/legal.ts
9509
- var TERMS_VERSION = "2026-10-12";
10000
+ var TERMS_VERSION = "2026-10-13";
9510
10001
  var LEGAL_SITE = "https://scaledthought.com";
9511
10002
  var LEGAL_PATHS = {
9512
10003
  index: "/legal",
@@ -10097,7 +10588,7 @@ async function init(ctx, opts) {
10097
10588
  const where = envKey ? "ST_API_KEY environment variable" : ".env (ST_API_KEY, ST_BASE_URL)";
10098
10589
  if (opts.region && opts.region !== region)
10099
10590
  throw new CliError("region_mismatch", `A ${region} key already exists (${where}) but --region ${opts.region} was requested. Nothing was created.`, `Accounts are pinned to one region. Use the existing ${region} account, or run init in a directory with no ST_API_KEY (and no ST_API_KEY in the environment) to create a separate ${opts.region} account.`, { existing_region: region, requested_region: opts.region });
10100
- const status = await account(ctx);
10591
+ const status = await account2(ctx);
10101
10592
  const ignored = [opts.source !== undefined && "--source", opts.adClick !== undefined && "--ad-click"].filter(Boolean);
10102
10593
  const shown = withoutFreeFields(status);
10103
10594
  const summary = await liveSummary(ctx, region, balanceOf(status));
@@ -10246,7 +10737,7 @@ function withoutFreeFields(o) {
10246
10737
  }
10247
10738
  return out;
10248
10739
  }
10249
- async function account(ctx) {
10740
+ async function account2(ctx) {
10250
10741
  const a = withoutFreeFields(await api(ctx, "GET", "/v1/account"));
10251
10742
  const fields = ["balance_usd", "auto_reload"];
10252
10743
  if (fields.every((f) => (f in a)))
@@ -10271,6 +10762,10 @@ async function accountEmailSet(ctx, address) {
10271
10762
  throw new CliError("bad_argument", `"${address}" isn't an email address.`, `Ask your human for their email, then run: ${OWNER_EMAIL_COMMAND}`);
10272
10763
  return api(ctx, "PUT", "/v1/account/email", { body: { email } });
10273
10764
  }
10765
+ async function accountRename(ctx, name) {
10766
+ const v = name.trim();
10767
+ return api(ctx, "PATCH", "/v1/account", { body: { name: v || null } });
10768
+ }
10274
10769
  async function accountAdMeasurement(ctx, state) {
10275
10770
  const v = state.trim().toLowerCase();
10276
10771
  if (v !== "on" && v !== "off")
@@ -10279,7 +10774,7 @@ async function accountAdMeasurement(ctx, state) {
10279
10774
  }
10280
10775
  var keysList = (ctx) => api(ctx, "GET", "/v1/keys");
10281
10776
  var DURATION_RE = /^(0|[1-9]\d{0,5}[smhd])$/;
10282
- function duration2(flag, v, allowZero = false) {
10777
+ function duration3(flag, v, allowZero = false) {
10283
10778
  if (v === undefined)
10284
10779
  return;
10285
10780
  if (!DURATION_RE.test(v) || !allowZero && v === "0")
@@ -10290,14 +10785,14 @@ var keysCreate = async (ctx, o) => api(ctx, "POST", "/v1/keys", {
10290
10785
  body: {
10291
10786
  name: o.name,
10292
10787
  daily_budget_usd: o.budgetUsd,
10293
- expires_in: duration2("expires-in", o.expiresIn),
10788
+ expires_in: duration3("expires-in", o.expiresIn),
10294
10789
  scopes: o.scopes,
10295
10790
  child: o.child || undefined
10296
10791
  }
10297
10792
  });
10298
10793
  var keysRevoke = (ctx, id) => api(ctx, "DELETE", `/v1/keys/${encodeURIComponent(id)}`);
10299
10794
  var keysRotate = async (ctx, id, o = {}) => api(ctx, "POST", `/v1/keys/${encodeURIComponent(id)}/rotate`, {
10300
- body: { grace: duration2("grace", o.grace, true), expires_in: duration2("expires-in", o.expiresIn) }
10795
+ body: { grace: duration3("grace", o.grace, true), expires_in: duration3("expires-in", o.expiresIn) }
10301
10796
  });
10302
10797
  var keysRevokeSelf = (ctx) => api(ctx, "DELETE", "/v1/keys/self");
10303
10798
  var usage = (ctx, o) => api(ctx, "GET", `/v1/usage?days=${o.days}&group_by=${encodeURIComponent(o.by)}`);
@@ -10358,7 +10853,7 @@ async function chat(ctx, o) {
10358
10853
  };
10359
10854
  }
10360
10855
  var billingStatus = async (ctx) => withoutFreeFields(await api(ctx, "GET", "/v1/billing"));
10361
- var TOPUP_LIMITS = { min_usd: 20, max_usd: 2000, daily_max_usd: 2000 };
10856
+ var TOPUP_LIMITS = { min_usd: 10, max_usd: 2000, daily_max_usd: 2000 };
10362
10857
  function checkTopupLimits(amountUsd, autoReload) {
10363
10858
  const { min_usd, max_usd, daily_max_usd } = TOPUP_LIMITS;
10364
10859
  const range = (flag, v, lo, hi) => {
@@ -12044,14 +12539,14 @@ var models = defineCommand({
12044
12539
  });
12045
12540
  }, args)
12046
12541
  });
12047
- var ACCOUNT_SUBCOMMANDS = new Set(["delete", "ad-measurement", "email"]);
12048
- var account2 = defineCommand({
12542
+ var ACCOUNT_SUBCOMMANDS = new Set(["delete", "rename", "ad-measurement", "email"]);
12543
+ var account3 = defineCommand({
12049
12544
  meta: { name: "account", description: "Region, spend, credit balance, auto-reload and owner_email" },
12050
12545
  args: jsonFlag,
12051
12546
  run: ({ args, rawArgs }) => {
12052
12547
  if (rawArgs.some((a) => ACCOUNT_SUBCOMMANDS.has(a)))
12053
12548
  return;
12054
- return run2(() => account(makeCtx()), args);
12549
+ return run2(() => account2(makeCtx()), args);
12055
12550
  },
12056
12551
  subCommands: {
12057
12552
  delete: defineCommand({
@@ -12065,6 +12560,17 @@ var account2 = defineCommand({
12065
12560
  },
12066
12561
  run: ({ args }) => run2(() => accountDelete(makeCtx(), { confirm: args.confirm }), args)
12067
12562
  }),
12563
+ rename: defineCommand({
12564
+ meta: {
12565
+ name: "rename",
12566
+ description: 'Rename the account (shown on the dashboard and in its emails); "" goes back to the default'
12567
+ },
12568
+ args: {
12569
+ ...jsonFlag,
12570
+ name: { type: "positional", required: true, description: "The new name" }
12571
+ },
12572
+ run: ({ args }) => run2(() => accountRename(makeCtx(), args.name), args)
12573
+ }),
12068
12574
  "ad-measurement": defineCommand({
12069
12575
  meta: {
12070
12576
  name: "ad-measurement",
@@ -12398,7 +12904,7 @@ var billing = defineCommand({
12398
12904
  ...jsonFlag,
12399
12905
  "amount-usd": {
12400
12906
  type: "string",
12401
- description: "Credits to buy in USD (default 20; $20 to $2,000, at most $2,000 per 24 h). Your human can change it"
12907
+ description: "Credits to buy in USD (default 20; $10 to $2,000, at most $2,000 per 24 h). Your human can change it"
12402
12908
  },
12403
12909
  "auto-reload-below": {
12404
12910
  type: "string",
@@ -12759,7 +13265,7 @@ var root = defineCommand({
12759
13265
  models,
12760
13266
  benchmarks: benchmarks2,
12761
13267
  status: status2,
12762
- account: account2,
13268
+ account: account3,
12763
13269
  keys,
12764
13270
  usage: usage3,
12765
13271
  chat: chat2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scaledthought",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "OpenAI-compatible inference for open-weight models, set up by your coding agent. Prepaid, pay per token, no subscription. US live; Canada coming soon.",
5
5
  "license": "MIT",
6
6
  "keywords": [