@robota-sdk/agent-command 3.0.0-beta.82 → 3.0.0-beta.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1044 -0
- package/dist/node/index.cjs +76 -70
- package/dist/node/index.d.cts +100 -8
- package/dist/node/index.d.cts.map +1 -1
- package/dist/node/index.d.ts +100 -8
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +76 -70
- package/dist/node/index.js.map +1 -1
- package/package.json +14 -9
- package/src/command-module-utils.test.ts +37 -0
- package/src/command-module-utils.ts +2 -0
- package/src/default/__tests__/default-command-modules.test.ts +50 -11
- package/src/default/__tests__/model-exposure.test.ts +16 -3
- package/src/default/__tests__/org-policy-forwarding.test.ts +10 -2
- package/src/default/default-command-modules.ts +7 -8
- package/src/devices/__tests__/devices-command-module.test.ts +99 -12
- package/src/devices/devices-command-module.ts +108 -24
- package/src/devices/devices-command-port.ts +62 -1
- package/src/devices/index.ts +3 -0
- package/src/doctor/doctor-node-deps.ts +6 -7
- package/src/editor/editor-command-module.ts +5 -0
- package/src/events/__tests__/events-command.test.ts +73 -0
- package/src/events/events-command-module.ts +49 -0
- package/src/events/events-command.ts +69 -0
- package/src/events/index.ts +2 -0
- package/src/git/__tests__/git-command-module.test.ts +10 -2
- package/src/handoff/__tests__/handoff-command-module.test.ts +2 -1
- package/src/handoff/handoff-command-module.ts +1 -1
- package/src/handoff/handoff-command.ts +2 -2
- package/src/help/__tests__/help-command-module.test.ts +3 -0
- package/src/help/__tests__/help-command.test.ts +3 -0
- package/src/index.ts +8 -0
- package/src/keybindings/keybindings-command-module.ts +17 -3
- package/src/mcp-activation/__tests__/mcp-activation-command.test.ts +41 -0
- package/src/mcp-activation/mcp-activation-command.ts +8 -3
- package/src/peers/__tests__/peers-command-module.test.ts +24 -0
- package/src/peers/__tests__/peers-command.test.ts +78 -0
- package/src/peers/peers-command-module.ts +1 -1
- package/src/peers/peers-command.ts +33 -4
- package/src/rewind/__tests__/rewind-command-module.test.ts +31 -1
- package/src/rewind/rewind-command.ts +23 -2
- package/src/schedule/__tests__/schedule-redos.test.ts +33 -0
- package/src/schedule/loop-command.ts +3 -1
- package/src/shell/shell-command-module.ts +5 -0
- package/src/terminal-client/__tests__/terminal-client-commands.test.ts +216 -0
- package/src/terminal-client/index.ts +5 -0
- package/src/terminal-client/terminal-client-commands.ts +109 -0
- package/src/theme/__tests__/theme-command.test.ts +1 -1
- package/src/theme/theme-command-module.ts +12 -2
- package/src/user-local/__tests__/user-local-command.test.ts +2 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1044 @@
|
|
|
1
|
+
# @robota-sdk/agent-command
|
|
2
|
+
|
|
3
|
+
## 3.0.0-beta.83
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 724fabb: External-event grants are given at start, carried exactly to a background session, listed without their
|
|
8
|
+
principal, and revoked by the owner.
|
|
9
|
+
|
|
10
|
+
- `agent-framework` (breaking) — `openExternalEventSource` and `ExternalEventIngress.open` take only
|
|
11
|
+
`{ grant, audit? }`: the session builds each grant's verifier from `grant.verifier` with the
|
|
12
|
+
`externalEventVerifierFactory` its host passed when the session was built (without one, no grant opens), and an
|
|
13
|
+
open that supplies a verifier or a factory is refused. `IExternalEventSource.revoke()` stops the grant's queued and running turns,
|
|
14
|
+
refuses its later events as `grant-revoked`, and keeps the label from being opened again. A submission the
|
|
15
|
+
session refuses is `shutting-down` only while it shuts down, and `session-unavailable` otherwise. New command
|
|
16
|
+
host adapter `externalEvents` (`ICommandExternalEventsAdapter`).
|
|
17
|
+
- `agent-ui-terminal` — forwards `externalEventVerifierFactory` from the render options to the session.
|
|
18
|
+
- `agent-interface-transport` — `TExternalEventRefusal` gains `session-unavailable`.
|
|
19
|
+
- `agent-command` — `/events` lists the session's grants (label, principal kind, state, counts) and
|
|
20
|
+
`/events revoke <grant-id>` withdraws one. User-only.
|
|
21
|
+
- `agent-cli` — a grant file (`grantId`, `issuer`, `resource` ending in `/events/<grantId>`, exactly one of
|
|
22
|
+
`subject` or `client`, `scopes`, optional `algorithms` and `rate`) is validated before anything starts, with a
|
|
23
|
+
reason that names the grant and no configured value. `robota --external-event-grant <file>` (TUI) and
|
|
24
|
+
`robota session start --background --external-event-grant <file>` open every grant or fail the start; a
|
|
25
|
+
background session receives its grants through a private file, opens them before it reports ready, and the
|
|
26
|
+
launcher refuses a readiness that names other grants. `robota session events list <id> [--json]` and
|
|
27
|
+
`robota session events revoke <id> <grant-id>` work over the generation-bound control socket, and
|
|
28
|
+
`robota session list --format json` shows each grant's counts. The retired `--external-event-allow` now points
|
|
29
|
+
at `--external-event-grant`.
|
|
30
|
+
|
|
31
|
+
- 28fa8a7: `/devices add` and `/devices join` enrol a new device into your devices.
|
|
32
|
+
|
|
33
|
+
- On a device that holds the signing key, `/devices add` shows a one-time code on the terminal. It
|
|
34
|
+
works once, for five minutes.
|
|
35
|
+
- On the new device, `/devices join [name]` asks for the code on the terminal, creates the device's
|
|
36
|
+
keys, and meets the other device through the signaling relay in
|
|
37
|
+
`transports.webrtc.options.relayUrl`. Both devices need that setting.
|
|
38
|
+
- The new device proves the code over the WebRTC connection's DTLS fingerprints before anything else
|
|
39
|
+
crosses, so a relay in the middle cannot enrol anyone.
|
|
40
|
+
- Both devices then show the same six digits, and both operators compare them and confirm. Someone
|
|
41
|
+
who saw the code cannot choose the digits: the new device commits to its part before it sees the
|
|
42
|
+
existing device's.
|
|
43
|
+
- Only when both operators say yes does the existing device certify the new one and issue a new
|
|
44
|
+
roster. The new device keeps its identity only once the chain it receives verifies.
|
|
45
|
+
- A wrong, expired or already used code is refused. So is a code after a few failed attempts. When
|
|
46
|
+
either operator declines, nothing is issued or kept.
|
|
47
|
+
- The code appears only on the two terminals. It never reaches history, transcripts or the model. A
|
|
48
|
+
code typed as a command argument is refused. Both commands stay user-only and refuse remote
|
|
49
|
+
surfaces.
|
|
50
|
+
- `agent-remote-pairing`: enrollment codes, the enrollment proof, the signed request with its
|
|
51
|
+
commitment, the short authentication string and the frame decoder.
|
|
52
|
+
- `agent-transport-webrtc`: `dialEnrollment` and `listenForEnrollment` provide a data channel bound to
|
|
53
|
+
the negotiated fingerprints.
|
|
54
|
+
|
|
55
|
+
- 4f49d14: The device mesh can be turned on, and `/peers`, `/handoff` and `/devices` reach the user's other devices.
|
|
56
|
+
|
|
57
|
+
- New user setting `transports.mesh.enabled` (default `false`). When it is `true`, an interactive
|
|
58
|
+
session opens the device mesh at startup and closes it on exit. Only the user settings count; a
|
|
59
|
+
project's settings cannot turn it on. Print and serve runs never open it, and a device without an
|
|
60
|
+
identity is told to run `/devices init`. Only one session of a device opens it at a time; another
|
|
61
|
+
session on the same device says so in `/devices` and links nothing.
|
|
62
|
+
- By default a linked device may send messages, files and sessions. Each file and each session still
|
|
63
|
+
waits for the operator's yes on this machine's terminal; with no terminal the answer is no.
|
|
64
|
+
Delegating, observing and driving stay off unless `transports.mesh.options.capabilities` lists
|
|
65
|
+
them.
|
|
66
|
+
- A message from a linked device arrives like one from a session on this host: a peer turn with no
|
|
67
|
+
authority, attributed to the device the handshake proved, under the same rate limit and
|
|
68
|
+
conversation limits.
|
|
69
|
+
- `/peers` lists linked devices beside the sessions on this host; `/peers send` and
|
|
70
|
+
`/peers send-file` take a device id. `/handoff` lists linked devices and pushes the session to one.
|
|
71
|
+
Files arrive in the usual place aside, and sessions are saved without starting.
|
|
72
|
+
- `/devices` shows whether the mesh is on, how this device finds the others, and which are linked.
|
|
73
|
+
- The mesh uses the relay at `transports.webrtc.options.relayUrl` when one is set. Without one it
|
|
74
|
+
finds devices on the local network and over the public ways in `transports.mesh.options`.
|
|
75
|
+
- `/peers`, `/handoff` and `/devices` stay user-only. Their descriptions tell the model they cover
|
|
76
|
+
linked devices.
|
|
77
|
+
- `agent-framework`: the `/peers` port can list linked devices (`listDevices`, `ILinkedDeviceSummary`).
|
|
78
|
+
- `agent-command`: the `/devices` port can report the mesh (`meshStatus`, `IDevicesMeshStatus`).
|
|
79
|
+
|
|
80
|
+
- 7b72344: Every client can offer the session's commands and skills and show its status. The GUI uses them as a
|
|
81
|
+
desktop-style composer.
|
|
82
|
+
|
|
83
|
+
- `agent-interface-session` is **`major` because `IInteractiveSession` gains required members**:
|
|
84
|
+
`ISessionCommands.listSkills()` and a `statusRead` capability, `getStatusSnapshot()`. The snapshot
|
|
85
|
+
holds session, model, permission mode, effort, context and goal. An external implementation stops
|
|
86
|
+
compiling until it adds both.
|
|
87
|
+
- `agent-transport` is **`major` for the same reason on `IProtocolSession`**. It also gains the wire
|
|
88
|
+
messages `get-commands` → `commands` and `get-status` → `session_status`. Both are reads that the
|
|
89
|
+
observe role may send.
|
|
90
|
+
- `agent-interface-command` gains `ICommandSkillListEntry`, moved from `agent-framework`, which
|
|
91
|
+
re-exports it unchanged.
|
|
92
|
+
- `agent-ui-web` is **`major` because its state changes shape**:
|
|
93
|
+
- A command's outcome and a finished turn's tool calls are now conversation entries: `messages` is
|
|
94
|
+
`TConversationEntry[]`.
|
|
95
|
+
- The `uiIntentNotices` list, `dismissUiIntentNotice`, `applyUiIntentEvent`,
|
|
96
|
+
`removeUiIntentNotice` and `IUiIntentNotice` are removed. An intent now answers with an info
|
|
97
|
+
line in the conversation.
|
|
98
|
+
- Session notices keep only `session-error` and `protocol-error`.
|
|
99
|
+
- The state gains `commandCatalog` and `sessionStatus`.
|
|
100
|
+
- `agent-command` registers `/theme` and `/keybindings` even without a terminal. They then answer
|
|
101
|
+
that they belong to the robota terminal, instead of being unknown.
|
|
102
|
+
- `agent-framework`:
|
|
103
|
+
- `InteractiveSession.getStatusSnapshot()`.
|
|
104
|
+
- The main-thread row previews the last chat message instead of the last record's type.
|
|
105
|
+
- `agent-cli` serves the full GUI web app, renamed from `agent-cli-web` to `agent-gui-web`, on
|
|
106
|
+
`robota --serve --open`.
|
|
107
|
+
|
|
108
|
+
- 9721162: The command catalog says who runs a command, and which surfaces can run it.
|
|
109
|
+
|
|
110
|
+
- **`agent-interface-command` (major).**
|
|
111
|
+
- Adds `TCommandRunner` (`'runtime' | 'client'`) and `TCommandSurface` (`'terminal' | 'gui'`).
|
|
112
|
+
- `ICommand` gains optional `runner` and `surfaces`.
|
|
113
|
+
- `ICommandListEntry` gains optional `surfaces` and a **required** `runner`. An implementation of `listCommands()`, or any code that constructs an `ICommandListEntry`, must now emit `runner`; a command that declares none gets `'runtime'`.
|
|
114
|
+
- **`agent-framework` (minor).**
|
|
115
|
+
- `ISystemCommand` gains optional `runner` and `surfaces`, and the command listing carries both.
|
|
116
|
+
- An undeclared runner resolves to `'runtime'`.
|
|
117
|
+
- `SessionTerminalHandoffGate` is exported for a terminal client that hands its own terminal to a command.
|
|
118
|
+
- **`agent-command` (minor).**
|
|
119
|
+
- `/shell`, `/editor`, `/theme` and `/keybindings` declare `runner: 'client'` and `surfaces: ['terminal']`.
|
|
120
|
+
- `createTerminalClientCommands()` builds the same four commands, from the same execute functions, for a terminal client to run itself. The set follows the preset's module selection.
|
|
121
|
+
- **`agent-ui-web` (minor).** The `/` menu marks a command that runs in the terminal with a "terminal" badge.
|
|
122
|
+
|
|
123
|
+
### Patch Changes
|
|
124
|
+
|
|
125
|
+
- 4241fc5: Device mesh follow-ups.
|
|
126
|
+
|
|
127
|
+
- A device with no identity is pointed to `/devices add` on one of the user's devices and `/devices join`
|
|
128
|
+
here, as well as to `/devices init`. The message says that `init` is for the first device only,
|
|
129
|
+
because it creates a separate identity that can never link to the user's other devices. The `/devices`
|
|
130
|
+
description and the `init` subcommand say the same.
|
|
131
|
+
- An identity created mid-session (`/devices init`, or a successful `/devices join`) opens the mesh
|
|
132
|
+
without a restart when `transports.mesh.enabled` is on.
|
|
133
|
+
- If a session stalls for longer than the mesh lock's stale window (for example while the machine
|
|
134
|
+
sleeps), another session can take the mesh over. The stalled session now notices this on its next
|
|
135
|
+
lock refresh, closes its own mesh, and says why. Two sessions no longer run it together.
|
|
136
|
+
`holdExclusiveFileLock` has a new `onLost` option for this.
|
|
137
|
+
- `/peers` and `/handoff` still list and reach linked mesh devices when local same-host peer discovery
|
|
138
|
+
fails. `/peers` says why sessions on this host are not listed. `ICommandLocalPeersAdapter` has a new
|
|
139
|
+
optional `localDiscoveryOff` field for this.
|
|
140
|
+
- `agent-transport-webrtc`: when lists become newer on a node (reissued, revoked, or adopted from a
|
|
141
|
+
peer), the node sends them over every admitted connection instead of waiting for the next handshake.
|
|
142
|
+
Reissues, revocations and enrolments in the CLI take effect this way at once. A receiver adopts a
|
|
143
|
+
pushed list only if it is newer, issued by this user's signing key, and verifies. The push does not
|
|
144
|
+
depend on the peer's capabilities, and it never reaches the application's message handlers.
|
|
145
|
+
|
|
146
|
+
- 57280bf: Every published package now declares `"engines": { "node": ">=22.12.0" }`. Before, 27 of the 38
|
|
147
|
+
packages declared no floor (`agent-core`, `agent-tools` and every provider among them),
|
|
148
|
+
`agent-session` and `agent-file-authority` declared `>=20.19.0`, and the other nine declared
|
|
149
|
+
`>=22.0.0`, so a consumer on Node 20 saw at most a warning from a transitive dependency.
|
|
150
|
+
|
|
151
|
+
Why 22.12: `agent-cli` and `agent-ui-terminal` need Node 22 through `ink` 7, and the CommonJS entries
|
|
152
|
+
of `agent-tools` and its dependents, `agent-transport`/`node` and its dependents, and
|
|
153
|
+
`agent-ui-terminal` `require()` ESM-only dependencies (`p-limit`, `jose`, `chalk`), which Node 22
|
|
154
|
+
supports unflagged only from 22.12. `engines` is advisory unless the consumer enables `engine-strict`.
|
|
155
|
+
|
|
156
|
+
No code changes: `tsdown` now reads `node22.12.0` as its build target from the field.
|
|
157
|
+
|
|
158
|
+
- 18c0d5c: Every published package now exports `./package.json`, so `require('<package>/package.json')` and
|
|
159
|
+
`import('<package>/package.json', { with: { type: 'json' } })` work instead of failing with
|
|
160
|
+
`ERR_PACKAGE_PATH_NOT_EXPORTED`, and each tarball now ships the package's `CHANGELOG.md`.
|
|
161
|
+
- caaab20: `/rewind` works again. Every session the CLI builds for a trusted workspace captures edit
|
|
162
|
+
checkpoints; before, none did, and `/rewind` failed everywhere with "Edit checkpoints require
|
|
163
|
+
project authority."
|
|
164
|
+
|
|
165
|
+
- `agent-cli` (patch): a trusted workspace composes an edit checkpoint store for the terminal UI, a
|
|
166
|
+
print run, a served runtime and each session a daemon keeps live. Every session gets its own
|
|
167
|
+
store, pooled or switched to in the terminal UI, since two can run turns at the same time. On a host that cannot prove a project write
|
|
168
|
+
stays inside the project (every platform but Linux), none is composed: a checkpoint could be
|
|
169
|
+
neither saved nor restored there.
|
|
170
|
+
- `agent-command` (patch): where a session has no checkpoints, `/rewind` says why: a restricted
|
|
171
|
+
workspace is told to run `robota trust --yes` and restart robota, and a host that cannot write
|
|
172
|
+
the project safely says so. `/rewind list` reports this as a failed command instead of throwing.
|
|
173
|
+
- `agent-framework` (minor): a checkpoint operation on a session without a store throws
|
|
174
|
+
`EditCheckpointsUnavailableError`, whose `reason` is `host-cannot-write-project`,
|
|
175
|
+
`restricted-workspace` or `no-checkpoint-store`. It is a `WorkspaceAuthorityRequiredError`, as
|
|
176
|
+
before, named `EditCheckpointsUnavailableError`. `HeadlessInteractionChannel` takes an
|
|
177
|
+
`editCheckpointStore` option.
|
|
178
|
+
- `agent-ui-terminal` (minor): `renderApp` takes `createEditCheckpointStore` in place of
|
|
179
|
+
`editCheckpointStore`, and builds each session its own store, since a session switch can build the
|
|
180
|
+
next session before the old one's turn ends. `TuiInteractionChannel` keeps `editCheckpointStore`:
|
|
181
|
+
a channel runs one session.
|
|
182
|
+
|
|
183
|
+
- Updated dependencies [3c81769]
|
|
184
|
+
- Updated dependencies [724fabb]
|
|
185
|
+
- Updated dependencies [997f2fb]
|
|
186
|
+
- Updated dependencies [bfe8ed5]
|
|
187
|
+
- Updated dependencies [e689c8e]
|
|
188
|
+
- Updated dependencies [4241fc5]
|
|
189
|
+
- Updated dependencies [4f49d14]
|
|
190
|
+
- Updated dependencies [7b72344]
|
|
191
|
+
- Updated dependencies [6ae3f28]
|
|
192
|
+
- Updated dependencies [9721162]
|
|
193
|
+
- Updated dependencies [be0e53c]
|
|
194
|
+
- Updated dependencies [57f57f5]
|
|
195
|
+
- Updated dependencies [ba822c1]
|
|
196
|
+
- Updated dependencies [9721162]
|
|
197
|
+
- Updated dependencies [6e6b06b]
|
|
198
|
+
- Updated dependencies [7d77ce4]
|
|
199
|
+
- Updated dependencies [8bd5fac]
|
|
200
|
+
- Updated dependencies [57280bf]
|
|
201
|
+
- Updated dependencies [5033dd9]
|
|
202
|
+
- Updated dependencies [18c0d5c]
|
|
203
|
+
- Updated dependencies [dbd888d]
|
|
204
|
+
- Updated dependencies [1887e54]
|
|
205
|
+
- Updated dependencies [caaab20]
|
|
206
|
+
- Updated dependencies [f01868f]
|
|
207
|
+
- Updated dependencies [e8779c9]
|
|
208
|
+
- Updated dependencies [5a0ee96]
|
|
209
|
+
- @robota-sdk/agent-framework@3.0.0-beta.83
|
|
210
|
+
- @robota-sdk/agent-core@3.0.0-beta.83
|
|
211
|
+
- @robota-sdk/agent-interface-session@3.0.0-beta.83
|
|
212
|
+
- @robota-sdk/agent-interface-command@3.0.0-beta.83
|
|
213
|
+
- @robota-sdk/agent-interface-execution@3.0.0-beta.83
|
|
214
|
+
- @robota-sdk/agent-preset@3.0.0-beta.83
|
|
215
|
+
|
|
216
|
+
## 3.0.0-beta.82
|
|
217
|
+
|
|
218
|
+
### Minor Changes
|
|
219
|
+
|
|
220
|
+
- c7f9203: Connected sessions can send each other files.
|
|
221
|
+
|
|
222
|
+
- `/peers send-file <session-id> <path>` sends a copy of any file the operator can read to another
|
|
223
|
+
live session on this host.
|
|
224
|
+
- The model sends a file only through the `peer_send_file` tool. Every call asks the user, showing
|
|
225
|
+
the path, size, hash and destination; no permission mode, rule or remembered consent answers it.
|
|
226
|
+
The tool reaches only files inside the workspace whose path does not look like it holds secrets
|
|
227
|
+
(`.env*`, `~/.ssh`, keys and credentials), and it does not exist in a turn a peer's message started.
|
|
228
|
+
- The receiving operator approves every file. A received file is kept as an inert copy (mode 0600)
|
|
229
|
+
under `~/.robota/peer-files/<sender>/`. It is never run and never placed in the model's context.
|
|
230
|
+
The conversation is told only its name, size and sha256. A name that leaves that directory is
|
|
231
|
+
refused, a symbolic link is never written through, and nothing is overwritten.
|
|
232
|
+
- Transfers travel on a channel of their own (a separate connection on this host, a separate data
|
|
233
|
+
channel between devices), in chunks the receiver paces, up to 32 MiB, and are kept only when the
|
|
234
|
+
whole content matches the offered sha256. A transfer that ends early is discarded; there is no
|
|
235
|
+
resume.
|
|
236
|
+
|
|
237
|
+
**API**
|
|
238
|
+
|
|
239
|
+
- `agent-interface-session-mobility`: the `file` capability, which asks the operator for every
|
|
240
|
+
request; `ConnectionAuthority.authorizeFile`; `IFileOffer` and `IFileFrameChannel`.
|
|
241
|
+
- `agent-transport/node`: `sendFileOverChannel` and `receiveFileOverChannel`, the carrier over any
|
|
242
|
+
`IFileFrameChannel`; `DEFAULT_MAX_FILE_BYTES`.
|
|
243
|
+
- `agent-transport-webrtc`: `IDeviceMeshLink.openFileChannel` and `onFileChannel`.
|
|
244
|
+
- `agent-remote-pairing`: `file` joins `DEVICE_CAPABILITIES`. A device certificate that names it is
|
|
245
|
+
refused as malformed by an earlier version.
|
|
246
|
+
- `agent-core`: `IToolPermissionProfile.notInPeerTurn` withholds a tool from a turn a peer's message
|
|
247
|
+
started.
|
|
248
|
+
- `agent-framework`: `ICommandLocalPeersAdapter.prepareFile`.
|
|
249
|
+
|
|
250
|
+
- 004fe7f: `/handoff` moves a session over a real connection.
|
|
251
|
+
|
|
252
|
+
- `/handoff <session-id>` pushes this conversation to another Robota session on this machine. The
|
|
253
|
+
same carrier also runs between two of the user's devices over their mesh connection; no command
|
|
254
|
+
opens that connection yet.
|
|
255
|
+
- A hand-off is push-only: only the operator of the session that holds it starts one. A session or
|
|
256
|
+
device that asks another for its session is refused.
|
|
257
|
+
- The source signs a grant for that one transfer over that one channel with its device key, so a
|
|
258
|
+
hand-off needs the device identity from `/devices init`. The receiving side checks it against the
|
|
259
|
+
sender's certificate, then asks its own operator; without a yes nothing is sent.
|
|
260
|
+
- The session travels on the file-transfer carrier, is kept aside until it matches the manifest, and
|
|
261
|
+
is saved without being started. The operator there resumes it with `robota --resume <id>`.
|
|
262
|
+
- The source gives the session up, and ends, only once the receiving side confirms it saved it.
|
|
263
|
+
Every other outcome leaves the session where it was; if the confirmation is lost, `/handoff` to the
|
|
264
|
+
same session again resends the same transfer, which the receiver settles without saving it twice.
|
|
265
|
+
Peer attribution (`driverId`, `turnSource`)
|
|
266
|
+
travels with it.
|
|
267
|
+
- `/handoff` stays user-only. Its description tells the model to suggest the command to the user.
|
|
268
|
+
- `agent-transport-webrtc`: an admitted mesh link exposes the DTLS fingerprints it is bound to, and
|
|
269
|
+
`judgeHandoffGrant` is exported.
|
|
270
|
+
- `agent-interface-session-mobility`: a hand-off carrier may move the sealed payload whole
|
|
271
|
+
(`sendPayload`), the destination verifies it with `receivePayload`, and the source can report its
|
|
272
|
+
open transfer (`status`) and abandon it for any refusal the destination names.
|
|
273
|
+
|
|
274
|
+
### Patch Changes
|
|
275
|
+
|
|
276
|
+
- e15e22b: Two of one user's devices can connect to each other over WebRTC, admitted by the device handshake.
|
|
277
|
+
|
|
278
|
+
- `agent-transport-webrtc` — `DeviceMeshNode` keeps one connection per device pair, in either role: the
|
|
279
|
+
device with the lower id offers and the other answers, so concurrent attempts resolve by rule. Both
|
|
280
|
+
roles bind the handshake to the certificate the DTLS layer verified and take one remote description
|
|
281
|
+
with exactly one fingerprint; before admission only handshake frames cross, and a connection counts
|
|
282
|
+
as admitted only once both sides admitted each other. Each connection gets its own DTLS certificate
|
|
283
|
+
(`createDtlsKeys`). A new attempt never displaces an admitted connection until it is admitted
|
|
284
|
+
itself, and attempts per pair are paced. Lists adopted in a handshake, or handed over through
|
|
285
|
+
`refresh`, apply at once, and a device they revoke loses its connection. Signaling runs through
|
|
286
|
+
`IMeshRelay`: `WsMeshRelayClient` for the self-hosted relay's `presence` / `message` frames
|
|
287
|
+
(topics capped per source and relay-wide), `createInMemoryMeshRelayHub` for tests.
|
|
288
|
+
- `agent-remote-pairing` — the pair's two relay inbox topics, one per direction, come from their
|
|
289
|
+
pairwise secret (`derivePairRendezvous(...).relayInbox()`).
|
|
290
|
+
- `agent-cli` — a device holding the signing key reissues its roster and revocation list before they
|
|
291
|
+
expire while an interactive session runs. The host can open this device's mesh endpoint from the
|
|
292
|
+
identity under `~/.robota/devices`, saving newer lists a peer hands over; no command starts it yet.
|
|
293
|
+
- `agent-command` — `/devices add|join` still reports that enrolment is not available yet.
|
|
294
|
+
|
|
295
|
+
- Updated dependencies [c7f9203]
|
|
296
|
+
- @robota-sdk/agent-core@3.0.0-beta.82
|
|
297
|
+
- @robota-sdk/agent-framework@3.0.0-beta.82
|
|
298
|
+
- @robota-sdk/agent-interface-command@3.0.0-beta.82
|
|
299
|
+
- @robota-sdk/agent-interface-execution@3.0.0-beta.82
|
|
300
|
+
- @robota-sdk/agent-interface-session@3.0.0-beta.82
|
|
301
|
+
- @robota-sdk/agent-preset@3.0.0-beta.82
|
|
302
|
+
|
|
303
|
+
## 3.0.0-beta.81
|
|
304
|
+
|
|
305
|
+
### Minor Changes
|
|
306
|
+
|
|
307
|
+
- 44fc732: Add `/devices` for this device's identity among the user's devices: `list`, `init` (creates the identity: a recovery phrase, the master-certified signing key, this device's keys and certificate, the first roster and revocation list), `revoke <device-id>` (signing key only, no phrase; confirmed at the terminal) and `recover` (rotates the signing key from the phrase and revokes the old ones). Enrolling another device (`add` / `join`) comes with the device connection.
|
|
308
|
+
|
|
309
|
+
The recovery phrase never enters the session: it is shown once and read with no echo on the controlling terminal (opened apart from the session's input), on the alternate screen that is cleared afterwards, and never reaches prompt history, conversation history, transcripts, traces or the model. Without an interactive terminal the phrase commands refuse. `/devices` is operator-only: never model-invocable and refused from remote surfaces. Private keys live in the host credential store; certificates, roster, revocation lists and sequence marks are kept in owner-only files under `~/.robota/devices`.
|
|
310
|
+
|
|
311
|
+
`agent-remote-pairing` adds `isRecoveryPhraseWord`, so a phrase can be checked one word at a time.
|
|
312
|
+
|
|
313
|
+
- 18b52cc: Built-in commands are offered to the model deliberately, each described for the model, and never
|
|
314
|
+
with a trust, credential or permission-widening action.
|
|
315
|
+
|
|
316
|
+
- `agent-interface-command` — `ICommand` gains `modelDescription?` (what the model is told, beside the
|
|
317
|
+
short `/help` line), and `modelInvocable` on a subcommand entry now narrows what the model may run.
|
|
318
|
+
- `agent-framework` — `ISystemCommand` gains `modelDescription?` and `modelRequiresPermission?`.
|
|
319
|
+
Once any subcommand of a model-invocable command declares `modelInvocable`, the model may run only
|
|
320
|
+
the bare command and the subcommands declared `true`; everything else, including an alias or an
|
|
321
|
+
undeclared subcommand, is refused before the command runs. The model-facing descriptor lists only
|
|
322
|
+
that subset. A model-requested monitor's command is now decided by the shell tool's gate (its
|
|
323
|
+
Bash/Shell rules, the mode and the prompt) and a refusal rejects with the new
|
|
324
|
+
`MonitorCommandRefusedError`. The `scriptedSession` test harness accepts `permissions` patterns.
|
|
325
|
+
- `agent-session` — `Session.checkToolPermission(toolName, toolArgs)` decides an action that has a
|
|
326
|
+
tool's effect by another route: that tool's PreToolUse hooks, then the gate's rules, mode,
|
|
327
|
+
remembered consent and prompt — never the command sandbox's auto-approval, since the action does
|
|
328
|
+
not run inside the sandbox.
|
|
329
|
+
- `agent-framework` also: `ICommandMCPActivationAdapter.userActionSurface?` tells `/mcp` whether the
|
|
330
|
+
user can type a session command, so the model's status names the terminal sign-in otherwise.
|
|
331
|
+
- `agent-command` — `/context` (bare and `list`), `/cost` (the report, not `budget`) and `/mcp`
|
|
332
|
+
(`status` only, without a prompt) are now model-invocable; `/memory approve` and `/memory reject`
|
|
333
|
+
are now user-only; the model's `/monitor` is decided by the shell gate rather than by consent to
|
|
334
|
+
the command's name. Every model-invocable command carries a model-facing description. The model's
|
|
335
|
+
`/mcp status` shows only safe names, states and the command to suggest, and a caller that does not
|
|
336
|
+
identify itself gets that view. `/context list` accounts only for turns still in context. New
|
|
337
|
+
`mcpUserActionNotice`, `mcpUserActionCommand` and `mcpUnavailableServersNotice` build the fixed
|
|
338
|
+
notices.
|
|
339
|
+
- `agent-command-workflows` — `/workflows` carries a model-facing description.
|
|
340
|
+
- `agent-mcp` — `createDiscoveredTool` accepts `authFailureNotice`: a call the server refuses for
|
|
341
|
+
authentication returns that host text instead of the generic failure.
|
|
342
|
+
- `agent-cli` — an MCP server that did not start because the user must approve it, trust the
|
|
343
|
+
workspace or sign in is named to the model at the start of an interactive session with the
|
|
344
|
+
command to suggest, and a
|
|
345
|
+
signed-in OAuth server that refuses a call tells the model to suggest `/mcp login <server>` — or, in print and serve runs, the terminal
|
|
346
|
+
`robota mcp login <server>`.
|
|
347
|
+
|
|
348
|
+
A command whose bare form is a complete action declares `runsBare`, so choosing `/cost` or `/mcp`
|
|
349
|
+
from the autocomplete menu still runs it even though they now declare subcommands.
|
|
350
|
+
|
|
351
|
+
- 9843fe6: Sign in to a remote MCP server from inside a session, and use its tools without restarting.
|
|
352
|
+
|
|
353
|
+
- **`/mcp login <server> [--no-browser]`** runs the same per-server OAuth sign-in as
|
|
354
|
+
`robota mcp login` (discovery checks, PKCE, `state`, RFC 9207 `iss`, RFC 8707 resource, the
|
|
355
|
+
loopback listener, the lock-guarded store). It opens the browser through the argv opener; with
|
|
356
|
+
`--no-browser`, or when no browser can be opened, it shows the authorization URL and asks for the
|
|
357
|
+
redirect URL in the session's own prompt (masked), held to the same rules as a pasted redirect in
|
|
358
|
+
the terminal. A failed, refused, timed-out or cancelled sign-in changes nothing and is reported by
|
|
359
|
+
a fixed reason only. `/mcp login <server> --client-secret` is refused: a secret is never typed into
|
|
360
|
+
a session, and `robota mcp login <server> --client-secret` is named instead (also after a failed
|
|
361
|
+
token exchange for a pre-registered client). `/mcp` stays user-only (`modelInvocable: false`).
|
|
362
|
+
- **Connected in the same session:** after a sign-in, a server that could not connect for want of
|
|
363
|
+
one goes through the normal admission (approval, fingerprint, trust) and connects, and its tools
|
|
364
|
+
are offered from the next message; a server that was already connected is admitted again and
|
|
365
|
+
reconnects, and its authenticator drops what it held and reads the new credential. A tool left out
|
|
366
|
+
because the session already has its name is reported, and only tools actually added get
|
|
367
|
+
provenance. In browser mode the authorization URL is shown in the session prompt before the
|
|
368
|
+
browser opens, where the user can also choose to paste the redirect instead or cancel.
|
|
369
|
+
- **`runMCPOAuthLogin`** takes `readRedirectWhenBrowserFails`: when `openBrowser` rejects, the
|
|
370
|
+
loopback listener stops and the pasted redirect is read instead, for the same redirect URI. The
|
|
371
|
+
loopback listener's time limit now runs from its first `wait()` — once the authorization page is
|
|
372
|
+
handed over — so time spent at a prompt before the browser opens does not count against it.
|
|
373
|
+
- **`Session.addTools`** (and `ICommandSessionTools.addTools`) offers tools that became usable
|
|
374
|
+
mid-session, through the same permission gate and — via `ISessionOptions.wrapAddedTools`, which
|
|
375
|
+
`createSession` sets — the same edit-checkpoint and reversible-execution wraps as the assembled
|
|
376
|
+
tools. A name the session already has is left out, never replaced. Calls are serialized, and tools
|
|
377
|
+
added while a turn runs are applied when the next turn starts, so a turn's rounds all see one
|
|
378
|
+
tool list and the prompt cache misses once, at that boundary.
|
|
379
|
+
- **Breaking (`agent-framework`, major):** `addTools` is a new required member of the
|
|
380
|
+
`ICommandSessionTools` role port (and so of `ICommandSessionRuntime`). A host that implements the
|
|
381
|
+
port itself must add it; one that passes an `agent-session` `Session` already has it.
|
|
382
|
+
- **`ICommandMCPActivationAdapter.oauthLogin`** (`ICommandMCPOAuthLoginRequest`,
|
|
383
|
+
`ICommandMCPOAuthLoginResult`, `ICommandMCPOAuthRedirectPrompt`) is the port behind it.
|
|
384
|
+
- The sign-in notice and `/mcp status` now suggest `/mcp login <server>` in a session and
|
|
385
|
+
`robota mcp login <server>` in a terminal; the server's name is shown only when it is safe to paste
|
|
386
|
+
into any shell, otherwise `<server>`.
|
|
387
|
+
|
|
388
|
+
### Patch Changes
|
|
389
|
+
|
|
390
|
+
- ec5e477: Add a credential store port (`ICredentialStore` in `agent-core`) and keep the CLI's secrets behind it: the OS keychain through the optional `@napi-rs/keyring` binding (macOS Keychain, Windows Credential Manager, Linux Secret Service), else an owner-only file under `~/.robota/credentials`. The backend is chosen at first use, recorded, and named by `/remote-control status`; a recorded keychain that stops working fails closed instead of degrading to the file.
|
|
391
|
+
|
|
392
|
+
The remote-control host identity key moves into the store. The old `~/.robota/remote-host-identity.json` may have been copied by backups or dotfile sync, so it is not carried over: on the first run after upgrading a new host key is generated, the old file is removed, and the operator is told once that trusted devices must pair again.
|
|
393
|
+
|
|
394
|
+
- 007fd90: Authority per connection: pairing stays with the local operator, and driving needs the operator's yes.
|
|
395
|
+
|
|
396
|
+
- `agent-interface-session-mobility` — `ConnectionAuthority` decides what one connection may do.
|
|
397
|
+
`presence` and `message` are allowed; `delegate` and `handoff` ask the receiving operator for every
|
|
398
|
+
request; `observe` and `drive` ask once per connection. With no `IOperatorApprover` the answer is
|
|
399
|
+
no. `authorizeDelegation` turns an approved task into a peer turn from where admission placed the
|
|
400
|
+
peer, ignoring anything else on the request, so the receiver's policy decides what it may do.
|
|
401
|
+
- `agent-transport-webrtc` — `connectionApproval` asks the operator before a connection reaches the
|
|
402
|
+
session, after every proof has run. Frames the peer sends meanwhile are held (bounded) and delivered
|
|
403
|
+
only after a yes. A channel that closes first withdraws the question (the approval context carries
|
|
404
|
+
an `AbortSignal`), and a later answer admits nothing. A first-pairing device is pinned for
|
|
405
|
+
reconnect only once it is admitted.
|
|
406
|
+
- `agent-command` — `/remote-control enable` and `revoke` from a connected surface are refused, and
|
|
407
|
+
`status` never shows a connected surface the pairing link.
|
|
408
|
+
- `agent-framework` — the `remote-control-enable` host action runs only for the operator's own
|
|
409
|
+
command, whichever command asked for it.
|
|
410
|
+
- `agent-cli` — every remote-control connection, a returning trusted device included, is put to the
|
|
411
|
+
operator on the host terminal; without an interactive terminal it is refused.
|
|
412
|
+
|
|
413
|
+
- Updated dependencies [3038eb7]
|
|
414
|
+
- Updated dependencies [02b7452]
|
|
415
|
+
- Updated dependencies [ec5e477]
|
|
416
|
+
- Updated dependencies [007fd90]
|
|
417
|
+
- Updated dependencies [18b52cc]
|
|
418
|
+
- Updated dependencies [9843fe6]
|
|
419
|
+
- @robota-sdk/agent-core@3.0.0-beta.81
|
|
420
|
+
- @robota-sdk/agent-interface-session@3.0.0-beta.81
|
|
421
|
+
- @robota-sdk/agent-framework@3.0.0-beta.81
|
|
422
|
+
- @robota-sdk/agent-interface-command@3.0.0-beta.81
|
|
423
|
+
- @robota-sdk/agent-interface-execution@3.0.0-beta.81
|
|
424
|
+
- @robota-sdk/agent-preset@3.0.0-beta.81
|
|
425
|
+
|
|
426
|
+
## 3.0.0-beta.80
|
|
427
|
+
|
|
428
|
+
### Major Changes
|
|
429
|
+
|
|
430
|
+
- 64ba748: **BREAKING — ARCH-042: project filesystem access is now an explicit, host-issued authority instead of an ambient consequence of `cwd`.**
|
|
431
|
+
|
|
432
|
+
`@robota-sdk/agent-framework` adds `WorkspaceTrustService` and the opaque
|
|
433
|
+
`IWorkspaceProjectAuthority`, plus bounded reader, settings-writer, state-storage, and mutation
|
|
434
|
+
facets. Public session, settings, context, checkpoint, memory, contribution, query, and replay
|
|
435
|
+
contracts consume those facets. A caller that does not supply `projectAccess` is deliberately
|
|
436
|
+
restricted to user-owned host state and receives no project filesystem capability.
|
|
437
|
+
|
|
438
|
+
The framework removes or renames ambient Node/project exports. Migrate `checkSettingsFile` to
|
|
439
|
+
`checkNodeHostSettingsFile`, `readMergedProviderSettingsFromPaths` to
|
|
440
|
+
`readMergedProviderSettingsFromSources`, `resolveProviderSettingsWriteTargetPath` to
|
|
441
|
+
`resolveProviderSettingsWriteTarget`, `FileSystemMemoryStore` / `createFileSystemMemoryStore` to
|
|
442
|
+
`WorkspaceMemoryStore` / `createWorkspaceMemoryStore`, and `PluginSettingsStore` to
|
|
443
|
+
`NodeHostPluginSettingsStore`. Host-only git helpers now carry the `FromNodeHost` suffix.
|
|
444
|
+
`projectPaths`, `resolveSettingsPathForScope`, and `getProviderSettingsPaths` are removed; project
|
|
445
|
+
consumers must use the authority facets rather than recover absolute paths.
|
|
446
|
+
|
|
447
|
+
`@robota-sdk/agent-session` renames the Node filesystem implementation `SessionStore` to
|
|
448
|
+
`NodeSessionStore` and adds explicit session-log/external-payload source and sink ports. Session
|
|
449
|
+
replay no longer resolves external payload files from an ambient directory.
|
|
450
|
+
|
|
451
|
+
`@robota-sdk/agent-interface-transport` changes `ISkillExecutionPort.loadCommands(cwd, home?)` to
|
|
452
|
+
the authority-bound `loadCommands()` and removes the optional absolute-path leak
|
|
453
|
+
`IInteractiveSessionStore.getFilePath`. `@robota-sdk/agent-command` consequently replaces the
|
|
454
|
+
`cwd` option of `createSkillsCommandModule` with required `contributionSources`; default command
|
|
455
|
+
composition accepts explicit contribution sources and discovers no project skills when none are
|
|
456
|
+
provided.
|
|
457
|
+
|
|
458
|
+
`@robota-sdk/agent-cli`, `@robota-sdk/agent-transport`, and
|
|
459
|
+
`@robota-sdk/agent-transport-tui` thread the trusted-or-restricted project decision through every
|
|
460
|
+
session surface. Embedded callers that need project settings, state, context, skills, checkpoints,
|
|
461
|
+
or mutation must mint access through `WorkspaceTrustService` and pass the returned
|
|
462
|
+
`projectAccess` (and a separately approved mutation/settings facet where required). Omitting it is
|
|
463
|
+
still type-compatible but is behaviorally breaking: the surface now fails closed instead of
|
|
464
|
+
reading or writing the current directory.
|
|
465
|
+
|
|
466
|
+
### Minor Changes
|
|
467
|
+
|
|
468
|
+
- 9c19c50: `/fork [name] [--same-dir]` copies the live conversation into a background session.
|
|
469
|
+
|
|
470
|
+
The session writes a copy of its own record under a fresh id — messages, system prompt, tool schemas
|
|
471
|
+
and full history, and deliberately not the sandbox snapshot, goal, plan or branch — then spawns a
|
|
472
|
+
background job carrying only `resumeSessionId`. The child restores that record itself, so no
|
|
473
|
+
conversation crosses the child-process boundary and the worker start payload's key set is unchanged.
|
|
474
|
+
The background panel gains an `attach` control that switches the terminal onto the forked session; it
|
|
475
|
+
is a view switch, never a merge, and a missing record or a terminal task is refused with the task's
|
|
476
|
+
own status.
|
|
477
|
+
|
|
478
|
+
**`@robota-sdk/agent-framework` is `major` for one reason: `ICommandHostSessionAccess` gains a
|
|
479
|
+
required member.** `forkSession({ name? })` is not optional, so an external implementation of that
|
|
480
|
+
role port stops compiling until it adds the method. Every other change in this set is additive:
|
|
481
|
+
|
|
482
|
+
- `agent-interface-execution` — `TExecutionControl` gains `'attach'`.
|
|
483
|
+
- `agent-interface-command` — `TCommandUiIntent` gains `{ type: 'switch-session'; sessionId }`.
|
|
484
|
+
- `agent-subagent-runner` — `ISubagentWorkerComposition` gains the optional `openSessionStore`, and
|
|
485
|
+
the worker resumes a record when the job names one. A composition that registers no store and
|
|
486
|
+
receives no `resumeSessionId` behaves exactly as before.
|
|
487
|
+
- `agent-framework` also gains the fork-record builder, `SessionTurnMemory`, and
|
|
488
|
+
`IAgentBackgroundTaskRequest.resumeSessionId?`; `loadSessionRecord` now returns
|
|
489
|
+
`restoredSystemPrompt`, which makes a record field that was written and never read take effect on
|
|
490
|
+
restore.
|
|
491
|
+
- `agent-executor`, `agent-command`, `agent-transport-tui`, `agent-cli` — the spawn input, the
|
|
492
|
+
`/fork` module and the attach control that carry it to the surface.
|
|
493
|
+
|
|
494
|
+
- 9368d00: Advisor escalation: the main model can consult a second model at the decision points it chooses.
|
|
495
|
+
|
|
496
|
+
With an advisor configured (`--advisor <profile>[:<model>]`, or the `advisorModel` setting that
|
|
497
|
+
`/advisor` saves; the flag wins), the session gets an `Advisor({ question? })` tool. The advisor reads
|
|
498
|
+
the whole conversation — system prompt, messages, tool calls and results — serialized into one prompt
|
|
499
|
+
and sent with `toolChoice: 'none'`, truncated from the front to fit its window with the system prompt
|
|
500
|
+
kept, and declines when even that does not fit. Its answer comes back framed as guidance to verify;
|
|
501
|
+
an empty or refusing answer reads as declined. Calls are limited to two per turn and a fixed number
|
|
502
|
+
per session, parallel calls in one round share those limits, and a repeated question in the same
|
|
503
|
+
turn returns the earlier answer. A request that was sent counts even when the provider failed (the
|
|
504
|
+
decline is reported by class, never by its text); only a call declined before sending gives its slot
|
|
505
|
+
back.
|
|
506
|
+
|
|
507
|
+
Advisor usage, including in-process subagents', is recorded where each turn's usage is recorded —
|
|
508
|
+
the persisted session history, under the advisor's own provider and model — so `/cost`, usage reports
|
|
509
|
+
and resumed sessions include it. `/cost` now totals that history and prices each part on its own
|
|
510
|
+
model, showing "mixed" when more than one model was priced.
|
|
511
|
+
|
|
512
|
+
`/advisor <model>` and `/advisor off` change only where calls go, never the tool list, so the main
|
|
513
|
+
model's prompt cache is not invalidated mid-session; the tool is added only when a session starts
|
|
514
|
+
with an advisor. Sending history to a destination (provider type and endpoint host) the main model
|
|
515
|
+
does not already use needs a one-time consent per destination, kept in the user settings file; a
|
|
516
|
+
refusal is remembered for the session. The organization's `allowedProviders` applies, and
|
|
517
|
+
`ROBOTA_DISABLE_ADVISOR=1` turns it off completely. In-process subagents inherit the advisor, bound
|
|
518
|
+
to their own conversation; child-process subagents do not get it.
|
|
519
|
+
|
|
520
|
+
**`@robota-sdk/agent-framework` is `major` for one reason: `ICommandHostSessionAccess` gains a
|
|
521
|
+
required member,** `getSessionUsage()`, the session's persisted usage records. An external
|
|
522
|
+
implementation of that role port stops compiling until it adds the method. The rest is additive.
|
|
523
|
+
|
|
524
|
+
- `agent-session` — `formatConversationEntries`, the one text rendering of a conversation, now used
|
|
525
|
+
by compaction too. It keeps tool calls and results, marks a user message a peer session sent
|
|
526
|
+
(`user [from "peer:<id>"]`), and JSON-encodes every message onto one line so no content can forge
|
|
527
|
+
another entry; compaction previously flattened all of this. `Session.getProvider()` returns the
|
|
528
|
+
provider the session currently uses.
|
|
529
|
+
- `agent-framework` — `AdvisorController`, `createAdvisorTool`, the advisor spec helpers, provider
|
|
530
|
+
destinations (`describeProviderDestination`, `rememberProviderDestination`), `getSessionUsage` and
|
|
531
|
+
`ISessionUsageRecord`, the `onUsageRecorded` session option, and the optional `advisor` command
|
|
532
|
+
host adapter. Session assembly binds a host-supplied Advisor tool to the session holding it.
|
|
533
|
+
- `agent-command` — the `/advisor` command module; `/cost` reads the session's persisted usage.
|
|
534
|
+
- `agent-cli` — the `--advisor` flag, `advisorModel` setting, per-destination consent store and kill
|
|
535
|
+
switch.
|
|
536
|
+
- `agent-ui-terminal` — a usage line from another source (the advisor, a background task) names that
|
|
537
|
+
source and leaves out the context window it does not have.
|
|
538
|
+
- `agent-session-analytics` — personal usage counts an advisor call's tokens and cost toward its
|
|
539
|
+
turn without counting it as a turn.
|
|
540
|
+
|
|
541
|
+
- d4189b9: The rest of the per-server MCP OAuth lifecycle: signing in to a server without a local browser,
|
|
542
|
+
signing out of it with token revocation, and each server's sign-in state in `/mcp`.
|
|
543
|
+
|
|
544
|
+
- **`robota mcp login <name> --no-browser`** prints the authorization URL and reads the redirect URL
|
|
545
|
+
the user pastes back (not echoed). `runMCPOAuthLogin` takes `readRedirect` for this; nothing
|
|
546
|
+
listens on the redirect URI then. The pasted URL is held to the loopback listener's rules through
|
|
547
|
+
`createPastedRedirectAcceptor`: it must be the registered redirect URI (same origin and path, no
|
|
548
|
+
user info), carry the sign-in's `state` (compared in constant time), and is accepted once; an
|
|
549
|
+
error redirect is `authorization-denied` without its `error_description`, and the RFC 9207 `iss`
|
|
550
|
+
check applies as before. `openBrowser` now also receives the redirect URI. `readRedirect` gets a
|
|
551
|
+
signal that aborts on cancel or at `callbackTimeoutMs` (5 minutes by default, as for the loopback
|
|
552
|
+
listener); a paste longer than the prompt accepts fails as `redirect-too-long`.
|
|
553
|
+
- **Signing out** (`runMCPOAuthLogout`; `robota mcp logout <name>`; `/mcp logout <serverId>`):
|
|
554
|
+
deletes the stored credential under the refresh lock, then revokes the refresh token and the
|
|
555
|
+
access token (RFC 7009) when the stored issuer advertises `revocation_endpoint`. Revocation is a
|
|
556
|
+
POST through the egress policy that never follows a redirect and is byte-bounded; it authenticates
|
|
557
|
+
the client by `revocation_endpoint_auth_methods_supported` when advertised, otherwise the way its
|
|
558
|
+
refresh does. The local delete always happens. Each token's outcome is reported in `tokens`, and
|
|
559
|
+
overall as `revoked`, `partial`, `unsupported`, `failed` or `not-attempted`, with fixed reasons
|
|
560
|
+
only (new: `revocation-failed`, and `token-type-not-revocable` for RFC 7009
|
|
561
|
+
`unsupported_token_type`). `/mcp logout` also makes the session's authenticator drop the token it
|
|
562
|
+
holds (`IMCPOAuthAuthenticator.forget`).
|
|
563
|
+
- **Sign-in state:** `readMCPOAuthCredentialState` answers `signed-in`, `expired-refreshable`,
|
|
564
|
+
`sign-in-required` or `signed-out` — never anything token-derived. `/mcp` shows it for every
|
|
565
|
+
OAuth server; a server this session was told needs a sign-in reads `sign-in-required`.
|
|
566
|
+
`ICommandMCPActivationAdapter` gains optional `oauthStatus` and `oauthLogout`
|
|
567
|
+
(`ICommandMCPOAuthStatus`, `ICommandMCPOAuthLogoutResult`).
|
|
568
|
+
- **No in-session sign-in:** signing in stays `robota mcp login <server>` in a terminal, since it
|
|
569
|
+
needs the terminal (browser, pasted redirect, hidden secret prompt) a running session owns. `/mcp`
|
|
570
|
+
names that command for a server that needs a sign-in, as does the session's sign-in notice; the
|
|
571
|
+
server name is shown there only when it is safe to paste into any shell — a plain token not
|
|
572
|
+
starting with `-` or `=` — and is otherwise replaced by `<server>` (`shellArgumentForDisplay` in
|
|
573
|
+
`agent-core`; nothing is quoted, since quoting rules differ between shells). Server names in OAuth
|
|
574
|
+
notices have control and format characters escaped.
|
|
575
|
+
- **Refresh hardening:** on `invalid_grant`, the store is read again under the lock; a refresh token
|
|
576
|
+
another holder rotated in meanwhile is kept (and used when still valid) instead of being deleted.
|
|
577
|
+
The expiry skew is capped at half the token's lifetime, so a short-lived token is not refreshed on
|
|
578
|
+
every request; credentials now record `issuedAt` for this.
|
|
579
|
+
|
|
580
|
+
- af2f2ad: `/cd <directory>` continues the conversation in another directory.
|
|
581
|
+
|
|
582
|
+
- **A move is a new session in the target directory.** In the TUI, robota saves a copy of the
|
|
583
|
+
conversation where the target's session store will find it, ends the current run through its
|
|
584
|
+
normal end-of-life flow, and starts again in the target directory resuming that copy. The target's
|
|
585
|
+
settings, trust decision, tools, skills and `AGENTS.md` apply, exactly as if robota had been
|
|
586
|
+
launched there. The process boundary makes the move atomic, so no tool call can straddle it.
|
|
587
|
+
- **The system prompt is kept as recorded**, so a provider's prompt cache survives. One appended
|
|
588
|
+
`<workspace-move>` message tells the model the new directory, and which project instructions now
|
|
589
|
+
apply.
|
|
590
|
+
- **Refused** while a turn is running or a background task is still running, for a missing directory
|
|
591
|
+
or the current one, and for a target a `Cd(...)` deny rule names.
|
|
592
|
+
- **Access never widens:** a restricted session stays restricted after a move, and a trusted session
|
|
593
|
+
takes the target's own trust decision.
|
|
594
|
+
- New contracts: the `workspace-move` host action, `ICommandWorkspaceAdapter` /
|
|
595
|
+
`IWorkspaceMoveRequest`, `InteractiveSession.moveWorkspace`, and the `workspaceMovedFrom` session
|
|
596
|
+
option. The CLI's `--moved-from` and `--restricted-workspace` flags are internal.
|
|
597
|
+
|
|
598
|
+
- 34e50f0: A new permission mode, `auto`, lets a model classifier approve or block what would otherwise prompt.
|
|
599
|
+
|
|
600
|
+
- **What it decides:**
|
|
601
|
+
- Reads and in-workspace edits run as in `acceptEdits`.
|
|
602
|
+
- Commands and other calls the mode leaves open go to the classifier, a side call to the
|
|
603
|
+
session's own model. It sees the call, the working directory and the git remotes, never the
|
|
604
|
+
conversation.
|
|
605
|
+
- A block reaches the model with its reason, so it can take another route.
|
|
606
|
+
- **What still reaches a person, or is refused:**
|
|
607
|
+
- Deny rules and background ceilings apply first.
|
|
608
|
+
- `ask` rules, critical removals and protected paths ask a person.
|
|
609
|
+
- After 3 refusals in a row (blocks, or no usable verdict), or 20 blocks in the session, the
|
|
610
|
+
mode asks a person until one approves.
|
|
611
|
+
With no one to ask, the call is denied.
|
|
612
|
+
- **Allow rules:** in `auto` mode, allow rules that approve any command are set aside while the
|
|
613
|
+
mode is on. Examples are `Bash(*)`, an interpreter (`Bash(python *)`), a package runner
|
|
614
|
+
(`Bash(npm run *)`, `Bash(pnpm exec *)`), `Agent`, `ExecuteCommand` or `Computer`. Narrow
|
|
615
|
+
rules still apply.
|
|
616
|
+
- **Retry:** `/permissions` lists classifier blocks. `/permissions retry <n>` lets that exact call
|
|
617
|
+
run once, unjudged, when the model tries it again.
|
|
618
|
+
- **Turning it on and off:**
|
|
619
|
+
- `--permission-mode auto`, `/mode auto` or `/permissions auto`.
|
|
620
|
+
- An organization turns it off with `disableAutoMode` in the org policy.
|
|
621
|
+
- **New contracts:**
|
|
622
|
+
- `TPermissionMode` gains `'auto'`.
|
|
623
|
+
- `allowRulesForAutoMode` and `isBroadExecutionAllowRule`.
|
|
624
|
+
- `IPermissionClassifier` and `AutoModeGate`.
|
|
625
|
+
- The `permissionClassifier` session option.
|
|
626
|
+
- `Session.retryPermissionDenial`, and `retryDenial` on the permission-mode adapter.
|
|
627
|
+
- The `'classifier'` denial reason.
|
|
628
|
+
- `createModelPermissionClassifier`.
|
|
629
|
+
- The `disableAutoMode` option on `createSession` and `IOrgPolicy`.
|
|
630
|
+
|
|
631
|
+
- 722e88a: Shell commands can run in an OS-level sandbox: bubblewrap on Linux and WSL2, Seatbelt on macOS.
|
|
632
|
+
|
|
633
|
+
- **Confinement:** covers the command and every process it starts.
|
|
634
|
+
- Writes are limited to the working directory, the temporary directories and
|
|
635
|
+
`sandbox.filesystem.allowWrite`.
|
|
636
|
+
- Agent, git-hook, MCP and shell configuration inside the workspace stays read-only.
|
|
637
|
+
- `sandbox.filesystem.denyRead` hides paths from the command.
|
|
638
|
+
- The network is on or off (`sandbox.network.enabled`).
|
|
639
|
+
- **Modes:** `/sandbox` switches between `auto-allow`, `regular` and `off` for the next command and
|
|
640
|
+
saves the choice.
|
|
641
|
+
- In `auto-allow` (`sandbox.autoAllowBashIfSandboxed`), a confined command runs without a prompt
|
|
642
|
+
in `default` and `acceptEdits`.
|
|
643
|
+
- Deny rules, ask rules, critical removals and plan mode still apply first.
|
|
644
|
+
- **Exclusions:** `sandbox.excludedCommands` run unconfined, through the ordinary permission path.
|
|
645
|
+
- **When the sandbox cannot run:** a missing or unusable backend is reported at startup, in
|
|
646
|
+
`robota doctor` and in `/sandbox`, and commands then run unconfined.
|
|
647
|
+
`sandbox.failIfUnavailable` refuses to start instead.
|
|
648
|
+
- **New contracts:**
|
|
649
|
+
- `OsSandboxClient`, `detectOsSandbox`, `bubblewrapArguments`, `seatbeltProfile`.
|
|
650
|
+
- `ISandboxClient.wrapCommand` and `autoApproves`.
|
|
651
|
+
- `IPermissionEvaluationContext.sandboxAutoApproved`.
|
|
652
|
+
- The `commandSandbox` session option.
|
|
653
|
+
- The `sandbox` settings key and the `sandbox` command host adapter.
|
|
654
|
+
|
|
655
|
+
- a5cc36e: `/permissions` shows the rules the session enforces and the calls it refused.
|
|
656
|
+
|
|
657
|
+
- **Rules by source:** each allow, deny and ask rule the gate reads is listed under the settings file
|
|
658
|
+
that declares it. Rules added by a CLI flag, a preset or a command are listed under "this session".
|
|
659
|
+
A rule a settings file declares but the session does not enforce is not shown.
|
|
660
|
+
- **Recent denials:** the latest refused calls, most recent first, with the reason: a rule or the
|
|
661
|
+
mode, the user declining, or no one available to approve.
|
|
662
|
+
- New contracts: `Session.getRecentPermissionDenials()`, `PermissionEnforcer.getRecentDenials()`,
|
|
663
|
+
`IPermissionDenial`, the `permissionRules` host adapter (`createSettingsPermissionRulesAdapter`),
|
|
664
|
+
and `getPermissionRules` / `listRecentDenials` on `ICommandPermissionModeAdapter`. Settings
|
|
665
|
+
provenance now covers `permissions.ask`.
|
|
666
|
+
|
|
667
|
+
- 4dd45cc: `/peers` shows how each other local session's workspace relates to this one's: `same worktree`,
|
|
668
|
+
`same repo`, `different repo`, or `workspace unknown`.
|
|
669
|
+
|
|
670
|
+
A session now publishes a workspace claim with its rendezvous entry — the root commits reachable
|
|
671
|
+
from HEAD, a SHA-256 of its normalized `origin` URL (never the URL itself), and the real path of its
|
|
672
|
+
worktree — and re-reads it as it runs, so a first commit or a checkout does not leave it stale. The
|
|
673
|
+
reader does not take the claim as written: it reads git at the claimed path itself, and a claim whose
|
|
674
|
+
contents disagree is shown as `workspace claim mismatched, not believed` and relates to nothing. Those
|
|
675
|
+
git reads are local-only and asynchronous, run only for the view that shows the relation (and for
|
|
676
|
+
the sender of an incoming peer message), and are cached per announcement. The relation also reaches
|
|
677
|
+
the peer-turn origin, computed by the receiver; a relation the sender put on the wire is discarded,
|
|
678
|
+
and the admission never carries it.
|
|
679
|
+
|
|
680
|
+
The relation is display and routing information only and is never an authorization input.
|
|
681
|
+
|
|
682
|
+
Additive: `agent-interface-session-mobility` exports `TWorkspaceRelation` and gains the optional
|
|
683
|
+
`IPeerOrigin.workspaceRelation`; `agent-framework`'s `ILocalPeerSummary` gains the optional
|
|
684
|
+
`workspaceRelation` and `workspaceClaim`, and `ICommandLocalPeersAdapter` the optional
|
|
685
|
+
`listWithWorkspace()`.
|
|
686
|
+
|
|
687
|
+
- 2d3b2c0: ARCH-024 replaces framework knowledge of command-owner ids with optional, owner-declared semantic
|
|
688
|
+
roles. `ISystemCommand` can declare `skillActivation`, `contextReduction`, or `subagentSpawn`;
|
|
689
|
+
`SystemCommandExecutor` exposes the selected role projection and rejects duplicate owners with the
|
|
690
|
+
typed `DuplicateSystemCommandSemanticRoleError`, atomically across construction, registration, and
|
|
691
|
+
replacement.
|
|
692
|
+
|
|
693
|
+
This is a beta-line breaking contract correction: unannotated commands named `skills`, `compact`, or
|
|
694
|
+
`agent` no longer receive special framework behavior. `@robota-sdk/agent-command` now declares the
|
|
695
|
+
roles on its shipped skills, compact, and agent commands.
|
|
696
|
+
|
|
697
|
+
- 1e3f91a: CMD-004 Phase 2 Stage E (breaking, beta line): the legacy `TCommandEffect` union and
|
|
698
|
+
`ICommandResult.effects` are DELETED. Commands emit the split contract directly —
|
|
699
|
+
`hostActions` (session-executed via `ICommandHostAdapters`; works headless and remote) and
|
|
700
|
+
`uiIntents` (requester-routed `ui_intent` session events with UI-neutral `show-*` names).
|
|
701
|
+
Final carriers for the former notification effects: `session_renamed` and the new
|
|
702
|
+
`history_cleared` are BROADCAST session events (forwarded to every WS surface, folded by the
|
|
703
|
+
TUI transcript/title and the GUI reducer's new `sessionName`/transcript-reset state);
|
|
704
|
+
`session-execution-started` rides `result.data.sessionExecution`; the plugin-registry refresh
|
|
705
|
+
rides `result.data.pluginRegistryReloaded`. A mechanical grep floor
|
|
706
|
+
(`command-effect-grep-floor.test.ts`) keeps `tui-requested`/`TCommandEffect`/`effects:` out of
|
|
707
|
+
every `packages/*/src` production tree.
|
|
708
|
+
- 44393be: Add the `/remote-control` enable path (REMOTE-008 Stage B4-2b) — turn on P2P remote control locally, get
|
|
709
|
+
a QR + link, and a paired device co-drives the SAME live session over pairing-gated WebRTC. The command
|
|
710
|
+
is a declarative trigger returning `remote-control-enable-requested`/`-stop-requested` effects (SSOT
|
|
711
|
+
agent-interface-transport) and reads state via a new `ICommandHostAdapters.remoteControl.getStatus()`;
|
|
712
|
+
the TUI dispatches the effects to injected callbacks; all transport construction lives at the agent-cli
|
|
713
|
+
composition root (`WsSignalingClient` + pairing-gated `WebRtcTransport`, relay URL from
|
|
714
|
+
`transports.webrtc.options.relayUrl`, QR/link rendered into history). Fail-closed: no relay configured ⇒
|
|
715
|
+
does nothing; pairing mismatch/timeout ⇒ the session is never exposed. Consumes REMOTE-007 so a paired
|
|
716
|
+
remote owner answers their own permission/ask prompts over the WebRTC channel.
|
|
717
|
+
- cbee54e: Surface unmatched preset command-module names instead of silently dropping them (INFRA-032). A preset `enabledCommandModules`/`disabledCommandModules` entry that matches no built command module — a short form like `"editor"` instead of `agent-command-editor`, or a typo — is now reported as a non-fatal notice on both the startup `--preset` path (CLI terminal) and the in-session `/preset` path (command result). Detection lives once in agent-framework's new pure `findUnknownModuleNames`, and agent-command's duplicate module filter now delegates to the framework's `selectCommandModules`; `createDefaultCommandModules` returns `{ modules, unknownModuleNames }`.
|
|
718
|
+
|
|
719
|
+
### Patch Changes
|
|
720
|
+
|
|
721
|
+
- b462ee7: Discriminate `IBackgroundTaskState` by kind, the same way `TBackgroundTaskRequest` and (as of the
|
|
722
|
+
prior change) `TBackgroundTaskResult` already are. Fields only one runner ever produces now live
|
|
723
|
+
only on that kind's member instead of being optional-and-cross-kind-reachable on every kind:
|
|
724
|
+
|
|
725
|
+
- `agent`-only: `agentType`, `isolation`, `resumeSessionId`, `promptPreview`, and the
|
|
726
|
+
worktree-isolation fields (`worktreePath`, `branchName`, `worktreeStatus`, `worktreeNextAction`,
|
|
727
|
+
`worktreeBaseRevision`, `parentWorktreeStatus`).
|
|
728
|
+
- `scheduled`-only: `schedule`, `nextFireAt`.
|
|
729
|
+
- Every kind except `agent`: `commandPreview` (a process command, an MCP tool-invocation summary, or
|
|
730
|
+
a schedule's shell command / wake instruction).
|
|
731
|
+
- `state.result` is now `IBackgroundTaskResult<K>` — correlated with `state.kind`, not the free
|
|
732
|
+
full-result union.
|
|
733
|
+
|
|
734
|
+
`pid`, `logPath`, and `transcriptPath` stay on the shared base rather than becoming agent- or
|
|
735
|
+
process-exclusive: the runner handle SPI already reports them for whichever runner's process
|
|
736
|
+
happens to produce them, and a subagent run via the worktree/child-process runner carries a `pid`
|
|
737
|
+
exactly as a `process`-kind task does. `timeoutReason` also stays base — session restore sets
|
|
738
|
+
`'stale_worker'` on any non-terminal, non-rearmable task regardless of kind, not only agent ones.
|
|
739
|
+
|
|
740
|
+
`IBackgroundTaskState<K>` narrows to the kind-specific member; called with no type argument it is
|
|
741
|
+
still the full union. The session-record decoder (`agent-session`) now rejects a persisted task
|
|
742
|
+
state carrying a field outside its own kind as corrupt, reported at that field's own path, the same
|
|
743
|
+
way it already rejects a `state.result` whose kind disagrees with `state.kind`.
|
|
744
|
+
|
|
745
|
+
**Breaking for `@robota-sdk/agent-interface-execution` and `@robota-sdk/agent-executor`**: code that
|
|
746
|
+
read a kind-specific field (e.g. `state.agentType`, `state.schedule`, `state.commandPreview`) off an
|
|
747
|
+
unnarrowed `IBackgroundTaskState` needs to narrow on `state.kind` first, since the fallback default
|
|
748
|
+
no longer carries every field on every kind. `agent-session`, `agent-framework`, and `agent-command`
|
|
749
|
+
land the corresponding narrowing at every read site the type change touched; no runtime behavior
|
|
750
|
+
changes there beyond the state decoder's new corruption checks.
|
|
751
|
+
|
|
752
|
+
- 3a8876b: ARCH-029: decompose the command host into role ports
|
|
753
|
+
|
|
754
|
+
`ICommandHostContext`, `ICommandSessionRuntime` and `IAgentJobHostContext` are now empty `extends`
|
|
755
|
+
aggregates over 26 named role ports, so a command declares only the capability it uses. A role port
|
|
756
|
+
is a supertype of the aggregate, so narrowing a declared parameter still satisfies
|
|
757
|
+
`ISystemCommand.execute` by contravariance.
|
|
758
|
+
|
|
759
|
+
All 79 members are preserved (46 + 18 + 15) with the declaration kind unchanged, so implementors and
|
|
760
|
+
callers stay source-compatible.
|
|
761
|
+
|
|
762
|
+
**Breaking:** every role-port member is now required except the adapter bag, whose contents are
|
|
763
|
+
genuinely variational. 38 members went from optional to required. A host that previously omitted a
|
|
764
|
+
member must now provide one — including `validateCurrentSessionReplayLog`, which was an override
|
|
765
|
+
with a framework-computed default and no implementor. `createTestCommandHost`,
|
|
766
|
+
`createTestAgentJobHost` and `createTestSessionRuntime` are published from
|
|
767
|
+
`@robota-sdk/agent-framework/testing` as conformant, cast-free doubles for exactly this.
|
|
768
|
+
|
|
769
|
+
Also removed: the `clearConversationHistory` fallback that reached past the host into
|
|
770
|
+
`getSession().clearHistory()`. Those were never the same operation — the host path also broadcasts
|
|
771
|
+
`history_cleared` to every attached surface, so a fallback clear left other surfaces still showing
|
|
772
|
+
the transcript.
|
|
773
|
+
|
|
774
|
+
- 4f3c075: Assemble complete, verified package generations before switching build output; preserve the previous generation on build failure and pack only verified regular-file images. Include copied CLI web assets in affected-build ordering and artifact transfer. Preserve the CLI version in managed build paths. Public runtime contracts remain compatible (patch).
|
|
775
|
+
- d6b9404: Remove polynomial-ReDoS backtracking (SEC-003, CodeQL `js/polynomial-redos`) from three parsers whose input is not repo-controlled.
|
|
776
|
+
|
|
777
|
+
`parseStructuredResponseText` (agent-core) parses raw model output; its fenced-code-block regex used `\s*\n`, and because `\s` also matches a newline the two overlapped, so an unterminated fence containing many blank lines was rejected in O(n^2) — 12.7s for a 400 KB string, now ~1ms. The whitespace run is now restricted to horizontal whitespace, which makes the newline split point unique.
|
|
778
|
+
|
|
779
|
+
`/schedule cron` and `/monitor` (agent-command) are declared `modelInvocable: true`, so their argument string is composed by the model. Both matched the trailing instruction with `\s+(.+)$`; since `.` also matches a space the split point was ambiguous and a non-matching argument cost O(n^2) — ~15s for a 200 KB argument, now <1ms. The instruction is now required to start with a non-space character, which pins the split point without changing which inputs are accepted.
|
|
780
|
+
|
|
781
|
+
No behaviour change: the set of accepted inputs and the parsed values are identical in every case.
|
|
782
|
+
|
|
783
|
+
- Updated dependencies [9c19c50]
|
|
784
|
+
- Updated dependencies [7b6234c]
|
|
785
|
+
- Updated dependencies [5307f8a]
|
|
786
|
+
- Updated dependencies [b462ee7]
|
|
787
|
+
- Updated dependencies [08a9bd6]
|
|
788
|
+
- Updated dependencies [37b4bd7]
|
|
789
|
+
- Updated dependencies [818f0c8]
|
|
790
|
+
- Updated dependencies [4eea54b]
|
|
791
|
+
- Updated dependencies [1698be4]
|
|
792
|
+
- Updated dependencies [9368d00]
|
|
793
|
+
- Updated dependencies [d4189b9]
|
|
794
|
+
- Updated dependencies [9edae52]
|
|
795
|
+
- Updated dependencies [4078a72]
|
|
796
|
+
- Updated dependencies [4c73a0b]
|
|
797
|
+
- Updated dependencies [af2f2ad]
|
|
798
|
+
- Updated dependencies [267af5f]
|
|
799
|
+
- Updated dependencies [196a900]
|
|
800
|
+
- Updated dependencies [f336838]
|
|
801
|
+
- Updated dependencies [34e50f0]
|
|
802
|
+
- Updated dependencies [722e88a]
|
|
803
|
+
- Updated dependencies [a5cc36e]
|
|
804
|
+
- Updated dependencies [d23c848]
|
|
805
|
+
- Updated dependencies [b70fa3d]
|
|
806
|
+
- Updated dependencies [2711ec6]
|
|
807
|
+
- Updated dependencies [4dd45cc]
|
|
808
|
+
- Updated dependencies [378c585]
|
|
809
|
+
- Updated dependencies [4c5148e]
|
|
810
|
+
- Updated dependencies [37af5dc]
|
|
811
|
+
- Updated dependencies [807d161]
|
|
812
|
+
- Updated dependencies [fec722f]
|
|
813
|
+
- Updated dependencies [e82215f]
|
|
814
|
+
- Updated dependencies [52b7346]
|
|
815
|
+
- Updated dependencies [2ebff01]
|
|
816
|
+
- Updated dependencies [2ebff01]
|
|
817
|
+
- Updated dependencies [2d3b2c0]
|
|
818
|
+
- Updated dependencies [b078afa]
|
|
819
|
+
- Updated dependencies [2d3b2c0]
|
|
820
|
+
- Updated dependencies [baa6863]
|
|
821
|
+
- Updated dependencies [2d3b2c0]
|
|
822
|
+
- Updated dependencies [3a8876b]
|
|
823
|
+
- Updated dependencies [4772067]
|
|
824
|
+
- Updated dependencies [7b85767]
|
|
825
|
+
- Updated dependencies [0f98419]
|
|
826
|
+
- Updated dependencies [64ba748]
|
|
827
|
+
- Updated dependencies [9fbab1b]
|
|
828
|
+
- Updated dependencies [d312755]
|
|
829
|
+
- Updated dependencies [a009f5b]
|
|
830
|
+
- Updated dependencies [1e3f91a]
|
|
831
|
+
- Updated dependencies [4f3c075]
|
|
832
|
+
- Updated dependencies [475e085]
|
|
833
|
+
- Updated dependencies [e477440]
|
|
834
|
+
- Updated dependencies [9dcb5da]
|
|
835
|
+
- Updated dependencies [a95ca85]
|
|
836
|
+
- Updated dependencies [b6d14ce]
|
|
837
|
+
- Updated dependencies [0382a51]
|
|
838
|
+
- Updated dependencies [93d061d]
|
|
839
|
+
- Updated dependencies [39554a1]
|
|
840
|
+
- Updated dependencies [d28430a]
|
|
841
|
+
- Updated dependencies [bed26ea]
|
|
842
|
+
- Updated dependencies [fe48835]
|
|
843
|
+
- Updated dependencies [1e40b5b]
|
|
844
|
+
- Updated dependencies [4b76cfa]
|
|
845
|
+
- Updated dependencies [d9bd9ec]
|
|
846
|
+
- Updated dependencies [8865acf]
|
|
847
|
+
- Updated dependencies [90e7a10]
|
|
848
|
+
- Updated dependencies [fcb0da3]
|
|
849
|
+
- Updated dependencies [07b627f]
|
|
850
|
+
- Updated dependencies [d0de5b2]
|
|
851
|
+
- Updated dependencies [9665c6e]
|
|
852
|
+
- Updated dependencies [44393be]
|
|
853
|
+
- Updated dependencies [c7fa299]
|
|
854
|
+
- Updated dependencies [5134b3b]
|
|
855
|
+
- Updated dependencies [dd444c1]
|
|
856
|
+
- Updated dependencies [1f57e7f]
|
|
857
|
+
- Updated dependencies [833afe1]
|
|
858
|
+
- Updated dependencies [d6b9404]
|
|
859
|
+
- Updated dependencies [7863b16]
|
|
860
|
+
- Updated dependencies [fde558e]
|
|
861
|
+
- Updated dependencies [db5c439]
|
|
862
|
+
- Updated dependencies [4a01a87]
|
|
863
|
+
- Updated dependencies [cbee54e]
|
|
864
|
+
- Updated dependencies [9814afc]
|
|
865
|
+
- Updated dependencies [242a644]
|
|
866
|
+
- @robota-sdk/agent-interface-execution@3.0.0-beta.80
|
|
867
|
+
- @robota-sdk/agent-interface-command@3.0.0-beta.80
|
|
868
|
+
- @robota-sdk/agent-framework@3.0.0-beta.80
|
|
869
|
+
- @robota-sdk/agent-core@3.0.0-beta.80
|
|
870
|
+
- @robota-sdk/agent-interface-session@3.0.0-beta.80
|
|
871
|
+
- @robota-sdk/agent-preset@3.0.0-beta.80
|
|
872
|
+
|
|
873
|
+
## 3.0.0-beta.79
|
|
874
|
+
|
|
875
|
+
### Patch Changes
|
|
876
|
+
|
|
877
|
+
- @robota-sdk/agent-core@3.0.0-beta.79
|
|
878
|
+
- @robota-sdk/agent-framework@3.0.0-beta.79
|
|
879
|
+
- @robota-sdk/agent-interface-transport@3.0.0-beta.79
|
|
880
|
+
- @robota-sdk/agent-preset@3.0.0-beta.79
|
|
881
|
+
|
|
882
|
+
## 3.0.0-beta.78
|
|
883
|
+
|
|
884
|
+
### Patch Changes
|
|
885
|
+
|
|
886
|
+
- Updated dependencies [6f308d1]
|
|
887
|
+
- @robota-sdk/agent-core@3.0.0-beta.78
|
|
888
|
+
- @robota-sdk/agent-framework@3.0.0-beta.78
|
|
889
|
+
- @robota-sdk/agent-interface-transport@3.0.0-beta.78
|
|
890
|
+
- @robota-sdk/agent-preset@3.0.0-beta.78
|
|
891
|
+
|
|
892
|
+
## 3.0.0-beta.77
|
|
893
|
+
|
|
894
|
+
### Patch Changes
|
|
895
|
+
|
|
896
|
+
- Updated dependencies
|
|
897
|
+
- @robota-sdk/agent-core@3.0.0-beta.77
|
|
898
|
+
- @robota-sdk/agent-framework@3.0.0-beta.77
|
|
899
|
+
- @robota-sdk/agent-interface-transport@3.0.0-beta.77
|
|
900
|
+
- @robota-sdk/agent-preset@3.0.0-beta.77
|
|
901
|
+
|
|
902
|
+
## 3.0.0-beta.76
|
|
903
|
+
|
|
904
|
+
### Patch Changes
|
|
905
|
+
|
|
906
|
+
- DQ-AUDIT-002 — consolidate duplicated domain data onto single owners: one model-pricing SSOT in agent-core (`MODEL_PRICES`/`lookupModelPrice`/`calculateModelCost`/`estimateBlendedCostPer1000`) consumed by agent-command and agent-plugin (drops two embedded/stale price tables); the `len/4` token estimator replaced by core `CONTEXT_ESTIMATE_CHARS_PER_TOKEN`; TUI `TContextState` derived from core `IContextWindowState`; dead pass-through re-exports removed from agent-session.
|
|
907
|
+
- 576af62: Fix `ConfigurationError: Agent must be fully initialized before changing model configuration` when running `/preset` (or any live model re-apply) on a fresh interactive session before the first message. The Robota agent initialized lazily on the first `run()`, but `setModel` requires full initialization. `Session.applyModelOptions` now awaits the new idempotent `Robota.ensureReady()` before `setModel`, and the preset live-switch path (`applyPresetToSession` → `executePresetCommand`) is async end-to-end. Adds a real cold-session regression test (no mocked Robota).
|
|
908
|
+
- Updated dependencies
|
|
909
|
+
- Updated dependencies [c0a6287]
|
|
910
|
+
- Updated dependencies [9df3a88]
|
|
911
|
+
- Updated dependencies
|
|
912
|
+
- Updated dependencies
|
|
913
|
+
- Updated dependencies [576af62]
|
|
914
|
+
- @robota-sdk/agent-core@3.0.0-beta.76
|
|
915
|
+
- @robota-sdk/agent-framework@3.0.0-beta.76
|
|
916
|
+
- @robota-sdk/agent-interface-transport@3.0.0-beta.76
|
|
917
|
+
- @robota-sdk/agent-preset@3.0.0-beta.76
|
|
918
|
+
|
|
919
|
+
## 3.0.0-beta.75
|
|
920
|
+
|
|
921
|
+
### Patch Changes
|
|
922
|
+
|
|
923
|
+
- Agent preset system + live preset switching + context/history correctness fixes.
|
|
924
|
+
|
|
925
|
+
- **Preset system (PRESET-001~017):** new `@robota-sdk/agent-preset` package layering framework
|
|
926
|
+
assembly options into named, selectable profiles (`default`, `autonomous-builder`, `careful-reviewer`,
|
|
927
|
+
`neutral-executor`) plus user-authored external presets loaded from `~/.robota/presets/*.json`.
|
|
928
|
+
- **Live preset switching:** `/preset` command (list + active marker + switch) and a TUI active-preset
|
|
929
|
+
display. Switching live re-applies permission posture, model/effort, persona, command-module
|
|
930
|
+
selection, parallel-subagents gating, and a self-verification system-prompt section via the single
|
|
931
|
+
`applyPresetToSession` engine.
|
|
932
|
+
- **CTX-001:** the TUI Context display + session auto-compact now use the accurate provider-based token
|
|
933
|
+
estimate (system prompt + tool schemas included) instead of a crude history-only char heuristic.
|
|
934
|
+
- **HIST-001:** conversation history is now append-only — removed the silent 100-message count cap that
|
|
935
|
+
could drop early context; context size is managed solely by size-based compaction.
|
|
936
|
+
|
|
937
|
+
- Updated dependencies
|
|
938
|
+
- @robota-sdk/agent-preset@3.0.0-beta.75
|
|
939
|
+
- @robota-sdk/agent-framework@3.0.0-beta.75
|
|
940
|
+
- @robota-sdk/agent-core@3.0.0-beta.75
|
|
941
|
+
- @robota-sdk/agent-interface-transport@3.0.0-beta.75
|
|
942
|
+
|
|
943
|
+
## 3.0.0-beta.74
|
|
944
|
+
|
|
945
|
+
### Patch Changes
|
|
946
|
+
|
|
947
|
+
- Updated dependencies
|
|
948
|
+
- @robota-sdk/agent-framework@3.0.0-beta.74
|
|
949
|
+
- @robota-sdk/agent-core@3.0.0-beta.74
|
|
950
|
+
- @robota-sdk/agent-interface-transport@3.0.0-beta.74
|
|
951
|
+
|
|
952
|
+
## 3.0.0-beta.73
|
|
953
|
+
|
|
954
|
+
### Patch Changes
|
|
955
|
+
|
|
956
|
+
- @robota-sdk/agent-core@3.0.0-beta.73
|
|
957
|
+
- @robota-sdk/agent-framework@3.0.0-beta.73
|
|
958
|
+
|
|
959
|
+
## 3.0.0-beta.72
|
|
960
|
+
|
|
961
|
+
### Patch Changes
|
|
962
|
+
|
|
963
|
+
- Updated dependencies
|
|
964
|
+
- @robota-sdk/agent-framework@3.0.0-beta.72
|
|
965
|
+
- @robota-sdk/agent-core@3.0.0-beta.72
|
|
966
|
+
|
|
967
|
+
## 3.0.0-beta.71
|
|
968
|
+
|
|
969
|
+
### Patch Changes
|
|
970
|
+
|
|
971
|
+
- fix(context): unify token estimation to single SSOT — status bar and /context list now use the same serialized JSON estimate
|
|
972
|
+
- Updated dependencies
|
|
973
|
+
- @robota-sdk/agent-core@3.0.0-beta.71
|
|
974
|
+
- @robota-sdk/agent-framework@3.0.0-beta.71
|
|
975
|
+
|
|
976
|
+
## 3.0.0-beta.70
|
|
977
|
+
|
|
978
|
+
### Patch Changes
|
|
979
|
+
|
|
980
|
+
- CLI UX fixes: /context list full LLM context breakdown (CLI-B10), logo resize fix (CLI-B03), token estimates in context list (CLI-B04)
|
|
981
|
+
- Updated dependencies
|
|
982
|
+
- @robota-sdk/agent-framework@3.0.0-beta.70
|
|
983
|
+
- @robota-sdk/agent-core@3.0.0-beta.70
|
|
984
|
+
|
|
985
|
+
## 3.0.0-beta.69
|
|
986
|
+
|
|
987
|
+
### Patch Changes
|
|
988
|
+
|
|
989
|
+
- Updated dependencies
|
|
990
|
+
- @robota-sdk/agent-framework@3.0.0-beta.69
|
|
991
|
+
- @robota-sdk/agent-core@3.0.0-beta.69
|
|
992
|
+
|
|
993
|
+
## 3.0.0-beta.68
|
|
994
|
+
|
|
995
|
+
### Patch Changes
|
|
996
|
+
|
|
997
|
+
- @robota-sdk/agent-core@3.0.0-beta.68
|
|
998
|
+
- @robota-sdk/agent-framework@3.0.0-beta.68
|
|
999
|
+
|
|
1000
|
+
## 3.0.0-beta.67
|
|
1001
|
+
|
|
1002
|
+
### Patch Changes
|
|
1003
|
+
|
|
1004
|
+
- Updated dependencies
|
|
1005
|
+
- @robota-sdk/agent-framework@3.0.0-beta.67
|
|
1006
|
+
- @robota-sdk/agent-core@3.0.0-beta.67
|
|
1007
|
+
|
|
1008
|
+
## 3.0.0-beta.66
|
|
1009
|
+
|
|
1010
|
+
### Patch Changes
|
|
1011
|
+
|
|
1012
|
+
- refactor: CLI-001/002 — agent-cli layer separation and monorepo-wide readability lint rules
|
|
1013
|
+
- CLI-001: Extract startup phases into focused modules; enforce agent-cli layer separation
|
|
1014
|
+
- CLI-002: Apply import/order, consistent-type-imports, explicit-function-return-type, prefer-const, object-shorthand across all packages
|
|
1015
|
+
- Fix stale child-process-subagent-worker entry in agent-cli tsdown.config.ts (build fix)
|
|
1016
|
+
|
|
1017
|
+
- Updated dependencies
|
|
1018
|
+
- @robota-sdk/agent-framework@3.0.0-beta.66
|
|
1019
|
+
- @robota-sdk/agent-core@3.0.0-beta.66
|
|
1020
|
+
|
|
1021
|
+
## 3.0.0-beta.65
|
|
1022
|
+
|
|
1023
|
+
### Patch Changes
|
|
1024
|
+
|
|
1025
|
+
- @robota-sdk/agent-core@3.0.0-beta.65
|
|
1026
|
+
- @robota-sdk/agent-framework@3.0.0-beta.65
|
|
1027
|
+
|
|
1028
|
+
## 3.0.0-beta.64
|
|
1029
|
+
|
|
1030
|
+
### Minor Changes
|
|
1031
|
+
|
|
1032
|
+
- feat: add displayName and requiresPermission to command interfaces
|
|
1033
|
+
- `ICommand`, `ISystemCommand`, `ICommandListEntry`: add optional `displayName` field for user-friendly labels
|
|
1034
|
+
- `ISystemCommand`: add optional `requiresPermission` field for per-command permission policy declaration
|
|
1035
|
+
- `SystemCommandExecutor`: add `resolveRequiresPermission()` — derives from `safety` when field is undefined
|
|
1036
|
+
- All 24 built-in commands declare explicit `displayName` and `requiresPermission`
|
|
1037
|
+
- TUI autocomplete renders `displayName ?? name`; Tab completion still inserts the technical command ID
|
|
1038
|
+
- `/help` output shows `Display Name (/command-id)` format
|
|
1039
|
+
|
|
1040
|
+
### Patch Changes
|
|
1041
|
+
|
|
1042
|
+
- Updated dependencies
|
|
1043
|
+
- @robota-sdk/agent-framework@3.0.0-beta.64
|
|
1044
|
+
- @robota-sdk/agent-core@3.0.0-beta.64
|