free-pi-cli 0.5.0 → 0.5.2

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
@@ -30,4 +30,4 @@ if (err) {
30
30
  console.error(err);
31
31
  process.exit(1);
32
32
  }
33
- await import("./main-a786gwpy.js");
33
+ await import("./main-43bb5vjt.js");
@@ -14542,6 +14542,23 @@ var BugReportRequestSchema = exports_external.object({
14542
14542
  model: exports_external.string().max(128).optional()
14543
14543
  });
14544
14544
  var BugReportResponseSchema = exports_external.object({ id: exports_external.string() });
14545
+ var MeReferralResponseSchema = exports_external.object({
14546
+ code: exports_external.string(),
14547
+ share_url: exports_external.string(),
14548
+ share_line: exports_external.string(),
14549
+ leaderboard_opt_in: exports_external.boolean()
14550
+ });
14551
+ var ReferralStatusResponseSchema = exports_external.object({
14552
+ signups: exports_external.number(),
14553
+ qualified: exports_external.number(),
14554
+ active_bonuses: exports_external.number(),
14555
+ active_bonus_credits_per_day: exports_external.number(),
14556
+ latest_bonus_ends_at: exports_external.string().nullable(),
14557
+ own_bonus: exports_external.object({ credits_per_day: exports_external.number(), ends_at: exports_external.string() }).nullable()
14558
+ });
14559
+ var ReferralLeaderboardResponseSchema = exports_external.object({
14560
+ entries: exports_external.array(exports_external.object({ rank: exports_external.number(), qualified_count: exports_external.number(), handle: exports_external.string().nullable() }))
14561
+ });
14545
14562
  // ../shared/src/errors.ts
14546
14563
  function assertExhaustiveErrorCode(code) {
14547
14564
  throw new Error(`unhandled error code: ${String(code)}`);
@@ -14621,7 +14638,11 @@ var ConfigSchema = exports_external.object({
14621
14638
  guestMinRequestHeadroomMicros: exports_external.bigint().default(5000n),
14622
14639
  guestIpHashRetentionDays: exports_external.number().int().default(7),
14623
14640
  returnBonusDay2Credits: exports_external.number().int().default(2000),
14624
- returnBonusDay7Credits: exports_external.number().int().default(1000)
14641
+ returnBonusDay7Credits: exports_external.number().int().default(1000),
14642
+ referralBonusCreditsPerDay: exports_external.number().int().default(5000),
14643
+ referralBonusDays: exports_external.number().int().default(30),
14644
+ referralMaxActivePerReferrer: exports_external.number().int().default(10),
14645
+ referralGithubMinAgeDays: exports_external.number().int().default(30)
14625
14646
  });
14626
14647
  function envNumber(value) {
14627
14648
  if (value === undefined || value === "")
@@ -14723,25 +14744,13 @@ function loadConfig(env = process.env) {
14723
14744
  guestMinRequestHeadroomMicros: envMicros("GUEST_MIN_REQUEST_HEADROOM_USD", env.GUEST_MIN_REQUEST_HEADROOM_USD),
14724
14745
  guestIpHashRetentionDays: envStrictInt("GUEST_IP_HASH_RETENTION_DAYS", env.GUEST_IP_HASH_RETENTION_DAYS),
14725
14746
  returnBonusDay2Credits: envStrictInt("RETURN_BONUS_DAY2_CREDITS", env.RETURN_BONUS_DAY2_CREDITS),
14726
- returnBonusDay7Credits: envStrictInt("RETURN_BONUS_DAY7_CREDITS", env.RETURN_BONUS_DAY7_CREDITS)
14747
+ returnBonusDay7Credits: envStrictInt("RETURN_BONUS_DAY7_CREDITS", env.RETURN_BONUS_DAY7_CREDITS),
14748
+ referralBonusCreditsPerDay: envStrictInt("REFERRAL_BONUS_CREDITS_PER_DAY", env.REFERRAL_BONUS_CREDITS_PER_DAY),
14749
+ referralBonusDays: envStrictInt("REFERRAL_BONUS_DAYS", env.REFERRAL_BONUS_DAYS),
14750
+ referralMaxActivePerReferrer: envStrictInt("REFERRAL_MAX_ACTIVE_PER_REFERRER", env.REFERRAL_MAX_ACTIVE_PER_REFERRER),
14751
+ referralGithubMinAgeDays: envStrictInt("REFERRAL_GITHUB_MIN_AGE_DAYS", env.REFERRAL_GITHUB_MIN_AGE_DAYS)
14727
14752
  });
14728
14753
  }
14729
- // ../shared/src/version.ts
14730
- function compareVersions(a, b) {
14731
- const pa = a.split(".").map(Number);
14732
- const pb = b.split(".").map(Number);
14733
- if (pa.length < 3 || pb.length < 3)
14734
- return null;
14735
- for (let i = 0;i < 3; i++) {
14736
- if (Number.isNaN(pa[i]) || Number.isNaN(pb[i]))
14737
- return null;
14738
- if (pa[i] < pb[i])
14739
- return -1;
14740
- if (pa[i] > pb[i])
14741
- return 1;
14742
- }
14743
- return 0;
14744
- }
14745
14754
  // ../shared/src/credits.ts
