free-pi-cli 0.6.16 → 0.6.18
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/README.md +2 -0
- package/dist/index.js +1 -1
- package/dist/{main-gckhcg3t.js → main-m86v4egg.js} +118 -16
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/main.ts
|
|
4
|
-
import { spawn as
|
|
4
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
5
5
|
import { realpathSync as realpathSync8, writeFileSync as writeFileSync6 } from "node:fs";
|
|
6
6
|
import { homedir as homedir10 } from "node:os";
|
|
7
7
|
import { dirname as dirname14, join as join15 } from "node:path";
|
|
@@ -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.
|
|
518
|
+
version: "0.6.18",
|
|
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",
|
|
@@ -6001,6 +6001,11 @@ var AdCreativeSchema = object({
|
|
|
6001
6001
|
cta: string2(),
|
|
6002
6002
|
accent: string2()
|
|
6003
6003
|
});
|
|
6004
|
+
var AdNextCreativeSchema = AdCreativeSchema.extend({
|
|
6005
|
+
icon_url: string2().optional(),
|
|
6006
|
+
image_url: string2().optional(),
|
|
6007
|
+
brand_name: string2().optional()
|
|
6008
|
+
});
|
|
6004
6009
|
var AdNextQuerySchema = object({
|
|
6005
6010
|
slot: AdSlotSchema,
|
|
6006
6011
|
own_only: _enum(["1"]).optional()
|
|
@@ -6008,7 +6013,7 @@ var AdNextQuerySchema = object({
|
|
|
6008
6013
|
var AdNextResponseSchema = object({
|
|
6009
6014
|
ad_id: string2(),
|
|
6010
6015
|
click_token: string2(),
|
|
6011
|
-
creative:
|
|
6016
|
+
creative: AdNextCreativeSchema,
|
|
6012
6017
|
click_url: string2(),
|
|
6013
6018
|
source: _enum(["gravity", "own"]).optional(),
|
|
6014
6019
|
imp_url: string2().optional()
|
|
@@ -6609,7 +6614,7 @@ async function runFreePiMcp(args, deps) {
|
|
|
6609
6614
|
}
|
|
6610
6615
|
|
|
6611
6616
|
// src/gravity-pixel.ts
|
|
6612
|
-
import { createHash } from "node:crypto";
|
|
6617
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
6613
6618
|
var GRAVITY_PIXEL_ID = "6cd74804-0541-4d9b-899d-d7fceb465b6f";
|
|
6614
6619
|
function userIdFromJwt(jwt) {
|
|
6615
6620
|
try {
|
|
@@ -6656,14 +6661,15 @@ function startGravityPixel(jwt, storageDir, env = process.env, load = () => impo
|
|
|
6656
6661
|
pixel = undefined;
|
|
6657
6662
|
}
|
|
6658
6663
|
})();
|
|
6664
|
+
const fallbackSessionId = randomUUID();
|
|
6659
6665
|
return () => {
|
|
6660
6666
|
try {
|
|
6661
|
-
|
|
6662
|
-
if (!sdk || !pixel || !sessionId)
|
|
6667
|
+
if (!sdk)
|
|
6663
6668
|
return;
|
|
6669
|
+
const sessionId = pixel?.getSessionId();
|
|
6664
6670
|
const ctx = sdk.gravityContext({
|
|
6665
|
-
sessionId,
|
|
6666
|
-
user: { userId: userHash, gruid: pixel.getVisitorId(), grclid: pixel.getClickId(), graid: pixel.getGraid() }
|
|
6671
|
+
sessionId: sessionId || fallbackSessionId,
|
|
6672
|
+
user: sessionId && pixel ? { userId: userHash, gruid: pixel.getVisitorId(), grclid: pixel.getClickId(), graid: pixel.getGraid() } : { userId: userHash }
|
|
6667
6673
|
});
|
|
6668
6674
|
const encoded = Buffer.from(JSON.stringify(ctx)).toString("base64url");
|
|
6669
6675
|
return encoded.length <= GRAVITY_CONTEXT_MAX_BYTES ? encoded : undefined;
|
|
@@ -6701,6 +6707,7 @@ function loadConfig(env = process.env) {
|
|
|
6701
6707
|
}
|
|
6702
6708
|
|
|
6703
6709
|
// ../pi-ads/src/api.ts
|
|
6710
|
+
import { arch } from "node:os";
|
|
6704
6711
|
var REQUEST_TIMEOUT_MS = 5000;
|
|
6705
6712
|
async function authedFetch(deps, path, init) {
|
|
6706
6713
|
const token = await deps.getToken();
|
|
@@ -6714,10 +6721,18 @@ async function authedFetch(deps, path, init) {
|
|
|
6714
6721
|
Authorization: `Bearer ${token}`,
|
|
6715
6722
|
"Content-Type": "application/json",
|
|
6716
6723
|
...deps.sessionId && (path.startsWith("/ads/next") || path === "/ads/impression") ? { "x-session-id": deps.sessionId } : {},
|
|
6717
|
-
...path.startsWith("/ads/next") ? gravityHeader(deps) : {}
|
|
6724
|
+
...path.startsWith("/ads/next") ? { ...deps.clientVersion ? { "x-client-version": deps.clientVersion } : {}, "x-client-os": process.platform, "x-client-arch": arch(), ...localeHeaders(), ...gravityHeader(deps) } : {}
|
|
6718
6725
|
}
|
|
6719
6726
|
});
|
|
6720
6727
|
}
|
|
6728
|
+
function localeHeaders() {
|
|
6729
|
+
try {
|
|
6730
|
+
const o = Intl.DateTimeFormat().resolvedOptions();
|
|
6731
|
+
return { ...o.timeZone ? { "x-client-timezone": o.timeZone } : {}, ...o.locale ? { "x-client-locale": o.locale } : {} };
|
|
6732
|
+
} catch {
|
|
6733
|
+
return {};
|
|
6734
|
+
}
|
|
6735
|
+
}
|
|
6721
6736
|
function gravityHeader(deps) {
|
|
6722
6737
|
try {
|
|
6723
6738
|
const ctx = deps.getGravityContext?.();
|
|
@@ -7121,6 +7136,7 @@ function createAdsExtension(opts) {
|
|
|
7121
7136
|
baseUrl: opts.baseUrl,
|
|
7122
7137
|
getToken: opts.getToken,
|
|
7123
7138
|
sessionId: opts.sessionId,
|
|
7139
|
+
clientVersion: opts.clientVersion,
|
|
7124
7140
|
fetchImpl: opts.fetchImpl,
|
|
7125
7141
|
getGravityContext: opts.getGravityContext,
|
|
7126
7142
|
onMe: opts.onMe
|
|
@@ -9843,6 +9859,17 @@ function mergeAttribution(a, b) {
|
|
|
9843
9859
|
|
|
9844
9860
|
// src/changelog.ts
|
|
9845
9861
|
var CHANGELOG_HIGHLIGHTS = [
|
|
9862
|
+
{
|
|
9863
|
+
version: "0.6.18",
|
|
9864
|
+
highlights: ["Ads load correctly from your first prompt."]
|
|
9865
|
+
},
|
|
9866
|
+
{
|
|
9867
|
+
version: "0.6.17",
|
|
9868
|
+
highlights: [
|
|
9869
|
+
"free-pi now runs full screen. Click an ad to open it; selecting text still copies it, and the mouse wheel scrolls.",
|
|
9870
|
+
"The questions before start (terms, how you found free-pi, folder trust) now use color."
|
|
9871
|
+
]
|
|
9872
|
+
},
|
|
9846
9873
|
{
|
|
9847
9874
|
version: "0.6.16",
|
|
9848
9875
|
highlights: [
|
|
@@ -14035,10 +14062,83 @@ function patchResumeLine(stream) {
|
|
|
14035
14062
|
};
|
|
14036
14063
|
}
|
|
14037
14064
|
|
|
14065
|
+
// src/safe-url-open.ts
|
|
14066
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
14067
|
+
function openLink(url) {
|
|
14068
|
+
if (process.platform !== "win32")
|
|
14069
|
+
return void openBrowser(url);
|
|
14070
|
+
spawn3("rundll32", ["url.dll,FileProtocolHandler", url], { stdio: "ignore", detached: true }).on("error", () => {}).unref();
|
|
14071
|
+
}
|
|
14072
|
+
function safeOpenUrl(url, open = openLink) {
|
|
14073
|
+
const safe = safeBrowserUrl(url);
|
|
14074
|
+
if (safe)
|
|
14075
|
+
open(safe);
|
|
14076
|
+
}
|
|
14077
|
+
function installSafeUrlOpen(mode, open = openLink) {
|
|
14078
|
+
const m = mode;
|
|
14079
|
+
const patch = (r) => {
|
|
14080
|
+
if (r && "openUrl" in r)
|
|
14081
|
+
r.openUrl = (url) => safeOpenUrl(url, open);
|
|
14082
|
+
};
|
|
14083
|
+
let current = m.renderer;
|
|
14084
|
+
patch(current);
|
|
14085
|
+
Object.defineProperty(m, "renderer", {
|
|
14086
|
+
configurable: true,
|
|
14087
|
+
enumerable: true,
|
|
14088
|
+
get: () => current,
|
|
14089
|
+
set: (next) => {
|
|
14090
|
+
current = next;
|
|
14091
|
+
patch(next);
|
|
14092
|
+
}
|
|
14093
|
+
});
|
|
14094
|
+
}
|
|
14095
|
+
|
|
14038
14096
|
// src/project-trust.ts
|
|
14039
14097
|
import { createInterface } from "node:readline/promises";
|
|
14040
14098
|
import { resolve as resolve3 } from "node:path";
|
|
14041
14099
|
import { hasTrustRequiringProjectResources, ProjectTrustStore } from "@earendil-works/pi-coding-agent";
|
|
14100
|
+
|
|
14101
|
+
// src/prelaunch-style.ts
|
|
14102
|
+
function colorOn() {
|
|
14103
|
+
return !process.env.NO_COLOR && process.stdout.isTTY === true;
|
|
14104
|
+
}
|
|
14105
|
+
var ACCENT = "96";
|
|
14106
|
+
var sgr2 = (code, s, on) => on ? `\x1B[${code}m${s}\x1B[0m` : s;
|
|
14107
|
+
function styleHeader(on = colorOn()) {
|
|
14108
|
+
return sgr2(`1;${ACCENT}`, "›π free-pi", on);
|
|
14109
|
+
}
|
|
14110
|
+
function styleYesNo(prompt, on = colorOn()) {
|
|
14111
|
+
return prompt.replace(/^(.*?)(\[y\/N\])(\s*)$/s, (_m, q, yn, sp) => `${sgr2("1", q, on)}${sgr2(ACCENT, yn, on)}${sp}`);
|
|
14112
|
+
}
|
|
14113
|
+
function styleConsent(text, on = colorOn()) {
|
|
14114
|
+
if (!on)
|
|
14115
|
+
return text;
|
|
14116
|
+
const body = text.split(`
|
|
14117
|
+
`).map((line, i) => {
|
|
14118
|
+
if (i === 0)
|
|
14119
|
+
return sgr2("1", line, on);
|
|
14120
|
+
if (line.startsWith("Terms:"))
|
|
14121
|
+
return line.replace(/https:\/\/\S+/g, (u) => sgr2(`4;${ACCENT}`, u, on));
|
|
14122
|
+
return sgr2("2", line, on);
|
|
14123
|
+
}).join(`
|
|
14124
|
+
`);
|
|
14125
|
+
return `${styleHeader(on)}
|
|
14126
|
+
${body}`;
|
|
14127
|
+
}
|
|
14128
|
+
function styleSourceQuestion(q, on = colorOn()) {
|
|
14129
|
+
if (!on)
|
|
14130
|
+
return q;
|
|
14131
|
+
return q.replace(/How did you find free-pi\? \(optional\)/, (h) => sgr2("1", h, on)).replace(/\d\)/g, (n) => sgr2(ACCENT, n, on)).replace(/Type a number, or press Enter to skip: $/, (h) => sgr2("2", h, on));
|
|
14132
|
+
}
|
|
14133
|
+
function styleIntro(text, on = colorOn()) {
|
|
14134
|
+
const i = text.indexOf("npx ");
|
|
14135
|
+
if (i < 0)
|
|
14136
|
+
return text;
|
|
14137
|
+
return `${sgr2("2", text.slice(0, i).trimEnd(), on)}
|
|
14138
|
+
${sgr2(ACCENT, text.slice(i), on)}`;
|
|
14139
|
+
}
|
|
14140
|
+
|
|
14141
|
+
// src/project-trust.ts
|
|
14042
14142
|
var PROJECT_TRUST_PROMPT = "This folder has project settings for free-pi (.pi/ or .agents/skills), which can run code such as MCP servers and extensions. Trust this folder? [y/N] ";
|
|
14043
14143
|
async function decideProjectTrust(cwd, agentDir, deps) {
|
|
14044
14144
|
if (!(deps.hasTrustRequiringResources ?? hasTrustRequiringProjectResources)(cwd))
|
|
@@ -14051,7 +14151,7 @@ async function decideProjectTrust(cwd, agentDir, deps) {
|
|
|
14051
14151
|
deps.log("This folder has project settings (.pi/ or .agents/skills); they are ignored because it is not trusted.");
|
|
14052
14152
|
return false;
|
|
14053
14153
|
}
|
|
14054
|
-
const decision = /^y(es)?$/i.test((await deps.askLine(PROJECT_TRUST_PROMPT)).trim());
|
|
14154
|
+
const decision = /^y(es)?$/i.test((await deps.askLine(styleYesNo(PROJECT_TRUST_PROMPT))).trim());
|
|
14055
14155
|
store.set(cwd, decision);
|
|
14056
14156
|
return decision;
|
|
14057
14157
|
}
|
|
@@ -14152,7 +14252,7 @@ function buildSettingsManager(opts, models, projectTrusted) {
|
|
|
14152
14252
|
quietStartup: true,
|
|
14153
14253
|
defaultThinkingLevel: "off",
|
|
14154
14254
|
hideThinkingBlock: true,
|
|
14155
|
-
tuiMode: "
|
|
14255
|
+
tuiMode: "fullscreen",
|
|
14156
14256
|
theme: "light/dark",
|
|
14157
14257
|
enableInstallTelemetry: false,
|
|
14158
14258
|
...compactionSettingsFor(opts.costArm) ? { compaction: compactionSettingsFor(opts.costArm) } : {}
|
|
@@ -14186,6 +14286,7 @@ function buildRuntimeOptions(opts, sessionId) {
|
|
|
14186
14286
|
baseUrl: opts.baseUrl,
|
|
14187
14287
|
getToken: () => auth.getJwt(),
|
|
14188
14288
|
sessionId,
|
|
14289
|
+
clientVersion: CLI_VERSION,
|
|
14189
14290
|
getGravityContext: opts.getGravityContext,
|
|
14190
14291
|
onBannerAd: (u) => {
|
|
14191
14292
|
advertiserUrl = u;
|
|
@@ -14451,6 +14552,7 @@ async function launchPi(opts) {
|
|
|
14451
14552
|
});
|
|
14452
14553
|
installLogoutHandler(mode, { credentialsPath: opts.credentialsPath, isGuest: () => auth.isGuest() });
|
|
14453
14554
|
installModelAllowanceHandler(mode);
|
|
14555
|
+
installSafeUrlOpen(mode);
|
|
14454
14556
|
installFooterRightAlign(mode, () => {
|
|
14455
14557
|
const id = runtime.session?.model?.id;
|
|
14456
14558
|
return freeModelBase(pickerModelName(opts, id));
|
|
@@ -14471,8 +14573,8 @@ async function promptConsent(deps, text = CONSENT_TEXT) {
|
|
|
14471
14573
|
deps.log(NON_INTERACTIVE_CONSENT_TEXT);
|
|
14472
14574
|
return false;
|
|
14473
14575
|
}
|
|
14474
|
-
deps.log(text);
|
|
14475
|
-
const answer = await deps.askLine(CONSENT_PROMPT);
|
|
14576
|
+
deps.log(styleConsent(text));
|
|
14577
|
+
const answer = await deps.askLine(styleYesNo(CONSENT_PROMPT));
|
|
14476
14578
|
return parseConsentAnswer(answer);
|
|
14477
14579
|
}
|
|
14478
14580
|
async function promptConsentInteractive(text) {
|
|
@@ -14664,7 +14766,7 @@ function showIntro(log, env = process.env) {
|
|
|
14664
14766
|
if (introSkipped(env))
|
|
14665
14767
|
return;
|
|
14666
14768
|
log(`
|
|
14667
|
-
${INTRO_TEXT}
|
|
14769
|
+
${styleIntro(INTRO_TEXT)}
|
|
14668
14770
|
`);
|
|
14669
14771
|
}
|
|
14670
14772
|
var FIRST_TASK_EXPERIMENT = "retain.first_task";
|
|
@@ -14839,7 +14941,7 @@ async function promptSourceInteractive() {
|
|
|
14839
14941
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
14840
14942
|
try {
|
|
14841
14943
|
return await Promise.race([
|
|
14842
|
-
rl.question(SOURCE_QUESTION),
|
|
14944
|
+
rl.question(styleSourceQuestion(SOURCE_QUESTION)),
|
|
14843
14945
|
new Promise((resolve) => rl.once("close", () => resolve(undefined))),
|
|
14844
14946
|
new Promise((resolve) => rl.once("SIGINT", () => resolve("aborted")))
|
|
14845
14947
|
]);
|
|
@@ -15460,7 +15562,7 @@ ${HELP_TEXT}`);
|
|
|
15460
15562
|
homedir: homedir10(),
|
|
15461
15563
|
execPath: process.execPath,
|
|
15462
15564
|
autoUpdateEnabled: () => readAutoUpdate(getConfigPath()),
|
|
15463
|
-
spawn: (cmd, args, opts) =>
|
|
15565
|
+
spawn: (cmd, args, opts) => spawn4(cmd, args, opts),
|
|
15464
15566
|
proc: process,
|
|
15465
15567
|
log: (message) => console.log(message)
|
|
15466
15568
|
}),
|
package/package.json
CHANGED