free-pi-cli 0.6.21 → 0.6.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -27,4 +27,4 @@ if (err) {
27
27
  console.error(err);
28
28
  process.exit(1);
29
29
  }
30
- await import("./main-7sxf1v5b.js");
30
+ await import("./main-7j7r4bhj.js");
@@ -515,7 +515,7 @@ function folderMatches(cwd, sessionCwd) {
515
515
  // package.json
516
516
  var package_default = {
517
517
  name: "free-pi-cli",
518
- version: "0.6.21",
518
+ version: "0.6.22",
519
519
  description: "Free AI coding agent for your terminal. Ads and a daily free allowance pay for the models; sign in with GitHub and run npx free-pi-cli.",
520
520
  keywords: [
521
521
  "coding agent",
@@ -557,7 +557,7 @@ var package_default = {
557
557
  "@earendil-works/pi-ai": "1.2.0",
558
558
  "@earendil-works/pi-coding-agent": "1.2.0",
559
559
  "@earendil-works/pi-tui": "1.2.0",
560
- "@gravity-ai/api": "1.2.1"
560
+ "@gravity-ai/api": "1.4.0"
561
561
  },
562
562
  devDependencies: {
563
563
  "@freepi/pi-ads": "workspace:*",
@@ -5822,6 +5822,8 @@ var AuthConsentRequestSchema = object({
5822
5822
  signup_src: string2().optional(),
5823
5823
  referral_code: string2().optional()
5824
5824
  });
5825
+ var AuthConsentResponseSchema = object({ ok: literal(true) });
5826
+ var MeConsentResponseSchema = object({ ok: literal(true) });
5825
5827
  var ConnectStartRequestSchema = object({
5826
5828
  consent_version: string2().min(1).max(32),
5827
5829
  signup_src: string2().optional(),
@@ -6028,6 +6030,7 @@ var AdImpressionRequestSchema = object({
6028
6030
  click_token: string2(),
6029
6031
  imp_fired: boolean2().optional()
6030
6032
  });
6033
+ var AdImpressionResponseSchema = object({ ok: literal(true) });
6031
6034
  var AdminAdRequestSchema = object({
6032
6035
  slot: AdSlotSchema,
6033
6036
  creative: AdCreativeSchema,
@@ -6054,10 +6057,26 @@ var ClientVersionResponseSchema = object({
6054
6057
  latest: string2(),
6055
6058
  model: string2().optional(),
6056
6059
  notice: string2().optional(),
6057
- models: array(object({ id: string2(), name: string2(), section: string2().optional(), tier: _enum(["regular", "premium"]).optional() })).optional(),
6060
+ models: array(object({
6061
+ id: string2(),
6062
+ name: string2(),
6063
+ section: string2().optional(),
6064
+ tier: _enum(["regular", "premium"]).optional(),
6065
+ display_name: string2().optional(),
6066
+ free: boolean2().optional(),
6067
+ usage_x: string2().nullable().optional(),
6068
+ note: string2().nullable().optional(),
6069
+ unavailable: boolean2().optional(),
6070
+ stats_id: string2().optional()
6071
+ })).optional(),
6058
6072
  fusion: object({ planner: string2(), executor: string2() }).optional(),
6059
- experiments: record(string2(), object({ variant: _enum(["control", "treatment"]) }).passthrough()).optional(),
6060
- cost_experiment: object({ arm: _enum(COST_ARMS) }).optional()
6073
+ experiments: record(string2(), object({ variant: _enum(["control", "treatment"]), recent_hours: number2().optional() }).passthrough()).optional(),
6074
+ cost_experiment: object({ arm: _enum(COST_ARMS) }).optional(),
6075
+ min_desktop_version: string2().optional(),
6076
+ latest_desktop_version: string2().optional(),
6077
+ min_web_version: string2().optional(),
6078
+ latest_web_version: string2().optional(),
6079
+ desktop_download_url: string2().optional()
6061
6080
  });
6062
6081
  var SessionResetResponseSchema = object({
6063
6082
  released: boolean2()
@@ -6075,6 +6094,7 @@ var MeReferralResponseSchema = object({
6075
6094
  share_line: string2(),
6076
6095
  leaderboard_opt_in: boolean2()
6077
6096
  });
6097
+ var ReferralOptInResponseSchema = object({ ok: literal(true), opt_in: boolean2() });
6078
6098
  var ReferralStatusResponseSchema = object({
6079
6099
  signups: number2(),
6080
6100
  qualified: number2(),
@@ -6086,6 +6106,62 @@ var ReferralStatusResponseSchema = object({
6086
6106
  var ReferralLeaderboardResponseSchema = object({
6087
6107
  entries: array(object({ rank: number2(), qualified_count: number2(), handle: string2().nullable() }))
6088
6108
  });
6109
+ var HealthResponseSchema = object({ ok: literal(true), sha: string2() });
6110
+ var HealthDeepResponseSchema = object({
6111
+ ok: boolean2(),
6112
+ db: _enum(["ok", "timeout", "error"]),
6113
+ sha: string2(),
6114
+ last_db_ok_at: string2().nullable()
6115
+ });
6116
+ var RedeemResponseSchema = object({
6117
+ ok: literal(true),
6118
+ credits_added: number2().int(),
6119
+ balance: number2().int()
6120
+ });
6121
+ var LoginFunnelResponseSchema = union([
6122
+ object({ attempt_id: string2() }),
6123
+ object({ ok: literal(true) })
6124
+ ]);
6125
+ var TelemetryOkResponseSchema = object({ ok: literal(true) });
6126
+ var BlogPostsResponseSchema = object({
6127
+ posts: array(object({
6128
+ slug: string2(),
6129
+ title: string2(),
6130
+ category: string2(),
6131
+ description: string2().nullable(),
6132
+ author: string2().nullable(),
6133
+ published: string2(),
6134
+ revised: string2().nullable(),
6135
+ updated_at: string2(),
6136
+ body: string2()
6137
+ }))
6138
+ });
6139
+ var ToolWebSearchResponseSchema = object({
6140
+ results: array(object({
6141
+ title: string2(),
6142
+ url: string2(),
6143
+ published_date: string2().nullable(),
6144
+ text: string2()
6145
+ })),
6146
+ cost_usd: string2()
6147
+ });
6148
+ var ToolDocsResponseSchema = object({
6149
+ library_id: string2(),
6150
+ title: string2(),
6151
+ docs: string2(),
6152
+ cost_usd: string2()
6153
+ });
6154
+ var ToolImageResponseSchema = object({
6155
+ image_b64: string2(),
6156
+ media_type: _enum(["image/png", "image/jpeg", "image/webp"]),
6157
+ cost_usd: string2(),
6158
+ model: string2()
6159
+ });
6160
+ var ToolVisionResponseSchema = object({
6161
+ text: string2(),
6162
+ cost_usd: string2(),
6163
+ model: string2()
6164
+ });
6089
6165
 
6090
6166
  // ../shared/src/errors.ts
6091
6167
  function assertExhaustiveErrorCode(code) {
@@ -6643,7 +6719,7 @@ function dropPixelSignalHandlers() {
6643
6719
  process.removeListener("newListener", onNew);
6644
6720
  };
6645
6721
  }
6646
- function startGravityPixel(jwt, storageDir, env = process.env, load = () => import("./index-xkn61g24.js")) {
6722
+ function startGravityPixel(jwt, storageDir, env = process.env, load = () => import("./index-vz2s5sjf.js")) {
6647
6723
  if (env.FREEPI_NO_GRAVITY_PIXEL === "1")
6648
6724
  return;
6649
6725
  const userId = userIdFromJwt(jwt);
@@ -7074,6 +7150,20 @@ function mapErrorCode(code) {
7074
7150
  return "This model is only for reward holders. Finish an EARN task from your terminal to unlock it, or switch models with /model.";
7075
7151
  case "subagents_unavailable":
7076
7152
  return "Subagents run on the free Particle model, or with credits. Switch with /model or run /buy-credits.";
7153
+ case "bad_request":
7154
+ case "payload_too_large":
7155
+ case "rate_limited":
7156
+ case "unauthorized":
7157
+ case "denied":
7158
+ case "expired":
7159
+ case "account_ceiling":
7160
+ case "misconfigured":
7161
+ case "bug_report_limit":
7162
+ case "ip_blocked":
7163
+ case "request_aborted":
7164
+ case "insufficient_credits":
7165
+ case "upstream_rate_limited":
7166
+ throw new Error(`unhandled error code: ${code}`);
7077
7167
  default:
7078
7168
  return assertExhaustiveErrorCode(code);
7079
7169
  }
@@ -9324,7 +9414,19 @@ function routeFusion(request, models) {
9324
9414
  return handedOffThisTurn(request.messages) ? route(models.planner, "plan") : route(models.executor, "explore");
9325
9415
  }
9326
9416
  }
9327
- function createFusionExtension(defaultModelId, ids = resolveFusionIds([])) {
9417
+ var FUSION_PREMIUM_REFUSAL = "At capacity for free users. Available with premium credits: /buy-credits. Or switch to Particle-1, DeepSeek V4.1 Flash or GLM 5.3 Flash with /model.";
9418
+ async function fetchHasPremium(opts) {
9419
+ try {
9420
+ const res = await (opts.fetchImpl ?? fetch)(`${opts.baseUrl}/me`, { headers: { Authorization: `Bearer ${await opts.getToken()}` }, signal: AbortSignal.timeout(5000) });
9421
+ if (!res.ok)
9422
+ return true;
9423
+ const me = await res.json();
9424
+ return typeof me.premium_credits === "number" ? me.premium_credits > 0 : true;
9425
+ } catch {
9426
+ return true;
9427
+ }
9428
+ }
9429
+ function createFusionExtension(defaultModelId, ids = resolveFusionIds([]), hasPremium) {
9328
9430
  const name = ids.planner === FUSION_PLANNER_ID && ids.executor === FUSION_EXECUTOR_ID ? FUSION_NAME : ids.planner === FUSION_FALLBACK_PLANNER_ID ? FUSION_FALLBACK_NAME : "\uD83E\uDDE8 Fusion";
9329
9431
  return {
9330
9432
  name: "free-pi-fusion",
@@ -9336,8 +9438,21 @@ function createFusionExtension(defaultModelId, ids = resolveFusionIds([])) {
9336
9438
  return;
9337
9439
  pi.setActiveTools(on ? [...active, FUSION_PLAN_TOOL] : active.filter((name) => name !== FUSION_PLAN_TOOL));
9338
9440
  };
9339
- pi.on("session_start", (_event, ctx) => syncPlanTool(ctx.model));
9340
- pi.on("model_select", (event) => syncPlanTool(event.model));
9441
+ const refuseWithoutPremium = async (model, ctx) => {
9442
+ if (!hasPremium || !isFusionModel(model) || await hasPremium())
9443
+ return false;
9444
+ ctx.ui.notify(FUSION_PREMIUM_REFUSAL, "warning");
9445
+ const fallback = ctx.modelRegistry.find(PROVIDER_NAME, defaultModelId);
9446
+ if (fallback)
9447
+ await pi.setModel(fallback);
9448
+ return true;
9449
+ };
9450
+ const onSelect = (model, ctx) => hasPremium && isFusionModel(model) ? refuseWithoutPremium(model, ctx).then((refused) => {
9451
+ if (!refused)
9452
+ syncPlanTool(model);
9453
+ }) : syncPlanTool(model);
9454
+ pi.on("session_start", (_event, ctx) => onSelect(ctx.model, ctx));
9455
+ pi.on("model_select", (event, ctx) => onSelect(event.model, ctx));
9341
9456
  pi.registerTool({
9342
9457
  name: FUSION_PLAN_TOOL,
9343
9458
  label: "Fusion plan",
@@ -10225,6 +10340,13 @@ function mergeAttribution(a, b) {
10225
10340
 
10226
10341
  // src/changelog.ts
10227
10342
  var CHANGELOG_HIGHLIGHTS = [
10343
+ {
10344
+ version: "0.6.22",
10345
+ highlights: [
10346
+ 'The /model picker now shows "DeepSeek V4.1 Flash 600tps" instead of fire emojis.',
10347
+ "Fusion needs premium credits; without them the CLI explains how to get credits or switch models."
10348
+ ]
10349
+ },
10228
10350
  {
10229
10351
  version: "0.6.21",
10230
10352
  highlights: ["The /support command is removed."]
@@ -12459,7 +12581,8 @@ function createHeaderExtension(opts) {
12459
12581
  // src/ultrafast.ts
12460
12582
  var ULTRAFAST_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high"];
12461
12583
  var ULTRAFAST_CATALOG_ID = "deepseek-v4.1-flash-1017-ultrafast";
12462
- var ULTRAFAST_PICKER_ID = "\uD83D\uDD25\uD83D\uDD25\uD83D\uDD25 ultrafast";
12584
+ var ULTRAFAST_PICKER_ID = "deepseek-v4.1-flash-600tps";
12585
+ var ULTRAFAST_LEGACY_PICKER_ID = "\uD83D\uDD25\uD83D\uDD25\uD83D\uDD25 ultrafast";
12463
12586
  function createUltrafastExtension(model) {
12464
12587
  return {
12465
12588
  name: "free-pi-ultrafast",
@@ -15206,7 +15329,8 @@ function resolveModelName(opts) {
15206
15329
  return opts.models?.[0]?.name || opts.model || MODEL_ID;
15207
15330
  }
15208
15331
  function buildSettingsManager(opts, models, projectTrusted) {
15209
- const saved = readDefaultModel(opts.agentDir);
15332
+ const raw = readDefaultModel(opts.agentDir);
15333
+ const saved = raw?.model === ULTRAFAST_LEGACY_PICKER_ID ? { ...raw, model: ULTRAFAST_PICKER_ID } : raw;
15210
15334
  const known = new Map([
15211
15335
  [PROVIDER_NAME, new Set([...models.map((m) => m.id), FUSION_PICKER_ID, ...models.some((m) => m.id === ULTRAFAST_CATALOG_ID) ? [ULTRAFAST_PICKER_ID] : []])],
15212
15336
  [DEFENSE_PROVIDER_NAME, new Set(defenseModelsFor(opts).map((m) => m.id))]
@@ -15385,7 +15509,7 @@ function buildRuntimeOptions(opts, sessionId) {
15385
15509
  const extensionFactories = [
15386
15510
  providerExtension,
15387
15511
  ...models.some((m) => m.id === ULTRAFAST_CATALOG_ID) ? [createUltrafastExtension(models.find((m) => m.id === ULTRAFAST_CATALOG_ID))] : [],
15388
- createFusionExtension(models[0].id, resolveFusionIds(models.map((m) => m.id), opts.fusion)),
15512
+ createFusionExtension(models[0].id, resolveFusionIds(models.map((m) => m.id), opts.fusion), () => fetchHasPremium({ baseUrl: opts.baseUrl, getToken: () => auth.getJwt() })),
15389
15513
  adsExtension,
15390
15514
  usageToolExtension,
15391
15515
  buyToolExtension,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "free-pi-cli",
3
- "version": "0.6.21",
3
+ "version": "0.6.22",
4
4
  "description": "Free AI coding agent for your terminal. Ads and a daily free allowance pay for the models; sign in with GitHub and run npx free-pi-cli.",
5
5
  "keywords": [
6
6
  "coding agent",
@@ -42,7 +42,7 @@
42
42
  "@earendil-works/pi-ai": "1.2.0",
43
43
  "@earendil-works/pi-coding-agent": "1.2.0",
44
44
  "@earendil-works/pi-tui": "1.2.0",
45
- "@gravity-ai/api": "1.2.1"
45
+ "@gravity-ai/api": "1.4.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@freepi/pi-ads": "workspace:*",