feat(coding-agent): make bare update self-only
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed bare `pi update` to update only pi, added `pi update --all` for updating pi and extensions together, and clarified extension update prompts.
|
||||
- Updated extension docs, examples, runtime help, trust prompts, and config labels to use the configured project config directory instead of hardcoded `.pi` paths.
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -419,7 +419,8 @@ pi install ssh://git@github.com/user/repo@v1 # tag or commit
|
||||
pi remove npm:@foo/pi-tools
|
||||
pi uninstall npm:@foo/pi-tools # alias for remove
|
||||
pi list
|
||||
pi update # update pi and packages (skips pinned packages)
|
||||
pi update # update pi only
|
||||
pi update --all # update pi and packages
|
||||
pi update --extensions # update packages only
|
||||
pi update --self # update pi only
|
||||
pi update --self --force # reinstall pi even if current
|
||||
@@ -427,7 +428,7 @@ pi update npm:@foo/pi-tools # update one package
|
||||
pi config # enable/disable extensions, skills, prompts, themes
|
||||
```
|
||||
|
||||
Packages install to `~/.pi/agent/git/` (git) or `~/.pi/agent/npm/` (npm). Use `-l` for project-local installs (`.pi/git/`, `.pi/npm/`). Git `@ref` values are pinned tags or commits; pinned packages are skipped by `pi update`, so use `pi install git:host/user/repo@new-ref` to move an existing package to a new ref. Git packages install dependencies with `npm install --omit=dev` by default, so runtime deps must be listed under `dependencies`; when `npmCommand` is configured, git packages use plain `install` for compatibility with wrappers. If you use a Node version manager and want package installs to reuse a stable npm context, set `npmCommand` in `settings.json`, for example `["mise", "exec", "node@20", "--", "npm"]`.
|
||||
Packages install to `~/.pi/agent/git/` (git) or `~/.pi/agent/npm/` (npm). Use `-l` for project-local installs (`.pi/git/`, `.pi/npm/`). Git `@ref` values are pinned tags or commits; pinned packages are skipped by `pi update --extensions` and `pi update --all`, so use `pi install git:host/user/repo@new-ref` to move an existing package to a new ref. Git packages install dependencies with `npm install --omit=dev` by default, so runtime deps must be listed under `dependencies`; when `npmCommand` is configured, git packages use plain `install` for compatibility with wrappers. If you use a Node version manager and want package installs to reuse a stable npm context, set `npmCommand` in `settings.json`, for example `["mise", "exec", "node@20", "--", "npm"]`.
|
||||
|
||||
Create a package by adding a `pi` key to `package.json`:
|
||||
|
||||
@@ -518,7 +519,8 @@ pi [options] [@files...] [messages...]
|
||||
pi install <source> [-l] # Install package, -l for project-local
|
||||
pi remove <source> [-l] # Remove package
|
||||
pi uninstall <source> [-l] # Alias for remove
|
||||
pi update [source|self|pi] # Update pi and packages (skips pinned packages)
|
||||
pi update [source|self|pi] # Update pi only, or one package source
|
||||
pi update --all # Update pi and packages
|
||||
pi update --extensions # Update packages only
|
||||
pi update --self # Update pi only
|
||||
pi update --self --force # Reinstall pi even if current
|
||||
|
||||
@@ -28,7 +28,8 @@ pi install ./relative/path/to/package
|
||||
|
||||
pi remove npm:@foo/bar
|
||||
pi list # show installed packages from settings
|
||||
pi update # update pi, update packages, and reconcile pinned git refs
|
||||
pi update # update pi only
|
||||
pi update --all # update pi, update packages, and reconcile pinned git refs
|
||||
pi update --extensions # update packages and reconcile pinned git refs only
|
||||
pi update --self # update pi only
|
||||
pi update --self --force # reinstall pi even if current
|
||||
@@ -36,7 +37,7 @@ pi update npm:@foo/bar # update one package
|
||||
pi update --extension npm:@foo/bar
|
||||
```
|
||||
|
||||
These commands manage pi packages, not the pi CLI installation. To uninstall pi itself, see [Quickstart](quickstart.md#uninstall).
|
||||
These commands manage pi packages and `pi update` can update the pi CLI installation. To uninstall pi itself, see [Quickstart](quickstart.md#uninstall).
|
||||
|
||||
By default, `install` and `remove` write to user settings (`~/.pi/agent/settings.json`). Use `-l` to write to project settings (`.pi/settings.json`) instead. Project settings can be shared with your team, and pi installs any missing packages automatically on startup after the project is trusted.
|
||||
|
||||
@@ -58,7 +59,7 @@ npm:@scope/pkg@1.2.3
|
||||
npm:pkg
|
||||
```
|
||||
|
||||
- Versioned specs are pinned and skipped by package updates (`pi update`, `pi update --extensions`).
|
||||
- Versioned specs are pinned and skipped by package updates (`pi update --extensions`, `pi update --all`).
|
||||
- User installs go under `~/.pi/agent/npm/`.
|
||||
- Project installs go under `.pi/npm/`.
|
||||
- Set `npmCommand` in `settings.json` to pin npm package lookup and install operations to a specific wrapper command such as `mise` or `asdf`.
|
||||
@@ -85,7 +86,7 @@ ssh://git@github.com/user/repo@v1
|
||||
- HTTPS and SSH URLs are both supported.
|
||||
- SSH URLs use your configured SSH keys automatically (respects `~/.ssh/config`).
|
||||
- For non-interactive runs (for example CI), you can set `GIT_TERMINAL_PROMPT=0` to disable credential prompts and set `GIT_SSH_COMMAND` (for example `ssh -o BatchMode=yes -o ConnectTimeout=5`) to fail fast.
|
||||
- Refs are pinned tags or commits. `pi update` and `pi update --extensions` do not move them to newer refs, but they do reconcile an existing clone to the configured ref.
|
||||
- Refs are pinned tags or commits. `pi update --extensions` and `pi update --all` do not move them to newer refs, but they do reconcile an existing clone to the configured ref.
|
||||
- Use `pi install git:host/user/repo@new-ref` to update settings and move an existing package to a new pinned ref.
|
||||
- Cloned to `~/.pi/agent/git/<host>/<path>` (global) or `.pi/git/<host>/<path>` (project).
|
||||
- When reconciliation changes the checkout, pi resets and cleans the clone, then runs `npm install` if `package.json` exists.
|
||||
|
||||
@@ -145,7 +145,8 @@ pi [options] [@files...] [messages...]
|
||||
pi install <source> [-l] # Install package, -l for project-local
|
||||
pi remove <source> [-l] # Remove package
|
||||
pi uninstall <source> [-l] # Alias for remove
|
||||
pi update [source|self|pi] # Update pi and packages; reconcile pinned git refs
|
||||
pi update [source|self|pi] # Update pi only, or one package source
|
||||
pi update --all # Update pi and packages; reconcile pinned git refs
|
||||
pi update --extensions # Update packages only; reconcile pinned git refs
|
||||
pi update --self # Update pi only
|
||||
pi update --extension <src> # Update one package
|
||||
@@ -153,7 +154,7 @@ pi list # List installed packages
|
||||
pi config # Enable/disable package resources
|
||||
```
|
||||
|
||||
These commands manage pi packages, not the pi CLI installation. To uninstall pi itself, see [Quickstart](quickstart.md#uninstall). `pi config` and project package commands accept `--approve`/`--no-approve` to trust or ignore project-local settings for one command. `pi update` never prompts for project trust.
|
||||
These commands manage pi packages and `pi update` can update the pi CLI installation. To uninstall pi itself, see [Quickstart](quickstart.md#uninstall). `pi config` and project package commands accept `--approve`/`--no-approve` to trust or ignore project-local settings for one command. `pi update` never prompts for project trust.
|
||||
|
||||
See [Pi Packages](packages.md) for package sources and security notes.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user