Merge remote-tracking branch 'origin/main' into pr-4756-squash-cleanup
# Conflicts: # scripts/build-binaries.sh
This commit is contained in:
@@ -1047,14 +1047,15 @@ export class DefaultPackageManager implements PackageManager {
|
||||
|
||||
for (const entry of sources) {
|
||||
const parsed = this.parseSource(entry.source);
|
||||
if (parsed.type === "local" || parsed.pinned) {
|
||||
continue;
|
||||
}
|
||||
// Pinned npm versions are fixed. Pinned git refs are configured checkout targets,
|
||||
// so include them to reconcile an existing clone when the configured ref changes.
|
||||
if (parsed.type === "npm") {
|
||||
npmCandidates.push({ ...entry, parsed });
|
||||
continue;
|
||||
if (!parsed.pinned) {
|
||||
npmCandidates.push({ ...entry, parsed });
|
||||
}
|
||||
} else if (parsed.type === "git") {
|
||||
gitCandidates.push({ ...entry, parsed });
|
||||
}
|
||||
gitCandidates.push({ ...entry, parsed });
|
||||
}
|
||||
|
||||
const npmCheckTasks = npmCandidates.map((entry) => async () => ({
|
||||
@@ -1766,6 +1767,11 @@ export class DefaultPackageManager implements PackageManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.ref) {
|
||||
await this.ensureGitRef(targetDir, ["fetch", "origin", source.ref], "FETCH_HEAD");
|
||||
return;
|
||||
}
|
||||
|
||||
const target = await this.getLocalGitUpdateTarget(targetDir);
|
||||
await this.ensureGitRef(targetDir, target.fetchArgs, target.ref);
|
||||
}
|
||||
@@ -1778,7 +1784,8 @@ export class DefaultPackageManager implements PackageManager {
|
||||
cwd: targetDir,
|
||||
timeoutMs: NETWORK_TIMEOUT_MS,
|
||||
});
|
||||
const targetHead = await this.runCommandCapture("git", ["rev-parse", ref], {
|
||||
const commitRef = `${ref}^{commit}`;
|
||||
const targetHead = await this.runCommandCapture("git", ["rev-parse", commitRef], {
|
||||
cwd: targetDir,
|
||||
timeoutMs: NETWORK_TIMEOUT_MS,
|
||||
});
|
||||
@@ -1786,7 +1793,7 @@ export class DefaultPackageManager implements PackageManager {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.runCommand("git", ["reset", "--hard", ref], { cwd: targetDir });
|
||||
await this.runCommand("git", ["reset", "--hard", commitRef], { cwd: targetDir });
|
||||
|
||||
// Clean untracked files (extensions should be pristine)
|
||||
await this.runCommand("git", ["clean", "-fdx"], { cwd: targetDir });
|
||||
|
||||
@@ -129,7 +129,15 @@ function getDefaultAgentDir(): string {
|
||||
function getAttributionHeaders(
|
||||
model: Model<any>,
|
||||
settingsManager: SettingsManager,
|
||||
sessionId?: string,
|
||||
): Record<string, string> | undefined {
|
||||
if (
|
||||
sessionId &&
|
||||
(model.provider === "opencode" || model.provider === "opencode-go" || model.baseUrl.includes("opencode.ai"))
|
||||
) {
|
||||
return { "x-opencode-session": sessionId, "x-opencode-client": "pi" };
|
||||
}
|
||||
|
||||
if (!isInstallTelemetryEnabled(settingsManager)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -332,7 +340,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
||||
throw new Error(auth.error);
|
||||
}
|
||||
const providerRetrySettings = settingsManager.getProviderRetrySettings();
|
||||
const attributionHeaders = getAttributionHeaders(model, settingsManager);
|
||||
const attributionHeaders = getAttributionHeaders(model, settingsManager, options?.sessionId);
|
||||
return streamSimple(model, context, {
|
||||
...options,
|
||||
apiKey: auth.apiKey,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { isAbsolute, relative, resolve, sep } from "node:path";
|
||||
import { type Component, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
||||
import type { AgentSession } from "../../../core/agent-session.ts";
|
||||
import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.ts";
|
||||
@@ -26,6 +27,20 @@ function formatTokens(count: number): string {
|
||||
return `${Math.round(count / 1000000)}M`;
|
||||
}
|
||||
|
||||
export function formatCwdForFooter(cwd: string, home: string | undefined): string {
|
||||
if (!home) return cwd;
|
||||
|
||||
const resolvedCwd = resolve(cwd);
|
||||
const resolvedHome = resolve(home);
|
||||
const relativeToHome = relative(resolvedHome, resolvedCwd);
|
||||
const isInsideHome =
|
||||
relativeToHome === "" ||
|
||||
(relativeToHome !== ".." && !relativeToHome.startsWith(`..${sep}`) && !isAbsolute(relativeToHome));
|
||||
|
||||
if (!isInsideHome) return cwd;
|
||||
return relativeToHome === "" ? "~" : `~${sep}${relativeToHome}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Footer component that shows pwd, token stats, and context usage.
|
||||
* Computes token/context stats from session, gets git branch and extension statuses from provider.
|
||||
@@ -92,11 +107,7 @@ export class FooterComponent implements Component {
|
||||
const contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : "?";
|
||||
|
||||
// Replace home directory with ~
|
||||
let pwd = this.session.sessionManager.getCwd();
|
||||
const home = process.env.HOME || process.env.USERPROFILE;
|
||||
if (home && pwd.startsWith(home)) {
|
||||
pwd = `~${pwd.slice(home.length)}`;
|
||||
}
|
||||
let pwd = formatCwdForFooter(this.session.sessionManager.getCwd(), process.env.HOME || process.env.USERPROFILE);
|
||||
|
||||
// Add git branch if available
|
||||
const branch = this.footerData.getGitBranch();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { createRequire } from "module";
|
||||
import { dirname, join } from "path";
|
||||
import { pathToFileURL } from "url";
|
||||
|
||||
export type ClipboardModule = {
|
||||
setText: (text: string) => Promise<void>;
|
||||
@@ -6,17 +8,25 @@ export type ClipboardModule = {
|
||||
getImageBinary: () => Promise<Array<number>>;
|
||||
};
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
let clipboard: ClipboardModule | null = null;
|
||||
type ClipboardRequire = (id: string) => unknown;
|
||||
|
||||
const moduleRequire = createRequire(import.meta.url);
|
||||
const executableDirRequire = createRequire(pathToFileURL(join(dirname(process.execPath), "package.json")).href);
|
||||
const hasDisplay = process.platform !== "linux" || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
|
||||
|
||||
if (!process.env.TERMUX_VERSION && hasDisplay) {
|
||||
try {
|
||||
clipboard = require("@mariozechner/clipboard") as ClipboardModule;
|
||||
} catch {
|
||||
clipboard = null;
|
||||
export function loadClipboardNative(
|
||||
requires: readonly ClipboardRequire[] = [moduleRequire, executableDirRequire],
|
||||
): ClipboardModule | null {
|
||||
for (const requireClipboard of requires) {
|
||||
try {
|
||||
return requireClipboard("@mariozechner/clipboard") as ClipboardModule;
|
||||
} catch {
|
||||
// Try the next resolution root.
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const clipboard = !process.env.TERMUX_VERSION && hasDisplay ? loadClipboardNative() : null;
|
||||
|
||||
export { clipboard };
|
||||
|
||||
Reference in New Issue
Block a user