feat(coding-agent): make bare update self-only

This commit is contained in:
Armin Ronacher
2026-06-18 18:09:03 +02:00
parent 2b46f38863
commit aae62dfa87
7 changed files with 58 additions and 20 deletions

View File

@@ -229,7 +229,7 @@ ${chalk.bold("Commands:")}
${APP_NAME} install <source> [-l] Install extension source and add to settings
${APP_NAME} remove <source> [-l] Remove extension source from settings
${APP_NAME} uninstall <source> [-l] Alias for remove
${APP_NAME} update [source|self|pi] Update pi and installed extensions
${APP_NAME} update [source|self|pi] Update pi (use --all for pi and extensions)
${APP_NAME} list List installed extensions from settings
${APP_NAME} config Open TUI to enable/disable package resources
${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list

View File

@@ -3740,7 +3740,7 @@ export class InteractiveMode {
}
showPackageUpdateNotification(packages: string[]): void {
const action = theme.fg("accent", `${APP_NAME} update`);
const action = theme.fg("accent", `${APP_NAME} update --extensions`);
const updateInstruction = theme.fg("muted", "Package updates are available. Run ") + action;
const packageLines = packages.map((pkg) => `- ${pkg}`).join("\n");

View File

@@ -52,6 +52,7 @@ interface PackageCommandOptions {
command: PackageCommand;
source?: string;
updateTarget?: UpdateTarget;
showExtensionsSkippedNote: boolean;
local: boolean;
force: boolean;
projectTrustOverride?: boolean;
@@ -79,7 +80,7 @@ function getPackageCommandUsage(command: PackageCommand): string {
case "remove":
return `${APP_NAME} remove <source> [-l] [--approve|--no-approve]`;
case "update":
return `${APP_NAME} update [source|self|pi] [--self] [--extensions] [--extension <source>] [--approve|--no-approve] [--force]`;
return `${APP_NAME} update [source|self|pi] [--self|--extensions|--all] [--extension <source>] [--approve|--no-approve] [--force]`;
case "list":
return `${APP_NAME} list [--approve|--no-approve]`;
}
@@ -133,15 +134,17 @@ Examples:
Update pi and installed packages.
Options:
--self Update pi only
--self Update pi only (default when no target is given)
--extensions Update installed packages only
--all Update pi and installed packages
--extension <source> Update one package only
-a, --approve Trust project-local files for this command
-na, --no-approve Ignore project-local files for this command
--force Reinstall pi even if the current version is latest
Short forms:
${APP_NAME} update Update pi and all extensions
${APP_NAME} update Update pi only
${APP_NAME} update --all Update pi and all extensions
${APP_NAME} update <source> Update one package
${APP_NAME} update pi Update pi only (self works as alias to pi)
`);
@@ -184,6 +187,7 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
let source: string | undefined;
let selfFlag = false;
let extensionsFlag = false;
let allFlag = false;
let extensionFlagSource: string | undefined;
for (let index = 0; index < rest.length; index++) {
@@ -220,6 +224,15 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
continue;
}
if (arg === "--all") {
if (command === "update") {
allFlag = true;
} else {
invalidOption = invalidOption ?? arg;
}
continue;
}
if (arg === "--approve" || arg === "-a") {
projectTrustOverride = true;
continue;
@@ -271,10 +284,20 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
}
let updateTarget: UpdateTarget | undefined;
let showExtensionsSkippedNote = false;
if (command === "update") {
if (allFlag && (selfFlag || extensionsFlag || extensionFlagSource)) {
conflictingOptions =
conflictingOptions ?? "--all cannot be combined with --self, --extensions, or --extension";
}
if (allFlag && source) {
conflictingOptions = conflictingOptions ?? "--all cannot be combined with a positional source";
}
if (extensionFlagSource) {
if (selfFlag || extensionsFlag) {
conflictingOptions = conflictingOptions ?? "--extension cannot be combined with --self or --extensions";
if (selfFlag || extensionsFlag || allFlag) {
conflictingOptions =
conflictingOptions ?? "--extension cannot be combined with --self, --extensions, or --all";
}
if (source) {
conflictingOptions = conflictingOptions ?? "--extension cannot be combined with a positional source";
@@ -285,12 +308,15 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
if (sourceIsSelf) {
updateTarget = extensionsFlag ? { type: "all" } : { type: "self" };
} else {
if (extensionsFlag || selfFlag) {
if (extensionsFlag || selfFlag || allFlag) {
conflictingOptions =
conflictingOptions ?? "positional update targets cannot be combined with --self or --extensions";
conflictingOptions ??
"positional update targets cannot be combined with --self, --extensions, or --all";
}
updateTarget = { type: "extensions", source };
}
} else if (allFlag) {
updateTarget = { type: "all" };
} else if (selfFlag && extensionsFlag) {
updateTarget = { type: "all" };
} else if (selfFlag) {
@@ -298,7 +324,8 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
} else if (extensionsFlag) {
updateTarget = { type: "extensions" };
} else {
updateTarget = { type: "all" };
updateTarget = { type: "self" };
showExtensionsSkippedNote = true;
}
}
@@ -306,6 +333,7 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
command,
source,
updateTarget,
showExtensionsSkippedNote,
local,
force,
projectTrustOverride,
@@ -660,7 +688,12 @@ export async function handlePackageCommand(
}
case "update": {
const target = options.updateTarget ?? { type: "all" };
const target = options.updateTarget ?? { type: "self" };
if (options.showExtensionsSkippedNote) {
console.log(
chalk.dim(`Extensions are skipped. Run ${APP_NAME} update --extensions to update extensions.`),
);
}
if (updateTargetIncludesExtensions(target)) {
const updateSource = target.type === "extensions" ? target.source : undefined;
await packageManager.update(updateSource);