Merge branch 'main' into stream-fn-in-compaction
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Test with: npx tsx src/cli-new.ts [args...]
|
||||
*/
|
||||
import { EnvHttpProxyAgent, setGlobalDispatcher, fetch as undiciFetch } from "undici";
|
||||
import { EnvHttpProxyAgent, setGlobalDispatcher } from "undici";
|
||||
import { APP_NAME } from "./config.js";
|
||||
import { main } from "./main.js";
|
||||
|
||||
@@ -17,15 +17,6 @@ process.emitWarning = (() => {}) as typeof process.emitWarning;
|
||||
// (e.g. vLLM buffering a large tool call) exceed that and abort the SSE stream
|
||||
// with UND_ERR_BODY_TIMEOUT. Disable both — provider SDKs enforce their own
|
||||
// AbortController-based deadlines via retry.provider.timeoutMs.
|
||||
// Node 26 uses an internal undici for globalThis.fetch that does not honor npm
|
||||
// undici's global dispatcher, so route global fetch through npm undici as well.
|
||||
const dispatcher = new EnvHttpProxyAgent({ bodyTimeout: 0, headersTimeout: 0 });
|
||||
setGlobalDispatcher(dispatcher);
|
||||
const fetchWithDispatcher = undiciFetch as unknown as typeof fetch;
|
||||
globalThis.fetch = (input, init) =>
|
||||
fetchWithDispatcher(input, {
|
||||
...init,
|
||||
dispatcher,
|
||||
} as unknown as RequestInit);
|
||||
setGlobalDispatcher(new EnvHttpProxyAgent({ bodyTimeout: 0, headersTimeout: 0 }));
|
||||
|
||||
main(process.argv.slice(2));
|
||||
|
||||
@@ -1084,7 +1084,7 @@ export class DefaultPackageManager implements PackageManager {
|
||||
}
|
||||
|
||||
private async shouldUpdateNpmSource(source: NpmSource, scope: InstalledSourceScope): Promise<boolean> {
|
||||
const installedPath = this.getNpmInstallPath(source, scope);
|
||||
const installedPath = this.getManagedNpmInstallPath(source, scope);
|
||||
const installedVersion = existsSync(installedPath) ? this.getInstalledNpmVersion(installedPath) : undefined;
|
||||
if (!installedVersion) {
|
||||
return true;
|
||||
@@ -1114,13 +1114,9 @@ export class DefaultPackageManager implements PackageManager {
|
||||
}
|
||||
|
||||
private async installNpmBatch(specs: string[], scope: InstalledSourceScope): Promise<void> {
|
||||
if (scope === "user") {
|
||||
await this.runNpmCommand(["install", "-g", ...specs]);
|
||||
return;
|
||||
}
|
||||
const installRoot = this.getNpmInstallRoot(scope, false);
|
||||
this.ensureNpmProject(installRoot);
|
||||
await this.runNpmCommand(["install", ...specs, "--prefix", installRoot]);
|
||||
await this.runNpmCommand(this.getNpmInstallArgs(specs, installRoot));
|
||||
}
|
||||
|
||||
async checkForAvailableUpdates(): Promise<PackageUpdate[]> {
|
||||
@@ -1669,6 +1665,14 @@ export class DefaultPackageManager implements PackageManager {
|
||||
return { command, args };
|
||||
}
|
||||
|
||||
private getPackageManagerName(): string {
|
||||
const npmCommand = this.getNpmCommand();
|
||||
const commandParts = [npmCommand.command, ...npmCommand.args];
|
||||
const separatorIndex = commandParts.lastIndexOf("--");
|
||||
const packageManagerCommand = separatorIndex >= 0 ? commandParts[separatorIndex + 1] : npmCommand.command;
|
||||
return packageManagerCommand ? basename(packageManagerCommand).replace(/\.(cmd|exe)$/i, "") : "";
|
||||
}
|
||||
|
||||
private async runNpmCommand(args: string[], options?: { cwd?: string }): Promise<void> {
|
||||
const npmCommand = this.getNpmCommand();
|
||||
await this.runCommand(npmCommand.command, [...npmCommand.args, ...args], options);
|
||||
@@ -1687,25 +1691,32 @@ export class DefaultPackageManager implements PackageManager {
|
||||
return this.runCommandSync(npmCommand.command, [...npmCommand.args, ...args]);
|
||||
}
|
||||
|
||||
private async installNpm(source: NpmSource, scope: SourceScope, temporary: boolean): Promise<void> {
|
||||
if (scope === "user" && !temporary) {
|
||||
await this.runNpmCommand(["install", "-g", source.spec]);
|
||||
return;
|
||||
private getNpmInstallArgs(specs: string[], installRoot: string): string[] {
|
||||
const packageManagerName = this.getPackageManagerName();
|
||||
if (packageManagerName === "bun") {
|
||||
return ["install", ...specs, "--cwd", installRoot];
|
||||
}
|
||||
if (packageManagerName === "pnpm") {
|
||||
return ["install", ...specs, "--prefix", installRoot, "--config.strict-dep-builds=false"];
|
||||
}
|
||||
return ["install", ...specs, "--prefix", installRoot];
|
||||
}
|
||||
|
||||
private async installNpm(source: NpmSource, scope: SourceScope, temporary: boolean): Promise<void> {
|
||||
const installRoot = this.getNpmInstallRoot(scope, temporary);
|
||||
this.ensureNpmProject(installRoot);
|
||||
await this.runNpmCommand(["install", source.spec, "--prefix", installRoot]);
|
||||
await this.runNpmCommand(this.getNpmInstallArgs([source.spec], installRoot));
|
||||
}
|
||||
|
||||
private async uninstallNpm(source: NpmSource, scope: SourceScope): Promise<void> {
|
||||
if (scope === "user") {
|
||||
await this.runNpmCommand(["uninstall", "-g", source.name]);
|
||||
return;
|
||||
}
|
||||
const installRoot = this.getNpmInstallRoot(scope, false);
|
||||
if (!existsSync(installRoot)) {
|
||||
return;
|
||||
}
|
||||
if (this.getPackageManagerName() === "bun") {
|
||||
await this.runNpmCommand(["uninstall", source.name, "--cwd", installRoot]);
|
||||
return;
|
||||
}
|
||||
await this.runNpmCommand(["uninstall", source.name, "--prefix", installRoot]);
|
||||
}
|
||||
|
||||
@@ -1836,7 +1847,7 @@ export class DefaultPackageManager implements PackageManager {
|
||||
if (scope === "project") {
|
||||
return join(this.cwd, CONFIG_DIR_NAME, "npm");
|
||||
}
|
||||
return join(this.getGlobalNpmRoot(), "..");
|
||||
return join(this.agentDir, "npm");
|
||||
}
|
||||
|
||||
private getGlobalNpmRoot(): string {
|
||||
@@ -1845,8 +1856,7 @@ export class DefaultPackageManager implements PackageManager {
|
||||
if (this.globalNpmRoot && this.globalNpmRootCommandKey === commandKey) {
|
||||
return this.globalNpmRoot;
|
||||
}
|
||||
const isBunPackageManager = npmCommand.command === "bun";
|
||||
if (isBunPackageManager) {
|
||||
if (this.getPackageManagerName() === "bun") {
|
||||
const binDir = this.runNpmCommandSync(["pm", "bin", "-g"]).trim();
|
||||
this.globalNpmRoot = join(dirname(binDir), "install", "global", "node_modules");
|
||||
} else {
|
||||
@@ -1857,14 +1867,7 @@ export class DefaultPackageManager implements PackageManager {
|
||||
}
|
||||
|
||||
private getPnpmGlobalPackagePath(packageName: string): string | undefined {
|
||||
const npmCommand = this.getNpmCommand();
|
||||
const commandParts = [npmCommand.command, ...npmCommand.args];
|
||||
const separatorIndex = commandParts.lastIndexOf("--");
|
||||
const packageManagerCommand = separatorIndex >= 0 ? commandParts[separatorIndex + 1] : npmCommand.command;
|
||||
const packageManagerName = packageManagerCommand
|
||||
? basename(packageManagerCommand).replace(/\.(cmd|exe)$/i, "")
|
||||
: "";
|
||||
if (packageManagerName !== "pnpm") {
|
||||
if (this.getPackageManagerName() !== "pnpm") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1877,14 +1880,31 @@ export class DefaultPackageManager implements PackageManager {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private getNpmInstallPath(source: NpmSource, scope: SourceScope): string {
|
||||
private getManagedNpmInstallPath(source: NpmSource, scope: SourceScope): string {
|
||||
if (scope === "temporary") {
|
||||
return join(this.getTemporaryDir("npm"), "node_modules", source.name);
|
||||
}
|
||||
if (scope === "project") {
|
||||
return join(this.cwd, CONFIG_DIR_NAME, "npm", "node_modules", source.name);
|
||||
}
|
||||
return this.getPnpmGlobalPackagePath(source.name) ?? join(this.getGlobalNpmRoot(), source.name);
|
||||
return join(this.agentDir, "npm", "node_modules", source.name);
|
||||
}
|
||||
|
||||
private getLegacyGlobalNpmInstallPath(source: NpmSource): string | undefined {
|
||||
try {
|
||||
return this.getPnpmGlobalPackagePath(source.name) ?? join(this.getGlobalNpmRoot(), source.name);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private getNpmInstallPath(source: NpmSource, scope: SourceScope): string {
|
||||
const managedPath = this.getManagedNpmInstallPath(source, scope);
|
||||
if (scope !== "user" || existsSync(managedPath)) {
|
||||
return managedPath;
|
||||
}
|
||||
const legacyPath = this.getLegacyGlobalNpmInstallPath(source);
|
||||
return legacyPath && existsSync(legacyPath) ? legacyPath : managedPath;
|
||||
}
|
||||
|
||||
private getGitInstallPath(source: GitSource, scope: SourceScope): string {
|
||||
|
||||
@@ -59,11 +59,12 @@ export function buildSystemPrompt(options: BuildSystemPromptOptions): string {
|
||||
|
||||
// Append project context files
|
||||
if (contextFiles.length > 0) {
|
||||
prompt += "\n\n# Project Context\n\n";
|
||||
prompt += "\n\n<project_context>\n\n";
|
||||
prompt += "Project-specific instructions and guidelines:\n\n";
|
||||
for (const { path: filePath, content } of contextFiles) {
|
||||
prompt += `## ${filePath}\n\n${content}\n\n`;
|
||||
prompt += `<project_instructions path="${filePath}">\n${content}\n</project_instructions>\n\n`;
|
||||
}
|
||||
prompt += "</project_context>\n";
|
||||
}
|
||||
|
||||
// Append skills section (only if read tool is available)
|
||||
|
||||
Reference in New Issue
Block a user