Commit graph

7388 commits

Author SHA1 Message Date
Petr Houška
806cdd68e3
fix(coding-agent): only report packages as up to date when pi update checked them (#11711)
## Problem

#11707 prints `Packages are already up to date` whenever no package
changed. In two cases that claim is false.

**1. npm left the old version installed.** Extension updates install
`@latest` or the configured range. If npm resolves stale registry
metadata, it reinstalls the old version and exits 0. The existing check
warns, then the summary contradicts it:

```
Updating npm:foo...
npm:foo is still 1.2.0 (registry reports 1.3.0); npm registry metadata may be stale, try again in a few minutes
Packages are already up to date
```

**2. Offline mode.** With `--offline` or `PI_OFFLINE=1`,
`updateConfiguredSources()` returns before checking anything, and the
CLI still prints `Packages are already up to date`.

## Change

The CLI only prints "already up to date" when the update ran and printed
no warning:

| Situation | Output |
|---|---|
| Packages changed | `Updated N packages:` and the list (unchanged) |
| Nothing changed, no warnings | `Packages are already up to date`
(unchanged) |
| Nothing changed, a warning was printed | `No packages were updated,
see the warnings above` (or `<source> was not updated, ...`) |
| Offline mode | `Skipped package updates (offline mode)` |

The CLI counts `progress` update events, which are always warnings, and
does not try to map them to packages. That is deliberate: the git
warning about untracked files that could not be cleaned is printed even
though the commit did change, so a warning does not mean "this package
was not updated".

In offline mode, `update()` still runs, so `pi update <unknown source>`
still fails with "No matching package". `isOfflineModeEnabled()` is now
exported from `core/package-manager.ts` (not from the package index) so
the CLI uses the same check.

The changelog entry from #11707 is adjusted, since it is unreleased.

## Tests

`test/package-command-paths.test.ts`, both through `main()`:

- npm `view` reports 1.3.0 but `install` leaves 1.2.0: the
stale-metadata warning is printed, then `No packages were updated, see
the warnings above`, and no "up to date".
- `PI_OFFLINE=1`: `Skipped package updates (offline mode)`, no "up to
date".

Both fail without the fix. `cycles project package overrides in config
local mode`, `prints a pnpm metadata hint when self-update fails` and
`should expand ~ in exclusion and exact patterns` fail locally on
Windows, on `origin/main` as well.
2026-11-02 21:49:07 +01:00
Mario Zechner
65c85bda2c docs(chord): slice 11 spec, the sandbox is a child process 2026-11-02 20:47:13 +00:00
Mario Zechner
10cf3264fb docs(chord): design §23, the terminal's sandbox is a child process 2026-11-02 20:26:54 +00:00
Mario Zechner
128912d246 docs(chord): the terminal's sandbox is a child process 2026-11-02 20:26:39 +00:00
Petr Houška
342514bdf8
feat(coding-agent): list updated packages with version changes in pi update (#11707)
## Problem

`pi update`, `pi update --all` and `pi update --extensions` print only
`Updating <source>...` progress lines and a final `Updated packages`.
Users cannot see which extensions changed or to which version. Several
outdated npm packages in the same scope are installed as one batch, so
the progress output does not even name them.

## Change

`pi update` now prints a summary of what actually changed:

```
Updated 2 packages:
  npm:foo 1.2.0 -> 1.3.0
  git:github.com/user/bar (project) abc1234 -> def5678
```

When nothing changed it prints `Packages are already up to date` (or
`<source> is already up to date`).

- npm: compares the installed `package.json` version before and after
the batch install. The "before" version comes from the existing
`shouldUpdateNpmSource` check, so this adds no extra registry calls.
- git: compares `git rev-parse HEAD` before and after `updateGit`.
Commits are shortened to 7 characters.
- Packages whose version or commit did not change are omitted, including
npm installs that hit stale registry metadata (those already get the
existing warning).

## API

`PackageManager.update()` still returns `Promise<void>`.
`ProgressEvent.type` gains a `"result"` member. Each changed package is
reported through the existing progress callback as:

```ts
{ type: "result", action: "update", source: "npm:foo", message: "npm:foo 1.2.0 -> 1.3.0" }
```

The CLI collects these messages to print the summary. A separate type
keeps the existing contract that each `start` is followed by exactly one
`complete` or `error` for the same source. Reusing `complete` would have
produced a second `complete` for git packages and a `complete` without a
`start` for batched npm packages. The only compatibility cost is for
TypeScript consumers with an exhaustive `switch` on `event.type`.

## Tests

- `test/package-manager.test.ts`: npm update emits `start`, `complete`,
then a `result` with `npm:example@^1.0.0 (project) 1.0.0 -> 1.2.0`; an
up-to-date package emits no result.
- `test/git-update.test.ts`: git update emits a result with the old and
new commit; an up-to-date clone emits no result.

`should expand ~ in exclusion and exact patterns` fails locally on
Windows. It tests path resolution and is unrelated to this change.
2026-11-02 21:21:23 +01:00
Mario Zechner
15f00a786a docs(chord): example 60, session sync played with the store's outbox, applyBatch and archives 2026-11-02 20:13:38 +00:00
Mario Zechner
642e30b689 docs(chord): p3 meeting prep with pictures, sync example, branches 2026-11-02 17:18:31 +00:00
Mario Zechner
1746cfd515 docs(chord): i18n proposal, t.message and one file per host 2026-11-02 17:09:59 +00:00
Mario Zechner
48f9f1b423 docs(chord): i18n proposal, messages as object state 2026-11-02 17:03:46 +00:00
Mario Zechner
7dffeaf521 docs(chord): i18n proposal 2026-11-02 16:58:24 +00:00
Mario Zechner
1f8604f84f docs(chord): sync applies batches with the host stopped 2026-11-02 16:47:09 +00:00
Mario Zechner
95485d32f1 docs(chord): startServer, exportData without stopping; p3 notes on subagent context and tree 2026-11-02 16:15:54 +00:00
Mario Zechner
e64f313bd6 docs(chord): p3 feature set and work packages, meeting prep 2026-11-02 15:58:52 +00:00
Mario Zechner
cf74b67653 docs(chord): p3 meeting summary, session sync and index 2026-11-02 15:49:56 +00:00
Mario Zechner
d6af4d18e5 docs(chord): looks and themes decided; slice 11 spec gains themes 2026-11-02 15:23:22 +00:00
Mario Zechner
072e413bf3 feat(chord): Chord v2 slice 13, the app kit
chord/next/app: startApp and startWorker with the fixed app layout, worker kinds,
AppInfo and WorkerInfo; sessions (hashed tokens, rolling cookies, bearer tokens),
the one-time owner link, the owner token file, device pairing; Files per host
with ordered chunked uploads; export and import per address; plugin roots,
installs and applyChanges; optional users, invite and ephemeral login facets.
HTTP: deny by default (public routes and sockets), remoteAddress,
readSignedCookie. Examples 53-55.
2026-11-02 15:13:37 +00:00
m3
0ec20e157b
feat(ai): add Microsoft-Decision-1 classifier to GitHub Copilot (#11679)
Closes #11678

Changes:
- `catalog/providers/github-copilot.ts`: add `microsoft-decision-1` as a
`typesafe-system-one` classifier (text input, 32768 context, $0.042/M
input, Copilot's static headers).
- `src/providers/github-copilot.ts`: register the classifier and wrap
`typesafeSystemOneApi()` to add `/v1` to the base URL, since Copilot
serves `/v1/systemone` and the OAuth login replaces the base URL with
the account endpoint.
- README and `docs/models.md`: add the model to the classifier tables.

Tests:
- `test/classifier-models.test.ts`: with an OAuth credential, the
request goes to `https://api.enterprise.githubcopilot.com/v1/systemone`
with the Copilot headers, and the model stays available although
`availableModelIds` lists only chat models. With an API key, it goes to
`https://api.individual.githubcopilot.com/v1/systemone`. Both tests fail
without the wrapper.
- Ran against `api.enterprise.githubcopilot.com` with a Copilot login:
bool, choice, and score questions return answers and usage.

Co-authored-by: Hongwei Ma <11957602+Marvae@users.noreply.github.com>
2026-11-02 16:12:43 +01:00
Mario Zechner
ff2c8931cf docs(chord): looks and themes proposal 2026-11-02 15:05:24 +00:00
Vegard Stikbakke
62752fd4c3
fix(coding-agent): serve catalogs without version redirect (#11690)
Update the model catalog protocol to pi.dev after a change to stop
pi.dev redirecting released clients to `?pi-version=` URLs and serve
their catalog directly. The released CLI is unaffected.
2026-11-02 14:42:17 +01:00
Mario Zechner
9823079ad9 feat(chord): Chord v2 slice 12, the plugin model
Plugins import the app's versioned API (createPlugins api option: unlisted
versions, other kinds' modules, mixed versions and direct Chord imports refused),
each other by relative path within a root or by package name across
repositories (npm or git pins), with per-kind files checked by name.
chord.plugins lists a package's plugins. Required roots, single-file plugins,
installPlugin from git or npm, testPlugin with stub facets.
plugin-authoring.md for authors and agents. Examples 49-52.
2026-11-02 13:19:03 +00:00
Mario Zechner
3e0eec29f5 docs(chord): chord.plugins is a package's manifest of plugins 2026-11-02 12:20:33 +00:00
David Brailovsky
4a6a58eb59 fix(ai): keep root $defs in Anthropic non-strict tool schemas
The non-strict input_schema kept only type/properties/required, so
property $refs into root $defs or definitions pointed at nothing. Claude
then produced wrong arguments (a JSON string instead of an object), and
some Anthropic-compatible gateways rejected the request.

Root anyOf/oneOf/allOf are still left out: Anthropic rejects them with a
400. That part of #9557 and #9134 stays open.
2026-11-02 13:12:50 +01:00
David Brailovsky
9ee7586a95 fix(ai): send drop_block for OpenCode Zen and Go Claude models
Enable per-message effort for OpenCode Claude models that support it, which
also sends thinking.block_binding drop_block. OpenCode Go rejected replayed
thinking with a 400 after the tool list or system prompt changed.

closes #10954
2026-11-02 12:37:52 +01:00
Mario Zechner
7b991fd96a docs(chord): slice 11 spec, web and TUI on the app kit 2026-11-02 11:15:21 +00:00
Mario Zechner
8d81a0f49d docs(chord): slice 13 spec, the app kit 2026-11-02 11:14:37 +00:00
Mario Zechner
ebce9debd4 docs(chord): fold the plugin model, app kit and slice 11 decisions into the design; slice 12 spec 2026-11-02 11:13:08 +00:00
Mario Zechner
752019da07 docs(chord): slice 11 terminal component scope 2026-11-02 11:03:04 +00:00
Mario Zechner
e8504dfab5 docs(chord): slice 11 terminal client always sandboxed 2026-11-02 11:00:43 +00:00
Mario Zechner
20f600e58d docs(chord): slice 11 React bindings 2026-11-02 10:59:40 +00:00
Mario Zechner
2f153034b4 docs(chord): slice 11 connection loop 2026-11-02 10:58:40 +00:00
Mario Zechner
9942d5bbcf docs(chord): slice 11 pages learn of new scripts through Chord 2026-11-02 10:57:16 +00:00
Mario Zechner
7f7ec86806 docs(chord): slice 11 applies plugin scripts in place 2026-11-02 10:56:16 +00:00
Mario Zechner
cdd50052f6 docs(chord): slice 11 base bundle and plugin scripts 2026-11-02 10:55:18 +00:00
Mario Zechner
3cec8e2b66 docs(chord): app kit plugins, files and export 2026-11-02 10:50:22 +00:00
Mario Zechner
dbfb5bc105 docs(chord): app kit storage 2026-11-02 10:43:09 +00:00
Mario Zechner
e8c5ac945f docs(chord): app kit command-line clients 2026-11-02 10:42:09 +00:00
Mario Zechner
09f2dac685 docs(chord): app kit authentication 2026-11-02 10:40:04 +00:00
Armin Ronacher
db6c084455 Add [Unreleased] section for next cycle 2026-11-02 11:38:21 +01:00
Armin Ronacher
f9a2636556 Release v1.5.0 2026-11-02 11:38:21 +01:00
Armin Ronacher
513f6f1ce8 fix: keep Chord example dependencies out of releases 2026-11-02 11:38:21 +01:00
Armin Ronacher
7e7c98a0f5 docs(coding-agent): note branch summary context edits 2026-11-02 11:38:20 +01:00
Mario Zechner
87f69dbf3c docs(chord): app kit principals and users 2026-11-02 10:36:42 +00:00
Mario Zechner
2dd44fb1c8 docs(chord): app kit shape 2026-11-02 10:33:06 +00:00
Mario Zechner
7edaa131dd docs(chord): testing a plugin alone 2026-11-02 10:26:25 +00:00
Mario Zechner
95e2015f3b docs(chord): single-file plugins 2026-11-02 10:22:50 +00:00
Mario Zechner
ee7f61f92c docs(chord): the plugin model's points 3, 4, 5 and 8, imports and builds 2026-11-02 10:19:47 +00:00
Armin Ronacher
ddbe02cd20 docs: audit changelogs and add release highlights 2026-11-02 11:03:52 +01:00
robopipi[bot]
d0fe213089
fix(coding-agent): apply context edits to branch summary input (#11680)
When a partial assistant reply fails and automatic retry succeeds, pi
appends a `context_edit` that hides the failed attempt from model
context. Branch summarization (`/tree` with summarize) built its input
from raw session entries through `getMessageFromEntry`, which ignored
`context_edit` entries. As a result, the summarizer received the hidden
attempt again. Content replacements were ignored the same way.

What the change does:
- `prepareBranchEntries` now collects the latest `context_edit` for each
target in the branch.
- It applies those edits to the entries it converts, using the same
`projectContextEntry` logic as the live context and compaction:
  - an omission (`replacement: null`) drops the entry;
  - a replacement swaps its content.
- `projectContextEntry` is now exported from `session-manager.ts` so
both paths share it.
- The existing branch-summary behavior is unchanged: tool results are
still skipped, and compaction or branch-summary entries still become
summary messages.

Testing:
- Added `applies context edits to branch entries` to
`test/branch-summarization.test.ts`. It covers one omitted assistant
entry and one replaced assistant entry. The test fails without the
change and passes with it.
- Ran `branch-summarization`, `branch-summary-extensions`,
`agent-session-branching` and the compaction tests: all pass.
- `npm run check`: biome and the coding-agent checks pass. `tsc` reports
6 errors in `packages/ai` model-catalog tests, and the same 6 errors
occur on unmodified `main`.
- End-to-end reproduction with the faux provider and `AgentSession`: a
failed attempt, a successful retry, then `navigateTree(target, {
summarize: true })`. Before the change, the summary request contained
the failed attempt's text. After the change, it contains only the
successful retry.

Fixes #11602

Requested by @davidbrai

Co-authored-by: triagent <triagent@localhost>
2026-11-02 10:55:30 +01:00
Mario Zechner
6ab6c1e0e4 docs(chord): plugins import only the app's versioned API 2026-11-02 09:41:22 +00:00
Mario Zechner
c9f4c7b9fc docs(chord): fold the cross-plugin import rule into design and slices 2026-11-01 23:11:22 +00:00