feat(coding-agent): make bare update self-only
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
### Changed
|
### 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.
|
- Updated extension docs, examples, runtime help, trust prompts, and config labels to use the configured project config directory instead of hardcoded `.pi` paths.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -419,7 +419,8 @@ pi install ssh://git@github.com/user/repo@v1 # tag or commit
|
|||||||
pi remove npm:@foo/pi-tools
|
pi remove npm:@foo/pi-tools
|
||||||
pi uninstall npm:@foo/pi-tools # alias for remove
|
pi uninstall npm:@foo/pi-tools # alias for remove
|
||||||
pi list
|
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 --extensions # update packages only
|
||||||
pi update --self # update pi only
|
pi update --self # update pi only
|
||||||
pi update --self --force # reinstall pi even if current
|
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
|
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`:
|
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 install <source> [-l] # Install package, -l for project-local
|
||||||
pi remove <source> [-l] # Remove package
|
pi remove <source> [-l] # Remove package
|
||||||
pi uninstall <source> [-l] # Alias for remove
|
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 --extensions # Update packages only
|
||||||
pi update --self # Update pi only
|
pi update --self # Update pi only
|
||||||
pi update --self --force # Reinstall pi even if current
|
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 remove npm:@foo/bar
|
||||||
pi list # show installed packages from settings
|
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 --extensions # update packages and reconcile pinned git refs only
|
||||||
pi update --self # update pi only
|
pi update --self # update pi only
|
||||||
pi update --self --force # reinstall pi even if current
|
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
|
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.
|
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
|
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/`.
|
- User installs go under `~/.pi/agent/npm/`.
|
||||||
- Project installs go under `.pi/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`.
|
- 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.
|
- HTTPS and SSH URLs are both supported.
|
||||||
- SSH URLs use your configured SSH keys automatically (respects `~/.ssh/config`).
|
- 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.
|
- 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.
|
- 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).
|
- 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.
|
- 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 install <source> [-l] # Install package, -l for project-local
|
||||||
pi remove <source> [-l] # Remove package
|
pi remove <source> [-l] # Remove package
|
||||||
pi uninstall <source> [-l] # Alias for remove
|
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 --extensions # Update packages only; reconcile pinned git refs
|
||||||
pi update --self # Update pi only
|
pi update --self # Update pi only
|
||||||
pi update --extension <src> # Update one package
|
pi update --extension <src> # Update one package
|
||||||
@@ -153,7 +154,7 @@ pi list # List installed packages
|
|||||||
pi config # Enable/disable package resources
|
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.
|
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} install <source> [-l] Install extension source and add to settings
|
||||||
${APP_NAME} remove <source> [-l] Remove extension source from settings
|
${APP_NAME} remove <source> [-l] Remove extension source from settings
|
||||||
${APP_NAME} uninstall <source> [-l] Alias for remove
|
${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} list List installed extensions from settings
|
||||||
${APP_NAME} config Open TUI to enable/disable package resources
|
${APP_NAME} config Open TUI to enable/disable package resources
|
||||||
${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list
|
${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list
|
||||||
|
|||||||
@@ -3740,7 +3740,7 @@ export class InteractiveMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showPackageUpdateNotification(packages: string[]): void {
|
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 updateInstruction = theme.fg("muted", "Package updates are available. Run ") + action;
|
||||||
const packageLines = packages.map((pkg) => `- ${pkg}`).join("\n");
|
const packageLines = packages.map((pkg) => `- ${pkg}`).join("\n");
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ interface PackageCommandOptions {
|
|||||||
command: PackageCommand;
|
command: PackageCommand;
|
||||||
source?: string;
|
source?: string;
|
||||||
updateTarget?: UpdateTarget;
|
updateTarget?: UpdateTarget;
|
||||||
|
showExtensionsSkippedNote: boolean;
|
||||||
local: boolean;
|
local: boolean;
|
||||||
force: boolean;
|
force: boolean;
|
||||||
projectTrustOverride?: boolean;
|
projectTrustOverride?: boolean;
|
||||||
@@ -79,7 +80,7 @@ function getPackageCommandUsage(command: PackageCommand): string {
|
|||||||
case "remove":
|
case "remove":
|
||||||
return `${APP_NAME} remove <source> [-l] [--approve|--no-approve]`;
|
return `${APP_NAME} remove <source> [-l] [--approve|--no-approve]`;
|
||||||
case "update":
|
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":
|
case "list":
|
||||||
return `${APP_NAME} list [--approve|--no-approve]`;
|
return `${APP_NAME} list [--approve|--no-approve]`;
|
||||||
}
|
}
|
||||||
@@ -133,15 +134,17 @@ Examples:
|
|||||||
Update pi and installed packages.
|
Update pi and installed packages.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--self Update pi only
|
--self Update pi only (default when no target is given)
|
||||||
--extensions Update installed packages only
|
--extensions Update installed packages only
|
||||||
|
--all Update pi and installed packages
|
||||||
--extension <source> Update one package only
|
--extension <source> Update one package only
|
||||||
-a, --approve Trust project-local files for this command
|
-a, --approve Trust project-local files for this command
|
||||||
-na, --no-approve Ignore 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
|
--force Reinstall pi even if the current version is latest
|
||||||
|
|
||||||
Short forms:
|
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 <source> Update one package
|
||||||
${APP_NAME} update pi Update pi only (self works as alias to pi)
|
${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 source: string | undefined;
|
||||||
let selfFlag = false;
|
let selfFlag = false;
|
||||||
let extensionsFlag = false;
|
let extensionsFlag = false;
|
||||||
|
let allFlag = false;
|
||||||
let extensionFlagSource: string | undefined;
|
let extensionFlagSource: string | undefined;
|
||||||
|
|
||||||
for (let index = 0; index < rest.length; index++) {
|
for (let index = 0; index < rest.length; index++) {
|
||||||
@@ -220,6 +224,15 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg === "--all") {
|
||||||
|
if (command === "update") {
|
||||||
|
allFlag = true;
|
||||||
|
} else {
|
||||||
|
invalidOption = invalidOption ?? arg;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (arg === "--approve" || arg === "-a") {
|
if (arg === "--approve" || arg === "-a") {
|
||||||
projectTrustOverride = true;
|
projectTrustOverride = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -271,10 +284,20 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
|
|||||||
}
|
}
|
||||||
|
|
||||||
let updateTarget: UpdateTarget | undefined;
|
let updateTarget: UpdateTarget | undefined;
|
||||||
|
let showExtensionsSkippedNote = false;
|
||||||
if (command === "update") {
|
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 (extensionFlagSource) {
|
||||||
if (selfFlag || extensionsFlag) {
|
if (selfFlag || extensionsFlag || allFlag) {
|
||||||
conflictingOptions = conflictingOptions ?? "--extension cannot be combined with --self or --extensions";
|
conflictingOptions =
|
||||||
|
conflictingOptions ?? "--extension cannot be combined with --self, --extensions, or --all";
|
||||||
}
|
}
|
||||||
if (source) {
|
if (source) {
|
||||||
conflictingOptions = conflictingOptions ?? "--extension cannot be combined with a positional source";
|
conflictingOptions = conflictingOptions ?? "--extension cannot be combined with a positional source";
|
||||||
@@ -285,12 +308,15 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
|
|||||||
if (sourceIsSelf) {
|
if (sourceIsSelf) {
|
||||||
updateTarget = extensionsFlag ? { type: "all" } : { type: "self" };
|
updateTarget = extensionsFlag ? { type: "all" } : { type: "self" };
|
||||||
} else {
|
} else {
|
||||||
if (extensionsFlag || selfFlag) {
|
if (extensionsFlag || selfFlag || allFlag) {
|
||||||
conflictingOptions =
|
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 };
|
updateTarget = { type: "extensions", source };
|
||||||
}
|
}
|
||||||
|
} else if (allFlag) {
|
||||||
|
updateTarget = { type: "all" };
|
||||||
} else if (selfFlag && extensionsFlag) {
|
} else if (selfFlag && extensionsFlag) {
|
||||||
updateTarget = { type: "all" };
|
updateTarget = { type: "all" };
|
||||||
} else if (selfFlag) {
|
} else if (selfFlag) {
|
||||||
@@ -298,7 +324,8 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
|
|||||||
} else if (extensionsFlag) {
|
} else if (extensionsFlag) {
|
||||||
updateTarget = { type: "extensions" };
|
updateTarget = { type: "extensions" };
|
||||||
} else {
|
} else {
|
||||||
updateTarget = { type: "all" };
|
updateTarget = { type: "self" };
|
||||||
|
showExtensionsSkippedNote = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,6 +333,7 @@ function parsePackageCommand(args: string[]): PackageCommandOptions | undefined
|
|||||||
command,
|
command,
|
||||||
source,
|
source,
|
||||||
updateTarget,
|
updateTarget,
|
||||||
|
showExtensionsSkippedNote,
|
||||||
local,
|
local,
|
||||||
force,
|
force,
|
||||||
projectTrustOverride,
|
projectTrustOverride,
|
||||||
@@ -660,7 +688,12 @@ export async function handlePackageCommand(
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "update": {
|
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)) {
|
if (updateTargetIncludesExtensions(target)) {
|
||||||
const updateSource = target.type === "extensions" ? target.source : undefined;
|
const updateSource = target.type === "extensions" ? target.source : undefined;
|
||||||
await packageManager.update(updateSource);
|
await packageManager.update(updateSource);
|
||||||
|
|||||||
Reference in New Issue
Block a user