14746
14755
  var CREDITS_PER_USD = 40000 / 3;
14747
14756
  function usdToCredits(usd) {
@@ -14802,6 +14811,22 @@ function formatLimitNotice(fields, opts = {}) {
14802
14811
  parts.push(`${fields.remaining_credits_today.toLocaleString("en-US")} credits left today`);
14803
14812
  return parts.join(", ");
14804
14813
  }
14814
+ // ../shared/src/version.ts
14815
+ function compareVersions(a, b) {
14816
+ const pa = a.split(".").map(Number);
14817
+ const pb = b.split(".").map(Number);
14818
+ if (pa.length < 3 || pb.length < 3)
14819
+ return null;
14820
+ for (let i = 0;i < 3; i++) {
14821
+ if (Number.isNaN(pa[i]) || Number.isNaN(pb[i]))
14822
+ return null;
14823
+ if (pa[i] < pb[i])
14824
+ return -1;
14825
+ if (pa[i] > pb[i])
14826
+ return 1;
14827
+ }
14828
+ return 0;
14829
+ }
14805
14830
  // ../shared/src/hive.ts
14806
14831
  var HIVE_MAX_CHAT_CHARS = 2048;
14807
14832
  var HIVE_MAX_PROMPT_CHARS = 8192;
@@ -14915,7 +14940,7 @@ var HiveClassifyResponseSchema = exports_external.object({
14915
14940
  // package.json
14916
14941
  var package_default = {
14917
14942
  name: "free-pi-cli",
14918
- version: "0.5.0",
14943
+ version: "0.5.2",
14919
14944
  description: "Free, ad-supported distribution of the pi coding agent. Inference paid for by ads.",
14920
14945
  license: "MIT",
14921
14946
  type: "module",
@@ -20951,6 +20976,17 @@ function mergeAttribution(a, b) {
20951
20976
 
20952
20977
  // src/changelog.ts
20953
20978
  var CHANGELOG_HIGHLIGHTS = [
20979
+ {
20980
+ version: "0.5.2",
20981
+ highlights: ["/model now lists Defense Flash right under Fusion."]
20982
+ },
20983
+ {
20984
+ version: "0.5.1",
20985
+ highlights: [
20986
+ "Invite friends with /invite: when a friend signs in through your link and starts using free-pi, you both get +5,000 credits/day for 30 days.",
20987
+ "/referrals shows your signups, how many qualified, and your active bonuses."
20988
+ ]
20989
+ },
20954
20990
  {
20955
20991
  version: "0.5.0",
20956
20992
  highlights: [
@@ -21664,6 +21700,62 @@ async function showUsage(opts, ctx) {
21664
21700
  const r = await fetchUsageText(opts);
21665
21701
  ctx.ui.notify(r.text, r.ok ? "info" : "error");
21666
21702
  }
21703
+ var GUEST_REFERRAL_LINE = "Sign in with GitHub to invite friends and earn bonus credits. Run /login.";
21704
+ var NO_REFERRALS_LINE = "No referrals yet. Run /invite to get your link.";
21705
+ async function getReferralJson(opts, ctx, path) {
21706
+ if (opts.isGuest?.()) {
21707
+ ctx.ui.notify(GUEST_REFERRAL_LINE, "warning");
21708
+ return;
21709
+ }
21710
+ try {
21711
+ const res = await (opts.fetchImpl ?? fetch)(new URL(path, opts.baseUrl), {
21712
+ headers: { authorization: `Bearer ${await opts.getToken()}` }
21713
+ });
21714
+ if (res.status === 403) {
21715
+ const body = await res.json().catch(() => {
21716
+ return;
21717
+ });
21718
+ ctx.ui.notify(typeof body?.message === "string" ? body.message : GUEST_REFERRAL_LINE, "warning");
21719
+ return;
21720
+ }
21721
+ if (!res.ok) {
21722
+ ctx.ui.notify("Couldn't load your referral info (the server said no) — try again in a moment.", "error");
21723
+ return;
21724
+ }
21725
+ return await res.json();
21726
+ } catch {
21727
+ ctx.ui.notify("Couldn't reach free-pi for your referral info — check your connection.", "error");
21728
+ return;
21729
+ }
21730
+ }
21731
+ async function showInvite(opts, ctx) {
21732
+ const parsed = MeReferralResponseSchema.safeParse(await getReferralJson(opts, ctx, "/me/referral"));
21733
+ if (!parsed.success)
21734
+ return;
21735
+ const r = parsed.data;
21736
+ ctx.ui.notify([`Your invite code: ${r.code}`, `Your invite link: ${r.share_url}`, r.share_line].join(`
21737
+ `), "info");
21738
+ }
21739
+ var formatDay = (iso) => new Date(iso).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" });
21740
+ async function showReferrals(opts, ctx) {
21741
+ const parsed = ReferralStatusResponseSchema.safeParse(await getReferralJson(opts, ctx, "/me/referral/status"));
21742
+ if (!parsed.success)
21743
+ return;
21744
+ const s = parsed.data;
21745
+ const lines = [];
21746
+ if (s.signups === 0) {
21747
+ lines.push(NO_REFERRALS_LINE);
21748
+ } else {
21749
+ lines.push(`Signups via your code: ${s.signups}`, `Qualified (made a first request): ${s.qualified}`, `Active bonuses: ${s.active_bonuses}` + (s.active_bonuses > 0 ? ` (+${s.active_bonus_credits_per_day.toLocaleString("en-US")} credits/day extra)` : ""));
21750
+ if (s.latest_bonus_ends_at)
21751
+ lines.push(`Latest bonus ends: ${formatDay(s.latest_bonus_ends_at)}`);
21752
+ }
21753
+ if (s.own_bonus) {
21754
+ lines.push(`Your signup bonus: +${s.own_bonus.credits_per_day.toLocaleString("en-US")} credits/day until ${formatDay(s.own_bonus.ends_at)}`);
21755
+ }
21756
+ ctx.ui.notify(lines.join(`
21757
+ `), "info");
21758
+ }
21667
21759
  var REA_ARGS = ["-y", "rea-agents@6.7.0", "mcp"];
21668
21760
  var REA_DESCRIPTION = "Reverse-engineering tools (REA): native binaries, JS/Electron apps, APKs, .NET, websites. Use for lawful, authorized analysis only.";
21669
21761
  var REA_NODE_RANGE = "^22.19.0, ^24.11.0, or >=26.0.0";
@@ -21755,6 +21847,14 @@ function createFreePiCommandsExtension(opts) {
21755
21847
  description: "Open today's advertiser in your browser to support free-pi.",
21756
21848
  handler: (_args, ctx) => openAdvertiser(opts, ctx)
21757
21849
  });
21850
+ pi.registerCommand("invite", {
21851
+ description: "Get your invite code and link: you and a friend both get +5k credits/day.",
21852
+ handler: (_args, ctx) => showInvite(opts, ctx)
21853
+ });
21854
+ pi.registerCommand("referrals", {
21855
+ description: "See how many friends signed up with your code and your active bonuses.",
21856
+ handler: (_args, ctx) => showReferrals(opts, ctx)
21857
+ });
21758
21858
  pi.registerCommand("tos", {
21759
21859
  description: "Open the free-pi Terms of Service in your browser.",
21760
21860
  handler: (_args, ctx) => openTos(opts, ctx)
@@ -21781,6 +21881,8 @@ var ALL_COMMANDS = [
21781
21881
  { name: "/privacy-policy", description: "privacy policy" },
21782
21882
  { name: "/buy-credits", description: "get more usage" },
21783
21883
  { name: "/close-other-session", description: "free a stuck session on another machine" },
21884
+ { name: "/invite", description: "invite a friend, you both get +5k credits/day" },
21885
+ { name: "/referrals", description: "your referral status" },
21784
21886
  { name: "/update", description: "get the latest free-pi" }
21785
21887
  ];
21786
21888
  var commands = () => ALL_COMMANDS.filter((c) => c.name !== "/hive" || process.env.FREEPI_HIVE === "1");
@@ -23796,10 +23898,10 @@ process.env.PI_SKIP_VERSION_CHECK = "1";
23796
23898
  process.env.PI_TELEMETRY = "0";
23797
23899
  patchResumeLine(process.stdout);
23798
23900
  function pickerScopeFor(modelRuntime, opts) {
23799
- return [
23800
- ...resolveFreePiScope(modelRuntime, PROVIDER_NAME, catalogModelsFor(opts).map((m) => m.id)),
23801
- ...resolveFreePiScope(modelRuntime, DEFENSE_PROVIDER_NAME, defenseModelsFor(opts).map((m) => m.id))
23802
- ];
23901
+ const main = resolveFreePiScope(modelRuntime, PROVIDER_NAME, catalogModelsFor(opts).map((m) => m.id));
23902
+ const defense = resolveFreePiScope(modelRuntime, DEFENSE_PROVIDER_NAME, defenseModelsFor(opts).map((m) => m.id));
23903
+ const fusion = main.filter((s) => s.model.id === FUSION_PICKER_ID);
23904
+ return [...fusion, ...defense, ...main.filter((s) => !fusion.includes(s))];
23803
23905
  }
23804
23906
  async function launchPi(opts) {
23805
23907
  const cwd = process.cwd();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "free-pi-cli",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Free, ad-supported distribution of the pi coding agent. Inference paid for by ads.",
5
5
  "license": "MIT",
6
6
  "type": "module",