free-pi-cli 0.6.2 → 0.6.3
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 +1 -1
- package/dist/{main-cwwgr8bh.js → main-q0zat1nk.js} +178 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,8 +5,10 @@ import {
|
|
|
5
5
|
} from "./index-n5qs9pq1.js";
|
|
6
6
|
|
|
7
7
|
// src/main.ts
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
9
|
+
import { realpathSync as realpathSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
10
|
+
import { homedir as homedir7 } from "node:os";
|
|
11
|
+
import { dirname as dirname11, join as join13 } from "node:path";
|
|
10
12
|
|
|
11
13
|
// src/browser.ts
|
|
12
14
|
import { spawn } from "node:child_process";
|
|
@@ -15057,7 +15059,7 @@ var HiveClassifyResponseSchema = exports_external.object({
|
|
|
15057
15059
|
// package.json
|
|
15058
15060
|
var package_default = {
|
|
15059
15061
|
name: "free-pi-cli",
|
|
15060
|
-
version: "0.6.
|
|
15062
|
+
version: "0.6.3",
|
|
15061
15063
|
description: "Free, ad-supported distribution of the pi coding agent. Inference paid for by ads.",
|
|
15062
15064
|
license: "MIT",
|
|
15063
15065
|
type: "module",
|
|
@@ -21270,6 +21272,12 @@ function mergeAttribution(a, b) {
|
|
|
21270
21272
|
|
|
21271
21273
|
// src/changelog.ts
|
|
21272
21274
|
var CHANGELOG_HIGHLIGHTS = [
|
|
21275
|
+
{
|
|
21276
|
+
version: "0.6.3",
|
|
21277
|
+
highlights: [
|
|
21278
|
+
"When your version is older than the minimum, free-pi now updates itself and restarts in the same folder, instead of asking you to run a command."
|
|
21279
|
+
]
|
|
21280
|
+
},
|
|
21273
21281
|
{
|
|
21274
21282
|
version: "0.6.2",
|
|
21275
21283
|
highlights: [
|
|
@@ -24562,6 +24570,140 @@ function createRealSpawn(io = { platform: process.platform, spawnSyncImpl: spawn
|
|
|
24562
24570
|
};
|
|
24563
24571
|
}
|
|
24564
24572
|
|
|
24573
|
+
// src/relaunch.ts
|
|
24574
|
+
import { existsSync as existsSync5, mkdtempSync as mkdtempSync2, realpathSync as realpathSync3, rmSync as rmSync2, statSync as statSync3 } from "node:fs";
|
|
24575
|
+
import { constants as osConstants, tmpdir as tmpdir2 } from "node:os";
|
|
24576
|
+
import { delimiter, dirname as dirname9, isAbsolute as isAbsolute2, join as join11, resolve as resolve4, sep as sep2, win32 } from "node:path";
|
|
24577
|
+
function applyRelaunchCwd(env, chdir = (d) => process.chdir(d), isDir = (p) => {
|
|
24578
|
+
try {
|
|
24579
|
+
return statSync3(p).isDirectory();
|
|
24580
|
+
} catch {
|
|
24581
|
+
return false;
|
|
24582
|
+
}
|
|
24583
|
+
}) {
|
|
24584
|
+
const dir = env.FREEPI_RELAUNCH_CWD;
|
|
24585
|
+
delete env.FREEPI_RELAUNCH_CWD;
|
|
24586
|
+
if (!dir)
|
|
24587
|
+
return;
|
|
24588
|
+
const fail2 = `free-pi: could not return to your project folder (${dir}) after updating. Run free-pi again from that folder.`;
|
|
24589
|
+
if (!isDir(dir))
|
|
24590
|
+
return fail2;
|
|
24591
|
+
try {
|
|
24592
|
+
chdir(dir);
|
|
24593
|
+
} catch {
|
|
24594
|
+
return fail2;
|
|
24595
|
+
}
|
|
24596
|
+
return;
|
|
24597
|
+
}
|
|
24598
|
+
var SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
24599
|
+
function canon(p, fold) {
|
|
24600
|
+
let r;
|
|
24601
|
+
try {
|
|
24602
|
+
r = realpathSync3.native(p);
|
|
24603
|
+
} catch {
|
|
24604
|
+
r = resolve4(p);
|
|
24605
|
+
}
|
|
24606
|
+
return fold ? r.toLowerCase() : r;
|
|
24607
|
+
}
|
|
24608
|
+
function isInside2(e, d) {
|
|
24609
|
+
return e === d || e.startsWith(d.endsWith(sep2) ? d : d + sep2);
|
|
24610
|
+
}
|
|
24611
|
+
function hasNodeModulesBin(entry) {
|
|
24612
|
+
const parts = entry.split(/[\\/]+/).map((x) => x.toLowerCase());
|
|
24613
|
+
return parts.some((x, i) => x === "node_modules" && parts[i + 1] === ".bin");
|
|
24614
|
+
}
|
|
24615
|
+
function sanitizedEnv(env, nodeDir, project, home, win) {
|
|
24616
|
+
const proj = canon(project, win);
|
|
24617
|
+
const broad = proj === canon(home, win) || dirname9(proj) === proj;
|
|
24618
|
+
const out = {};
|
|
24619
|
+
let pathKey = "PATH";
|
|
24620
|
+
let oldPath = "";
|
|
24621
|
+
for (const [k, v] of Object.entries(env)) {
|
|
24622
|
+
const lk = k.toLowerCase();
|
|
24623
|
+
if (lk.startsWith("npm_") || lk === "node_options" || lk === "node_path")
|
|
24624
|
+
continue;
|
|
24625
|
+
if (lk === "path") {
|
|
24626
|
+
pathKey = k;
|
|
24627
|
+
oldPath = v ?? "";
|
|
24628
|
+
continue;
|
|
24629
|
+
}
|
|
24630
|
+
if (win && lk === "comspec")
|
|
24631
|
+
continue;
|
|
24632
|
+
out[k] = v;
|
|
24633
|
+
}
|
|
24634
|
+
if (win) {
|
|
24635
|
+
const sysRoot = Object.entries(env).find(([k]) => k.toLowerCase() === "systemroot")?.[1];
|
|
24636
|
+
const root = sysRoot && win32.isAbsolute(sysRoot) ? sysRoot : "C:\\Windows";
|
|
24637
|
+
const comKey = Object.keys(env).find((k) => k.toLowerCase() === "comspec") ?? "ComSpec";
|
|
24638
|
+
out[comKey] = win32.join(root, "System32", "cmd.exe");
|
|
24639
|
+
}
|
|
24640
|
+
const kept = oldPath.split(delimiter).filter((e) => e && isAbsolute2(e) && (broad || !isInside2(canon(e, win), proj)) && !hasNodeModulesBin(e));
|
|
24641
|
+
out[pathKey] = [nodeDir, ...kept].join(delimiter);
|
|
24642
|
+
return out;
|
|
24643
|
+
}
|
|
24644
|
+
async function relaunchViaNpx(latest, deps) {
|
|
24645
|
+
const { env } = deps;
|
|
24646
|
+
if ("FREEPI_NO_AUTO_UPDATE" in env || !deps.autoUpdateEnabled())
|
|
24647
|
+
return;
|
|
24648
|
+
if (env.FREEPI_AUTO_UPDATED)
|
|
24649
|
+
return;
|
|
24650
|
+
const win = deps.platform === "win32";
|
|
24651
|
+
if (!latest || !SEMVER.test(latest))
|
|
24652
|
+
return;
|
|
24653
|
+
const target2 = latest;
|
|
24654
|
+
const nodeDir = dirname9(deps.execPath);
|
|
24655
|
+
const npxCli = win ? join11(nodeDir, "node_modules", "npm", "bin", "npx-cli.js") : join11(dirname9(nodeDir), "lib", "node_modules", "npm", "bin", "npx-cli.js");
|
|
24656
|
+
const exists = deps.exists ?? existsSync5;
|
|
24657
|
+
const distroNpxCli = "/usr/share/nodejs/npm/bin/npx-cli.js";
|
|
24658
|
+
let npxCliPath = npxCli;
|
|
24659
|
+
if (!exists(npxCli)) {
|
|
24660
|
+
if (!win && deps.execPath === "/usr/bin/node" && exists(distroNpxCli))
|
|
24661
|
+
npxCliPath = distroNpxCli;
|
|
24662
|
+
else
|
|
24663
|
+
return;
|
|
24664
|
+
}
|
|
24665
|
+
const childEnv = sanitizedEnv(env, nodeDir, deps.cwd, deps.homedir, win);
|
|
24666
|
+
const readyDir = mkdtempSync2(join11(tmpdir2(), "free-pi-relaunch-"));
|
|
24667
|
+
const readyFile = join11(readyDir, "started");
|
|
24668
|
+
try {
|
|
24669
|
+
deps.log(`Updating free-pi to ${target2}…`);
|
|
24670
|
+
return await new Promise((resolve5) => {
|
|
24671
|
+
let child;
|
|
24672
|
+
try {
|
|
24673
|
+
child = deps.spawn(deps.execPath, [npxCliPath, "--yes", `free-pi-cli@${target2}`, ...deps.argv], {
|
|
24674
|
+
stdio: "inherit",
|
|
24675
|
+
cwd: deps.homedir,
|
|
24676
|
+
env: { ...childEnv, FREEPI_AUTO_UPDATED: target2, FREEPI_RELAUNCH_READY: readyFile, FREEPI_RELAUNCH_CWD: deps.cwd },
|
|
24677
|
+
shell: false
|
|
24678
|
+
});
|
|
24679
|
+
} catch {
|
|
24680
|
+
resolve5(undefined);
|
|
24681
|
+
return;
|
|
24682
|
+
}
|
|
24683
|
+
const handlers = win ? [] : [
|
|
24684
|
+
["SIGINT", () => {}],
|
|
24685
|
+
["SIGTERM", () => void child.kill("SIGTERM")],
|
|
24686
|
+
["SIGHUP", () => void child.kill("SIGTERM")]
|
|
24687
|
+
];
|
|
24688
|
+
for (const [sig, cb] of handlers)
|
|
24689
|
+
deps.proc.on(sig, cb);
|
|
24690
|
+
const done3 = (code) => {
|
|
24691
|
+
for (const [sig, cb] of handlers)
|
|
24692
|
+
deps.proc.off(sig, cb);
|
|
24693
|
+
resolve5(code);
|
|
24694
|
+
};
|
|
24695
|
+
child.on("error", () => done3(undefined));
|
|
24696
|
+
child.on("exit", (code, signal) => {
|
|
24697
|
+
const exitCode = code ?? 128 + (signal ? osConstants.signals[signal] ?? 0 : 0);
|
|
24698
|
+
const cancelled = signal === "SIGINT" || signal === "SIGTERM" || signal === "SIGHUP" || exitCode === 130 || exitCode === 143 || exitCode === 129;
|
|
24699
|
+
done3(exitCode !== 0 && !cancelled && !existsSync5(readyFile) ? undefined : exitCode);
|
|
24700
|
+
});
|
|
24701
|
+
});
|
|
24702
|
+
} finally {
|
|
24703
|
+
rmSync2(readyDir, { recursive: true, force: true });
|
|
24704
|
+
}
|
|
24705
|
+
}
|
|
24706
|
+
|
|
24565
24707
|
// src/run.ts
|
|
24566
24708
|
import { SessionManager as SessionManager2 } from "@earendil-works/pi-coding-agent";
|
|
24567
24709
|
|
|
@@ -24692,13 +24834,13 @@ async function readOneKeypress(prompt, stdin = process.stdin, stdout = process.s
|
|
|
24692
24834
|
if (typeof stdin.setRawMode === "function")
|
|
24693
24835
|
stdin.setRawMode(true);
|
|
24694
24836
|
stdin.resume();
|
|
24695
|
-
return await new Promise((
|
|
24837
|
+
return await new Promise((resolve5) => {
|
|
24696
24838
|
const onData = (chunk) => {
|
|
24697
24839
|
stdin.off("data", onData);
|
|
24698
24840
|
if (typeof stdin.setRawMode === "function")
|
|
24699
24841
|
stdin.setRawMode(wasRaw ?? false);
|
|
24700
24842
|
stdin.pause();
|
|
24701
|
-
|
|
24843
|
+
resolve5(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
|
|
24702
24844
|
};
|
|
24703
24845
|
stdin.once("data", onData);
|
|
24704
24846
|
});
|
|
@@ -24714,9 +24856,9 @@ async function promptResumeInteractive(session) {
|
|
|
24714
24856
|
}
|
|
24715
24857
|
|
|
24716
24858
|
// src/onboarding.ts
|
|
24717
|
-
import { existsSync as
|
|
24859
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, realpathSync as realpathSync4 } from "node:fs";
|
|
24718
24860
|
import { homedir as homedir6 } from "node:os";
|
|
24719
|
-
import { join as
|
|
24861
|
+
import { join as join12 } from "node:path";
|
|
24720
24862
|
var INTRO_ENV_SKIP = "FREEPI_NO_INTRO";
|
|
24721
24863
|
var INTRO_TEXT = `
|
|
24722
24864
|
Welcome to free-pi — a free coding agent in your terminal.
|
|
@@ -24745,9 +24887,9 @@ var FIRST_TASK_EXPERIMENT = "retain.first_task";
|
|
|
24745
24887
|
var PROJECT_MARKERS = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "Gemfile", "composer.json"];
|
|
24746
24888
|
function looksLikeProject(cwd, home = homedir6()) {
|
|
24747
24889
|
try {
|
|
24748
|
-
if (
|
|
24890
|
+
if (realpathSync4(cwd) === realpathSync4(home))
|
|
24749
24891
|
return false;
|
|
24750
|
-
if (PROJECT_MARKERS.some((m) =>
|
|
24892
|
+
if (PROJECT_MARKERS.some((m) => existsSync6(join12(cwd, m))))
|
|
24751
24893
|
return true;
|
|
24752
24894
|
return readdirSync3(cwd).some((f) => /\.(sln|csproj)$/.test(f));
|
|
24753
24895
|
} catch {
|
|
@@ -24774,12 +24916,12 @@ ${text}
|
|
|
24774
24916
|
}
|
|
24775
24917
|
|
|
24776
24918
|
// src/whats-new.ts
|
|
24777
|
-
import { existsSync as
|
|
24778
|
-
import { dirname as
|
|
24919
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
24920
|
+
import { dirname as dirname10 } from "node:path";
|
|
24779
24921
|
function maybeWhatsNew(cliVersion, agentDir) {
|
|
24780
24922
|
try {
|
|
24781
24923
|
const path = getLastSeenVersionPath(agentDir);
|
|
24782
|
-
const lastSeen =
|
|
24924
|
+
const lastSeen = existsSync7(path) ? readFileSync4(path, "utf-8").trim() : undefined;
|
|
24783
24925
|
writeLastSeen(path, cliVersion);
|
|
24784
24926
|
if (lastSeen === undefined)
|
|
24785
24927
|
return;
|
|
@@ -24795,7 +24937,7 @@ function maybeWhatsNew(cliVersion, agentDir) {
|
|
|
24795
24937
|
}
|
|
24796
24938
|
}
|
|
24797
24939
|
function writeLastSeen(path, version3) {
|
|
24798
|
-
mkdirSync2(
|
|
24940
|
+
mkdirSync2(dirname10(path), { recursive: true });
|
|
24799
24941
|
writeFileSync2(path, version3, "utf-8");
|
|
24800
24942
|
}
|
|
24801
24943
|
|
|
@@ -24950,6 +25092,9 @@ Guest trial is not available right now.
|
|
|
24950
25092
|
if (outcome === "updated-exit")
|
|
24951
25093
|
return 0;
|
|
24952
25094
|
if (outcome === "blocked") {
|
|
25095
|
+
const relaunched = await deps.relaunchLatest?.(versionCheck.latest);
|
|
25096
|
+
if (relaunched !== undefined)
|
|
25097
|
+
return relaunched;
|
|
24953
25098
|
deps.log("free-pi-cli needs an update. From a trusted folder (for example: cd ~), run: npx --yes free-pi-cli@latest (or: npm i -g free-pi-cli@latest)");
|
|
24954
25099
|
return 1;
|
|
24955
25100
|
}
|
|
@@ -25118,12 +25263,17 @@ async function checkClientVersion(baseUrl, cliVersion, fetchImpl = fetch, jwt2)
|
|
|
25118
25263
|
// src/main.ts
|
|
25119
25264
|
function resolveCliRealpath() {
|
|
25120
25265
|
try {
|
|
25121
|
-
return
|
|
25266
|
+
return realpathSync5(process.argv[1] ?? "");
|
|
25122
25267
|
} catch {
|
|
25123
25268
|
return "";
|
|
25124
25269
|
}
|
|
25125
25270
|
}
|
|
25126
25271
|
async function main() {
|
|
25272
|
+
const cwdError = applyRelaunchCwd(process.env);
|
|
25273
|
+
if (cwdError) {
|
|
25274
|
+
console.error(cwdError);
|
|
25275
|
+
process.exit(1);
|
|
25276
|
+
}
|
|
25127
25277
|
if (process.env.FREEPI_RELAUNCH_READY) {
|
|
25128
25278
|
try {
|
|
25129
25279
|
writeFileSync3(process.env.FREEPI_RELAUNCH_READY, "");
|
|
@@ -25169,11 +25319,23 @@ ${HELP_TEXT}`);
|
|
|
25169
25319
|
credentialsPath: getCredentialsPath(agentDir),
|
|
25170
25320
|
promptConsent: promptConsentInteractive,
|
|
25171
25321
|
openBrowser,
|
|
25172
|
-
sleep: (ms) => new Promise((
|
|
25322
|
+
sleep: (ms) => new Promise((resolve5) => setTimeout(resolve5, ms)),
|
|
25173
25323
|
launchPi,
|
|
25174
25324
|
log: (message) => console.log(message),
|
|
25175
25325
|
checkClientVersion: (baseUrl, cliVersion, jwt2) => checkClientVersion(baseUrl, cliVersion, fetch, jwt2),
|
|
25176
|
-
startGravityPixel: (jwt2) => startGravityPixel(jwt2,
|
|
25326
|
+
startGravityPixel: (jwt2) => startGravityPixel(jwt2, join13(dirname11(agentDir), "gravity")),
|
|
25327
|
+
relaunchLatest: (latest) => relaunchViaNpx(latest, {
|
|
25328
|
+
env: process.env,
|
|
25329
|
+
argv: process.argv.slice(2),
|
|
25330
|
+
platform: process.platform,
|
|
25331
|
+
cwd: process.cwd(),
|
|
25332
|
+
homedir: homedir7(),
|
|
25333
|
+
execPath: process.execPath,
|
|
25334
|
+
autoUpdateEnabled: () => readAutoUpdate(getConfigPath()),
|
|
25335
|
+
spawn: (cmd, args, opts) => spawn3(cmd, args, opts),
|
|
25336
|
+
proc: process,
|
|
25337
|
+
log: (message) => console.log(message)
|
|
25338
|
+
}),
|
|
25177
25339
|
maybeSelfUpdate: (action2, latest) => maybeSelfUpdate(action2, latest, {
|
|
25178
25340
|
env: process.env,
|
|
25179
25341
|
autoUpdateEnabled: () => readAutoUpdate(getConfigPath()),
|