@namzu/sdk 45.0.0 → 46.0.0
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 +166 -0
- package/dist/authorization/gate.d.ts +5 -2
- package/dist/authorization/gate.d.ts.map +1 -1
- package/dist/authorization/gate.js +35 -4
- package/dist/authorization/gate.js.map +1 -1
- package/dist/authorization/rules.d.ts.map +1 -1
- package/dist/authorization/rules.js +56 -6
- package/dist/authorization/rules.js.map +1 -1
- package/dist/authorization/shell-lexer.d.ts +38 -0
- package/dist/authorization/shell-lexer.d.ts.map +1 -1
- package/dist/authorization/shell-lexer.js +88 -57
- package/dist/authorization/shell-lexer.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +2 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +1 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/directory/types.d.ts +2 -0
- package/dist/directory/types.d.ts.map +1 -1
- package/dist/directory/types.js.map +1 -1
- package/dist/manager/resident/outbox.d.ts +4 -4
- package/dist/pricing/catalogue.generated.d.ts.map +1 -1
- package/dist/pricing/catalogue.generated.js +28 -4
- package/dist/pricing/catalogue.generated.js.map +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
- package/dist/prompt/coding-agent-doctrine.js +1 -0
- package/dist/prompt/coding-agent-doctrine.js.map +1 -1
- package/dist/public-runtime.d.ts +6 -3
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +14 -2
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +7 -2
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +15 -2
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +8 -2
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/callable.d.ts +22 -0
- package/dist/registry/tool/callable.d.ts.map +1 -0
- package/dist/registry/tool/callable.js +29 -0
- package/dist/registry/tool/callable.js.map +1 -0
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +8 -1
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/runtime/query/declined.d.ts +12 -0
- package/dist/runtime/query/declined.d.ts.map +1 -0
- package/dist/runtime/query/declined.js +12 -0
- package/dist/runtime/query/declined.js.map +1 -0
- package/dist/runtime/query/executor/tool-call-admission.d.ts +37 -11
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +38 -12
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +7 -3
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +32 -7
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +1 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +7 -0
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +6 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/handoff.d.ts +22 -0
- package/dist/runtime/query/iteration/phases/handoff.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/handoff.js +65 -0
- package/dist/runtime/query/iteration/phases/handoff.js.map +1 -0
- package/dist/runtime/query/iteration/phases/index.d.ts +1 -0
- package/dist/runtime/query/iteration/phases/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/index.js +1 -0
- package/dist/runtime/query/iteration/phases/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +8 -3
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +3 -2
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +43 -0
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +63 -19
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/schedules/cron.d.ts +21 -0
- package/dist/schedules/cron.d.ts.map +1 -0
- package/dist/schedules/cron.js +167 -0
- package/dist/schedules/cron.js.map +1 -0
- package/dist/schedules/describe.d.ts +14 -0
- package/dist/schedules/describe.d.ts.map +1 -0
- package/dist/schedules/describe.js +133 -0
- package/dist/schedules/describe.js.map +1 -0
- package/dist/schedules/errors.d.ts +11 -0
- package/dist/schedules/errors.d.ts.map +1 -0
- package/dist/schedules/errors.js +15 -0
- package/dist/schedules/errors.js.map +1 -0
- package/dist/schedules/evaluate.d.ts +35 -0
- package/dist/schedules/evaluate.d.ts.map +1 -0
- package/dist/schedules/evaluate.js +158 -0
- package/dist/schedules/evaluate.js.map +1 -0
- package/dist/schedules/index.d.ts +11 -0
- package/dist/schedules/index.d.ts.map +1 -0
- package/dist/schedules/index.js +8 -0
- package/dist/schedules/index.js.map +1 -0
- package/dist/schedules/next-fire.d.ts +50 -0
- package/dist/schedules/next-fire.d.ts.map +1 -0
- package/dist/schedules/next-fire.js +250 -0
- package/dist/schedules/next-fire.js.map +1 -0
- package/dist/schedules/spec.d.ts +30 -0
- package/dist/schedules/spec.d.ts.map +1 -0
- package/dist/schedules/spec.js +169 -0
- package/dist/schedules/spec.js.map +1 -0
- package/dist/schedules/types.d.ts +144 -0
- package/dist/schedules/types.d.ts.map +1 -0
- package/dist/schedules/types.js +11 -0
- package/dist/schedules/types.js.map +1 -0
- package/dist/schedules/tz.d.ts +44 -0
- package/dist/schedules/tz.d.ts.map +1 -0
- package/dist/schedules/tz.js +141 -0
- package/dist/schedules/tz.js.map +1 -0
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/loader.d.ts +16 -3
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +48 -4
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/registry.d.ts +6 -0
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +1 -0
- package/dist/skills/registry.js.map +1 -1
- package/dist/tools/builtins/browser-url.d.ts +83 -0
- package/dist/tools/builtins/browser-url.d.ts.map +1 -0
- package/dist/tools/builtins/browser-url.js +240 -0
- package/dist/tools/builtins/browser-url.js.map +1 -0
- package/dist/tools/builtins/browser.d.ts +367 -0
- package/dist/tools/builtins/browser.d.ts.map +1 -0
- package/dist/tools/builtins/browser.js +704 -0
- package/dist/tools/builtins/browser.js.map +1 -0
- package/dist/tools/builtins/computer-use-coordinates.d.ts +65 -0
- package/dist/tools/builtins/computer-use-coordinates.d.ts.map +1 -0
- package/dist/tools/builtins/computer-use-coordinates.js +123 -0
- package/dist/tools/builtins/computer-use-coordinates.js.map +1 -0
- package/dist/tools/builtins/computer-use-image.d.ts +77 -0
- package/dist/tools/builtins/computer-use-image.d.ts.map +1 -0
- package/dist/tools/builtins/computer-use-image.js +223 -0
- package/dist/tools/builtins/computer-use-image.js.map +1 -0
- package/dist/tools/builtins/computer-use.d.ts +519 -14
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +1188 -183
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/index.d.ts +2 -1
- package/dist/tools/builtins/index.d.ts.map +1 -1
- package/dist/tools/builtins/index.js +1 -1
- package/dist/tools/builtins/index.js.map +1 -1
- package/dist/tools/builtins/skill.d.ts +74 -0
- package/dist/tools/builtins/skill.d.ts.map +1 -1
- package/dist/tools/builtins/skill.js +214 -159
- package/dist/tools/builtins/skill.js.map +1 -1
- package/dist/tools/defineTool.d.ts +4 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +8 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/schedules/index.d.ts +5 -0
- package/dist/tools/schedules/index.d.ts.map +1 -0
- package/dist/tools/schedules/index.js +4 -0
- package/dist/tools/schedules/index.js.map +1 -0
- package/dist/tools/schedules/loop-tool.d.ts +14 -0
- package/dist/tools/schedules/loop-tool.d.ts.map +1 -0
- package/dist/tools/schedules/loop-tool.js +81 -0
- package/dist/tools/schedules/loop-tool.js.map +1 -0
- package/dist/tools/schedules/present.d.ts +16 -0
- package/dist/tools/schedules/present.d.ts.map +1 -0
- package/dist/tools/schedules/present.js +71 -0
- package/dist/tools/schedules/present.js.map +1 -0
- package/dist/tools/schedules/prompt-scan.d.ts +17 -0
- package/dist/tools/schedules/prompt-scan.d.ts.map +1 -0
- package/dist/tools/schedules/prompt-scan.js +92 -0
- package/dist/tools/schedules/prompt-scan.js.map +1 -0
- package/dist/tools/schedules/schedule-tool.d.ts +17 -0
- package/dist/tools/schedules/schedule-tool.d.ts.map +1 -0
- package/dist/tools/schedules/schedule-tool.js +418 -0
- package/dist/tools/schedules/schedule-tool.js.map +1 -0
- package/dist/tools/schedules/types.d.ts +252 -0
- package/dist/tools/schedules/types.d.ts.map +1 -0
- package/dist/tools/schedules/types.js +11 -0
- package/dist/tools/schedules/types.js.map +1 -0
- package/dist/types/authorization/index.d.ts +107 -9
- package/dist/types/authorization/index.d.ts.map +1 -1
- package/dist/types/authorization/index.js +16 -1
- package/dist/types/authorization/index.js.map +1 -1
- package/dist/types/browser/index.d.ts +280 -0
- package/dist/types/browser/index.d.ts.map +1 -0
- package/dist/types/browser/index.js +12 -0
- package/dist/types/browser/index.js.map +1 -0
- package/dist/types/computer-use/index.d.ts +176 -0
- package/dist/types/computer-use/index.d.ts.map +1 -1
- package/dist/types/computer-use/index.js.map +1 -1
- package/dist/types/session/events.d.ts +6 -0
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +23 -0
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +9 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/tool/index.d.ts +60 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/tool/presentation.d.ts +7 -0
- package/dist/types/tool/presentation.d.ts.map +1 -1
- package/dist/utils/frontmatter.d.ts +18 -2
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +13 -3
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/id.d.ts +8 -0
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -1
- package/package.json +3 -1
- package/src/authorization/gate.ts +37 -4
- package/src/authorization/rules.ts +55 -7
- package/src/authorization/shell-lexer.ts +109 -51
- package/src/bridge/a2a/mapper.ts +2 -0
- package/src/bridge/sse/mapper.ts +1 -0
- package/src/directory/types.ts +2 -0
- package/src/pricing/catalogue.generated.ts +28 -4
- package/src/pricing/rates.source.json +27 -6
- package/src/prompt/coding-agent-doctrine.ts +1 -0
- package/src/public-runtime.ts +43 -1
- package/src/public-tools.ts +54 -1
- package/src/public-types.ts +55 -0
- package/src/registry/tool/callable.ts +37 -0
- package/src/registry/tool/execute.ts +8 -1
- package/src/runtime/query/declined.ts +12 -0
- package/src/runtime/query/executor/tool-call-admission.ts +60 -16
- package/src/runtime/query/executor.ts +36 -5
- package/src/runtime/query/index.ts +1 -0
- package/src/runtime/query/iteration/index.ts +8 -0
- package/src/runtime/query/iteration/phases/context.ts +6 -0
- package/src/runtime/query/iteration/phases/handoff.ts +74 -0
- package/src/runtime/query/iteration/phases/index.ts +1 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +11 -4
- package/src/runtime/query/resume-pending.ts +3 -2
- package/src/runtime/query/review-policy.ts +107 -18
- package/src/schedules/cron.ts +202 -0
- package/src/schedules/describe.ts +138 -0
- package/src/schedules/errors.ts +15 -0
- package/src/schedules/evaluate.ts +178 -0
- package/src/schedules/index.ts +18 -0
- package/src/schedules/next-fire.ts +257 -0
- package/src/schedules/spec.ts +210 -0
- package/src/schedules/types.ts +163 -0
- package/src/schedules/tz.ts +155 -0
- package/src/skills/index.ts +1 -1
- package/src/skills/loader.ts +55 -4
- package/src/skills/registry.ts +8 -0
- package/src/tools/builtins/browser-url.ts +251 -0
- package/src/tools/builtins/browser.ts +817 -0
- package/src/tools/builtins/computer-use-coordinates.ts +144 -0
- package/src/tools/builtins/computer-use-image.ts +278 -0
- package/src/tools/builtins/computer-use.ts +1485 -191
- package/src/tools/builtins/index.ts +7 -1
- package/src/tools/builtins/skill.ts +304 -156
- package/src/tools/defineTool.ts +13 -0
- package/src/tools/schedules/index.ts +4 -0
- package/src/tools/schedules/loop-tool.ts +85 -0
- package/src/tools/schedules/present.ts +88 -0
- package/src/tools/schedules/prompt-scan.ts +96 -0
- package/src/tools/schedules/schedule-tool.ts +482 -0
- package/src/tools/schedules/types.ts +265 -0
- package/src/types/authorization/index.ts +81 -2
- package/src/types/browser/index.ts +341 -0
- package/src/types/computer-use/index.ts +202 -0
- package/src/types/session/events.ts +6 -0
- package/src/types/session/records.ts +10 -0
- package/src/types/tool/index.ts +61 -0
- package/src/types/tool/presentation.ts +7 -0
- package/src/utils/frontmatter.ts +29 -3
- package/src/utils/id.ts +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,171 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 46.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 82769f1: `computer_use` now shows the model a screenshot sized for it and reads every coordinate as a pixel of that screenshot. On a display larger than 1568 px (or 1568 28-pixel patches) the coordinates a caller sends mean something different from before, so this is a major release.
|
|
8
|
+
|
|
9
|
+
**What changes for a caller of the tool**
|
|
10
|
+
|
|
11
|
+
- Each capture is fitted to `STANDARD_SCREENSHOT_LIMITS` (Anthropic's standard tier, within OpenAI's `detail: "high"` budget) and numbered `s1`, `s2`, …. `mouse_*`, `scroll` and `zoom` coordinates are pixels of the latest screenshot (or of `screenshot_id`) and are mapped onto the display; a coordinate outside the screenshot is refused. On a display that already fits, the mapping is the identity. To keep host pixels, pass `screenshotLimits` large enough that nothing is resized — but a model will then be sent an image its provider shrinks or rejects.
|
|
12
|
+
- Coordinate actions, `type_text` and `key` are refused until the tool instance has taken a screenshot. Call `screenshot` first.
|
|
13
|
+
- Results changed shape. An action returns `<label>: done` plus, by default, a new screenshot after 500 ms (`settleMs`, `screenshotAfterActions: false` to turn it off), in `content` with a text block first; `output` is no longer `"ok"`. `cursor_position` returns text in screenshot pixels, not JSON in host pixels. `data` carries `steps` and `screenshot` (`id`, `width`, `height`, `display`).
|
|
14
|
+
- `screenshot`, `zoom`, `cursor_position`, `wait` and `list_windows` are now read-only, so a review policy that exempts read-only calls no longer asks before them. Keep asking with an explicit `ask` rule for `computer_use`.
|
|
15
|
+
- `ActionInput` gains `zoom`, `wait`, `list_windows`, `focus_window` and `batch`, and an optional `screenshot_id`; code that switches exhaustively over `input.type` needs the new cases.
|
|
16
|
+
|
|
17
|
+
**New**
|
|
18
|
+
|
|
19
|
+
- `createComputerUseTool(host, options)` with `screenshotLimits`, `settleMs`, `screenshotAfterActions`, `maxBatchActions` (20), `maxWaitMs` (10 000) and `unavailableReason`.
|
|
20
|
+
- `{ type: "batch", actions: [...] }`: checked in full first, run in order, stopped at the first failure (which it names), one screenshot at the end.
|
|
21
|
+
- `zoom` (full-resolution crop, through `captureRegion` when the host declares `regionCapture`), `wait`, and `list_windows`/`focus_window` when the host declares `windows`.
|
|
22
|
+
- `computerUseUnavailableReason(provider)`: why a provider that cannot put an image in a tool result cannot drive the tool; pass it as `unavailableReason`.
|
|
23
|
+
- `screenshotTargetSize`, `STANDARD_SCREENSHOT_LIMITS`, `HIGH_RES_SCREENSHOT_LIMITS` and the types `ComputerUseToolOptions`, `ScreenshotLimits`, `ImageSize`.
|
|
24
|
+
- New dependencies `fast-png` and `pica` (pure JavaScript and WASM, MIT; no native build), loaded only when a capture has to be resized.
|
|
25
|
+
|
|
26
|
+
- 82769f1: `computer_use` can read a window's controls and act on them by reference, on a host that declares `uiTree` — which the Windows backend of `@namzu/computer-use` now does.
|
|
27
|
+
|
|
28
|
+
**What changes for a caller of the tool**
|
|
29
|
+
|
|
30
|
+
- Two new actions when the host declares `uiTree` and implements `uiSnapshot` and `uiAct`: `ui_snapshot { window_id? }` returns the window's accessibility tree as text, each control that can be acted on with a ref such as `e12`; `ui_act { ref, action, value? }` performs `invoke`, `set_value`, `toggle`, `select`, `expand`, `collapse`, `focus` or `scroll_into_view` on it and returns a screenshot afterwards. `ui_act` may be in a batch; `ui_snapshot` may not. Refs count up across snapshots and only the latest snapshot's are accepted, so a stale ref is refused rather than acting on another control. `ActionInput` gains both, so code that switches exhaustively over `input.type` needs two more cases — that is why this is a major release for `@namzu/sdk`.
|
|
31
|
+
- `ui_snapshot` is read-only; `ui_act` is destructive.
|
|
32
|
+
- `list_windows` now returns its window lines inside an untrusted-content frame (`<namzu-untrusted kind="desktop-windows">`), since titles are whatever each application shows. The lines themselves are unchanged; code that parsed the whole output text needs to skip the frame's three header lines.
|
|
33
|
+
- `createComputerUseTool` returns a `ComputerUseTool`, a `ToolDefinition<ActionInput>` with `describeUiRef(ref)` (experimental), which names the control a ref points at for a review screen.
|
|
34
|
+
- `UiSnapshot` gains optional `title` and `app`; `UiElement.ref` is empty for an element nothing can be done with. Both types stay experimental.
|
|
35
|
+
|
|
36
|
+
**`@namzu/computer-use`**
|
|
37
|
+
|
|
38
|
+
On Windows and WSL with the cua-driver backend, `capabilities.uiTree` is `true` and `SubprocessComputerUseHost` offers `uiSnapshot(windowId?)` and `uiAct(ref, action, value?)`, read from cua-driver's UI Automation walk. A control is invoked in the background, without moving the pointer or bringing its window to the front; a field without a settable value is typed into when it is empty. An action whose driver died mid-request comes back as not done with an unknown outcome, never retried. The PowerShell fallback and the other platforms do not declare `uiTree`, so nothing changes there.
|
|
39
|
+
|
|
40
|
+
- 82769f1: The interactive CLI now asks once per session before the model first sees your screen, and `strict` mode no longer lets a screenshot run on its own — that second part is why this is a major release for `@namzu/cli`. In `prompt`, `accept-edits` and `plan` mode the first `computer_use` call that would send the screen to the provider — a screenshot, a zoom, the list of open windows, a window's controls, or an action that returns a screenshot — opens a "Share your screen" box naming the provider; after a yes, later screenshots in that session run without asking, and clicks, typing and `ui_act` are still reviewed as before. A mode switch keeps the answer; a new session (`/new`, `/clear`, `/model`) asks again. `auto` never asks. **`strict` now refuses a screenshot unless a rule allows it**: to keep screenshots running in `strict`, add `permissions: { computer_use: 'allow' }` (which also allows clicks) or a narrower rule for the actions you want.
|
|
41
|
+
|
|
42
|
+
Approving a `ui_act` call shows the control by name (`Press Button "Beş" (e30)`), and `ui_snapshot` as the window it reads.
|
|
43
|
+
|
|
44
|
+
**`@namzu/sdk`**
|
|
45
|
+
|
|
46
|
+
- `ToolDefinition.capturesScreen?(input)` and `defineTool({ capturesScreen })` declare which calls send the operator's screen to the model provider. `computer_use` declares its observations and every action followed by a screenshot.
|
|
47
|
+
- **Breaking:** the authorization gate's `allow_read_only` rule (`allowReadOnlyTools: true`, in every shipped preset) no longer allows a call that declares `capturesScreen`; it goes to the review policy instead. With `createReviewHandler` and no `screenConsent` nothing changes (a screenshot is approved as a read); a custom `ResumeHandler` now sees `computer_use` screenshots, zooms, window lists and UI snapshots. To keep them out of review, add an explicit rule such as `{ type: 'allow_by_name', toolNames: ['computer_use'] }` (which allows clicks too).
|
|
48
|
+
- `createReviewHandler` / `createReviewPolicy` take `screenConsent: { sessions: Set<string> }` and an optional `capturesScreen(name, input)` predicate (default: the tool's declaration from `registry`). With them, the first such batch in a session is put to `prompt` with the new `ToolReviewRequest.screenConsent: true`; `strict` refuses it unless a rule allowed it, `auto` does not ask, and without a `prompt` it is refused with the new `SCREEN_CONSENT_UNATTENDED_REFUSAL`. A no is `SCREEN_CONSENT_DECLINED_FEEDBACK`. New type `ScreenConsentRecord`. Without `screenConsent` nothing changes.
|
|
49
|
+
|
|
50
|
+
### Minor Changes
|
|
51
|
+
|
|
52
|
+
- 82769f1: `ComputerUseHost` can now describe the display it captured and offer window and region operations. Everything is additive and optional, so an existing host compiles and behaves as before.
|
|
53
|
+
|
|
54
|
+
- `ScreenshotResult.display` (`DisplayInfo`: `id`, `x`, `y`, `width`, `height`, `scaleFactor`, `primary`) says which display a capture shows. Set it in a host you maintain; without it the SDK assumes one display at the origin, the size of the capture, at scale factor 1.
|
|
55
|
+
- The contract is now written down as physical pixels everywhere: action points are relative to the display last captured, window bounds are virtual-desktop pixels. A host that clicks in logical units (points, or a DPI-unaware process) must convert at its own boundary.
|
|
56
|
+
- Optional methods `listWindows()`, `focusWindow(id)` and `captureRegion(rect)` are used only when the new capability flags `windows` and `regionCapture` are `true`. `uiSnapshot()`/`uiAct()` behind `uiTree` are experimental and may change in a minor release.
|
|
57
|
+
- New exported types: `DisplayInfo`, `Rect`, `WindowInfo`, `FocusWindowResult`, `UiElement`, `UiElementAction`, `UiSnapshot`, `UiActResult`.
|
|
58
|
+
|
|
59
|
+
- 28102e1: A scheduled run can no longer reach the scheduler through a shell the command-line reader does not follow. `powershell -c 'namzu schedule stop'`, `pwsh -command '…'`, `fish -c '…'`, `tcsh -c '…'` and `bash.exe -c '…'` were allowed whatever their text held: the scheduled-run floor took any shell at the head of a command with a `-c` option as read, but only the payloads of `sh`, `bash`, `dash`, `zsh`, `ksh`, `ash` and `mksh` (and `busybox` running one) are. Such text now goes through the floor's tripwire like any other text a program runs as code. A job whose commands use those shells without naming the scheduler, `NAMZU_HOME` or the browser profiles runs as before.
|
|
60
|
+
|
|
61
|
+
SDK: new exports `nestedShellCommand(words)`, `NESTED_SHELLS` and the type `NestedShellCommand`. `nestedShellCommand` says, for one simple command's words (without its leading assignments), which `-c` payload `lexShellCommandLine` reads as a command line of its own, why it made the line opaque instead, or `null` when it reads none. The lexer uses it itself, so its reading is unchanged.
|
|
62
|
+
|
|
63
|
+
- 28102e1: A scheduled run may now run a command whose code merely mentions namzu. `powershell.exe -NoProfile -Command "[System.Windows.MessageBox]::Show('Namzu: scheduled job running','Namzu')"` was refused by the scheduled-run floor, because text passed to PowerShell, `cmd`, Python, Node or a shell reading its input was refused whenever it contained `namzu` or `schedul`. Such text is now refused only when it holds something that can reach the scheduler or `NAMZU_HOME`: a `schedule` subcommand other than `list`, `show`, `status`, `history` or `logs` with the CLI or an expansion in reach, the service's name (`namzu-scheduler…`, `com.namzu.…`), a service tool with a namzu name or a `*`, `pkill`/`killall`, `NAMZU_HOME` by name, `.namzu` as a path segment, a path into either protected folder, or `LOCALAPPDATA` with a `namzu` segment. A job that was refused for naming the product runs; nothing that reached the scheduler before is let through (checked against bash on 35 159 generated lines, and on 1 189 labelled lines of PowerShell, `cmd`, Python, Node and `sh` code).
|
|
64
|
+
|
|
65
|
+
The refusal now says which rule matched and where (`` the argument `~/.namzu/x` names NAMZU_HOME (/home/you/.namzu) ``, `` … it holds `schedule stop` (a `namzu schedule` subcommand other than …), in the argument `namzu schedule stop` ``) instead of listing everything the floor protects.
|
|
66
|
+
|
|
67
|
+
SDK: a `predicate` authorization rule may carry `describe(call)`, asked after `decide` returned a decision; its answer is the gate's reason for that call instead of the rule's fixed `description` (a `null`, empty or thrown answer keeps `description`). `describeRule(rule, call?)` takes the call as an optional second argument. Both are additions; existing rules and callers are unchanged.
|
|
68
|
+
|
|
69
|
+
- 28102e1: In the TUI, the model's `schedule` tool now lists every scheduled job, not only those of the session's folder. A model that created a job in a folder below the session's and then called `list` was told "No scheduled jobs." while `namzu schedule list` showed the job, because the TUI's host filtered by folder unless the model passed `allFolders: true`, which models do not. Jobs of the session's own folder are marked `(this folder)` and are still the only ones whose prompt the model sees.
|
|
70
|
+
|
|
71
|
+
SDK: `ScheduleJobSummary` gains an optional `inSessionFolder`, which the `schedule` tool prints as `(this folder)` on the job's `list` line. A host may use it to list every job regardless of `allFolders`. The tool still asks `host.list({ allFolders: false })` unless the model sets it, so a host that filters by folder behaves as before.
|
|
72
|
+
|
|
73
|
+
- 28102e1: The model can change a scheduled job instead of deleting and recreating it. The `schedule` tool has a new action, `update`: `job` names the job, and only the fields the model sets change (`prompt`, `when`, `folder`, `tz`, `budget`, or `permissions` as the whole new set, under the same limits as `create`). Asked whether it could change a job, a model with no such action deleted the job and created it again, and the job's history was lost.
|
|
74
|
+
|
|
75
|
+
In the TUI the operator confirms every change on one screen: what changes first (the `-`/`+` lines `namzu schedule edit` shows), a `THE PERMISSIONS CHANGE` warning when a run's rules, `unmatched`, execution or browser grant change, then the job as it will run. `Cancel` is the default. `Save` writes the same job — its id, creation time and history kept — with the operator's new confirmation, keeps a paused job paused, and records `edited by tool` with the changes in its history. A change is refused if the job was changed while the operator was being asked. Like `create`, `update` is not preceded by the ordinary permission review in `prompt`, `accept-edits` and `auto`.
|
|
76
|
+
|
|
77
|
+
SDK: `ScheduleToolHost` gains three optional methods, `previewUpdate(job, changes)`, `confirmUpdate(request, signal?)` and `update(preview)`, and new types `ScheduleJobChanges`, `ScheduleJobUpdateProposal` and `ScheduleUpdateRequest`. A host without them keeps working: the tool refuses `update` there and tells the model not to delete and recreate the job.
|
|
78
|
+
|
|
79
|
+
- 28102e1: The `skill` tool can tell the model which directory a skill's files are in (#536).
|
|
80
|
+
|
|
81
|
+
New `createSkillTool({ resolveModelDirectory })`, with the types `SkillToolOptions`, `SkillDirectoryResolver`, `SkillDirectoryRequest` and `SkillDirectoryContext`. `resolveModelDirectory(skill, { sandbox })` receives the registered name and the directory the host reads the skill from, and returns the directory the model's tools can open, or `undefined` when they cannot reach one. With it:
|
|
82
|
+
|
|
83
|
+
- a load opens with `[Skill directory: <dir>. …]` on its first page and reports `data.directory`; when the resolver answers `undefined` it says instead that the skill's directory is not reachable in this session and not to search the filesystem for it;
|
|
84
|
+
- the listing (`skill` without a name) gives each skill's `directory` and no longer the registry's `location`, which is the host's path;
|
|
85
|
+
- `${CLAUDE_SKILL_DIR}` in `allowed-tools` expands to the resolver's directory, and an entry using it is ignored when there is none.
|
|
86
|
+
|
|
87
|
+
The skill is still loaded from the registry's own path. `SkillTool` is `createSkillTool()` and behaves exactly as before, so nothing changes unless you pass the option. `SkillRegistryRef.catalog()` entries may now carry an optional `directory`, and `SkillRegistry.catalog()` sets it to the skill's directory; a registry that omits it still satisfies the interface.
|
|
88
|
+
|
|
89
|
+
### Patch Changes
|
|
90
|
+
|
|
91
|
+
- 28102e1: The two errors that tell a model which tools it can use now give the same list: the tools the current step can call, meaning registered, active and allowed by `allowedTools` or `prepareStep`. Before, they could send a model back and forth between them until the run was stopped. A call refused as `Tool "X" is not available on this step` repeated the step's allow-list word for word. That list is taken when the request is built, so it could name a tool unregistered since (a connector that disconnected) or one that is deferred or suspended. A call to a name the registry does not hold listed the whole registry, including the tools the step refuses.
|
|
92
|
+
|
|
93
|
+
That second error now reads `Unknown tool "X". Available: …` instead of `Unknown or unavailable tool "X": Not found: "X". Available: …`. `(none)` means the step can call nothing. This applies to a model's direct call, to a batch run without review preparation, and to a call a tool makes through `ToolContext.dispatchTool` (such as `run_code`). `ToolCallRepairContext.message` for `unknown_tool` carries the new wording; `availableTools` still lists every registered tool. No exported types change. Code that parses the old `Not found` wording out of a tool result must look for the new wording instead.
|
|
94
|
+
|
|
95
|
+
- 82769f1: `computer_use` clicks and drags with the left button when a call leaves `button` out, instead of refusing the call (a model asked to click the Start button sent no button and spent a round trip on the refusal). Its description now tells the model to batch the steps it can predict but to look before typing into a window a step should have opened, and, on Windows, that a shell command is the surest way to start a program (Start-menu search on a non-English Windows turned an English program name into a web search in the browser).
|
|
96
|
+
|
|
97
|
+
With a host that lists windows (the Windows cua-driver backend), `type_text` and `key` are refused while a terminal is in front: in a real session a key chord that did not open the Run dialog sent "notepad" and ENTER into the user's own terminal and submitted what they were typing. A call that types into a terminal on purpose now fails with that reason; bring the target window to the front first, or run the command through a shell tool. With a host that reads controls, the first screenshot says so. No change is needed on your side.
|
|
98
|
+
|
|
99
|
+
- 28102e1: `claude-opus-5-5`, `claude-fable-5-1` and `claude-mythos-5-1` now have prices in the built-in catalogue. Before, their tokens were reported as unpriced. A turn that set `turnConfig.costLimitUsd` without its own `pricing` table was refused at the start on these models, or stopped with `cost_unmeasurable` when it reached one through a step or a fallback.
|
|
100
|
+
|
|
101
|
+
The rates are the vendor's list prices per million tokens:
|
|
102
|
+
|
|
103
|
+
| Model | Input | Output | Cache read | Cache write (5 min) |
|
|
104
|
+
| --------------------------------------- | ----- | ------ | ---------- | ------------------- |
|
|
105
|
+
| `claude-opus-5-5` | $4 | $20 | $0.20 | $5 |
|
|
106
|
+
| `claude-fable-5-1`, `claude-mythos-5-1` | $10 | $50 | $0.25 | $12.50 |
|
|
107
|
+
|
|
108
|
+
On these three models a cache read costs less than the usual 0.1x of input: 0.05x on Opus 5.5, 0.025x on the 5.1 pair. The catalogue has one write rate, the five-minute one the Anthropic driver requests, so the one-hour rates ($8 and $20) are not represented. Nothing to change on your side.
|
|
109
|
+
|
|
110
|
+
- 28102e1: `claude-sonnet-5` is priced at $2 input and $10 output per million tokens, with $0.20 for a cache read and $2.50 for a five-minute cache write. The catalogue had $3 / $15 / $0.30 / $3.75. That was the increase the vendor scheduled for 2026-09-01 and then cancelled; $2 / $10 is now its standard price.
|
|
111
|
+
|
|
112
|
+
What changes for you: a Sonnet 5 turn reports two-thirds of the cost it reported before. A `turnConfig.costLimitUsd` set against Sonnet 5 now allows about 1.5 times as many tokens before it stops the turn. To keep the old ceiling, lower the limit to two-thirds of its value, or pass your own `pricing` table.
|
|
113
|
+
|
|
114
|
+
## 45.1.0
|
|
115
|
+
|
|
116
|
+
### Minor Changes
|
|
117
|
+
|
|
118
|
+
- 2b96136: Add the browser tool contract, let `argument_pattern` rules ask for review, and let a scheduled-job proposal carry a browser grant.
|
|
119
|
+
|
|
120
|
+
**Browser tools (new).** `createBrowserTools(host)` returns two tools over a `BrowserHost` you supply: `browser` (navigate, back, forward, reload, snapshot, screenshot, scroll, wait_for, tabs) and `browser_act` (click, type, fill_form, select, press, hover, upload, dialog). The SDK ships no browser engine. Every `browser_act` call carries a required `origin`, and the host contract says the host compares it with the live page before acting. `url` and `origin` are canonicalised by the input schema (WHATWG form, punycode, no default port, no trailing dot on the host). Other schemes, credentials in the URL and cloud metadata addresses in any spelling are refused. Because the gate sees the canonical value, a site rule matches the address the browser loads. Page text is returned inside `wrapUntrusted`, under a `Page: <origin> — "<title>" (tab tN)` header. Hosts refuse by throwing structural shapes (`browser_origin_mismatch`, `browser_stale_ref`, `browser_human_required`, `browser_outcome_unknown`, `browser_site_denied`). New exports: `createBrowserTools`, `BROWSER_TOOL_NAME`, `BROWSER_ACT_TOOL_NAME`, `isBrowserCallReadOnly`, `browserHostErrorOf`, `formatBrowserPageHeader`, `canonicalizeBrowserUrl`, `canonicalizeBrowserOrigin`, `canonicalizeBrowserSitePattern`, `isCloudMetadataHost`, `BROWSER_URL_MAX_LENGTH`, `BROWSER_SNAPSHOT_MAX_CHARS`, `BROWSER_WAIT_MAX_MS`, `BROWSER_FILL_FORM_MAX_FIELDS`, and the types in their signatures (`BrowserHost`, `BrowserCapabilities`, the action, result and error types). Both tools are `category: 'network'`. Do not pair them with a preset that allows network tools by category because a sandbox confines egress: the browser runs outside the sandbox.
|
|
121
|
+
|
|
122
|
+
**`argument_pattern` with `decision: 'review'` (widened union).** `AuthorizationRule`'s `argument_pattern` variant now accepts `'review'`. It matches as `deny` does: the whole value, then every segment of a command line. Code that switches exhaustively over that variant's `decision`, or narrows it to `'allow' | 'deny'`, needs a `review` branch. Existing rules behave as before.
|
|
123
|
+
|
|
124
|
+
**`ToolDefinition.urlArgument` (new, optional).** A tool whose input schema canonicalises an argument to a URL can declare it. An `argument_pattern` rule on that argument then tests the value whole, instead of cutting it at `&`, `;` or `|` as a command line, which made an `allow` for a site decline every address with a query string. Tools that do not declare it are unchanged. `defineTool` accepts it too.
|
|
125
|
+
|
|
126
|
+
**Reason text.** A `custom_pattern` rule with `decision: 'review'` is now described as `sent for review by a pattern rule …`; it used to say `allowed by …`. If you match on the old text, update the match.
|
|
127
|
+
|
|
128
|
+
**Scheduled jobs.** `ScheduleJobDraft.permissions.browser?: ScheduleBrowserGrant` (`profile`, `sites` mapping each site to `read`, `ask` or `act`, `headed?`) and `ScheduleToolHost.browserGrants?: boolean` are new. The `schedule` tool refuses a proposed browser grant unless your host sets `browserGrants: true`, so a host that does not know the field keeps working unchanged and never silently drops a grant. It canonicalises site keys and refuses `*`. It also treats the grant as network access, so the grant is refused beside a shell on the host. The refusal for web access beside a host shell now says "web or browser access".
|
|
129
|
+
|
|
130
|
+
See `docs/sdk/browser-tools.md` and `docs/sdk/review-policy.md#rules-that-ask`.
|
|
131
|
+
|
|
132
|
+
- 2b96136: A generic tool result view may now set `outcome: 'cancelled'` for a call the person declined on the tool's own screen. `save_skill` and the `schedule` tool's `create`, `resume` and `delete` use it (the `schedule` tool also sets `data.cancelled` on those results), and the TUI shows the row as `○ … Cancelled — nothing was saved` instead of `✗ … failed: Error: The operator cancelled`. The model still receives the same refusal text.
|
|
133
|
+
- 2b96136: A tool call a person declines without giving a reason now tells the model not to get the same content or result another way — another tool, another site or address, or a web search — unless it asks first and the person agrees. The text was "User declined to run the proposed tool(s)." (and "The user rejected this tool call." on a resumed decision); in a live session a model whose browser navigation was declined fetched the same page through web search instead.
|
|
134
|
+
|
|
135
|
+
New export: `DECLINED_TOOL_CALL_FEEDBACK`, the text. A host that passes its own `feedback` with a refusal is unchanged. A test or host that matched the old default text must match the new one.
|
|
136
|
+
|
|
137
|
+
- d233f26: Add a `predicate` authorization rule, and export the command-line lexer the gate uses.
|
|
138
|
+
|
|
139
|
+
- `AuthorizationRule` gains `{ type: 'predicate', description, decide }`. `decide(call)` receives the tool name, input, definition and the `commandDialect` the line runs in (`sh` when the caller did not say) and returns `allow`, `deny`, `review` or `null`; it sits in its place in the rule list, after the dangerous-command floor. A `decide` that throws is read as `deny`. New types `AuthorizationPredicate` and `AuthorizationPredicateCall`.
|
|
140
|
+
- `lexShellCommandLine` is exported, with `ShellLexResult`, `ShellCommand`, `ShellWord`, `ShellRedirection` and `ShellLexOptions`, so a predicate reads a command line exactly as the gate does.
|
|
141
|
+
- A lexer result also reports `compoundWords` (a `for` or `select` loop's variable and list, a `case` statement's subject and patterns) and, on a here-document redirection, its `body`.
|
|
142
|
+
|
|
143
|
+
Nothing existing changes behaviour. `AuthorizationRule` is also the type of `GateEvaluationResult.matchedRule`: code that switches over `rule.type` with an exhaustive check (`const x: never = rule`) needs a `predicate` case or a `default:` branch to compile.
|
|
144
|
+
|
|
145
|
+
- 2b96136: `ScheduleToolHost.create()` may return an optional `note`, which the `schedule` tool appends to what the model is told about the new job. Existing hosts that return only `{ name }` are unaffected. The CLI uses it to tell the model that no scheduler is installed, so its reply no longer promises a run that cannot happen until you run `namzu schedule install`.
|
|
146
|
+
- d233f26: Add a schedule time engine and evaluator, and the `schedule` and `session_loop` tools.
|
|
147
|
+
|
|
148
|
+
New exports, all additive: `parseScheduleSpec`, `parseCronExpression`, `nextFireTime`, `previousFireTime`, `upcomingFireTimes`, `countOccurrences`, `describeSchedule`, `validateTimeZone`, `hostTimeZone`, `parseDuration`, `evaluateJob`, `ScheduleValidationError`, `SCHEDULE_CATCH_UP_WINDOW_MS`, `SCHEDULE_LATE_GRACE_MS`, `buildScheduleTools`, `buildSessionLoopTools`, `scanSchedulePrompt`, `revealHiddenCharacters`, `SCHEDULE_TOOL_NAME`, `SESSION_LOOP_TOOL_NAME`, `generateScheduleJobId`, `generateScheduleRunId`, and the types in their signatures (`ScheduleSpec` and its three variants, `CronExpression`, `ScheduleEvaluationInput`, `ScheduleDecision`, `ScheduleSkipReason`, `ScheduleMissedReason`, `ScheduleToolHost`, `ScheduleJobDraft`, `ScheduleJobPreview`, `SessionLoopHost`, `SessionLoop` and their neighbours).
|
|
149
|
+
|
|
150
|
+
Everything here is pure: `Intl` for time zones, no clock, no I/O, no new dependency. Cron follows cronie's DST rule (a fixed-time job fires once across a change; a wildcard job fires at every matching instant). Nothing existing changes. `ScheduleDecision`, `ScheduleSkipReason` and `ScheduleMissedReason` may gain members in a later minor release, so switch over them with a `default:` branch. See `docs/sdk/schedules.md`.
|
|
151
|
+
|
|
152
|
+
- 2b96136: `loadSkill` (and so `SkillRegistry`) skips frontmatter keys it does not read, whatever YAML they are written in, instead of refusing the whole file: a `SKILL.md` carrying `argument-hint: [file]` or a `hooks:` block with a list now loads with those fields ignored. The keys it does read are still parsed strictly; they are exported as `SKILL_FRONTMATTER_KEYS`. `disable-model-invocation: true` now reads as `invocation: operator`; a value other than `true` or `false`, or one that contradicts an explicit `invocation`, refuses the file. `parseFrontmatter` takes an optional third argument, `{ readsKey }`, to get the same leniency for a caller's own vocabulary; without it every key is parsed and refused as before. A skill file that used to be refused over an unread key now loads, and one with `disable-model-invocation: true` is no longer offered to the model — nothing else changes.
|
|
153
|
+
- 2b96136: A tool can now stop the turn for a person: return `handoff: { kind: 'human-required', reason, detail? }` on its `ToolResult` (new type `ToolHandoff`). The kernel commits the batch's results, writes a checkpoint and ends the segment with `turn_paused` instead of calling the model again. The event and its session-log record carry the new optional `handoff` field, and the SSE (`turn.paused`) and A2A bridges forward it. `resumeSession` continues the turn from that checkpoint as it does after a provider pause, with a model call that sees the results. In a delegated child (a turn with `parentSessionId`) the handoff fails the child's turn with a non-retryable `tool_error` naming the reason, so the parent receives a failed child result.
|
|
154
|
+
|
|
155
|
+
Nothing changes for tools that do not set the field. A consumer that switches exhaustively on `turn_paused` fields, or validates session-log records with its own strict schema, should accept `handoff`.
|
|
156
|
+
|
|
157
|
+
### Patch Changes
|
|
158
|
+
|
|
159
|
+
- 2b96136: The `browser` tool's `cursor` field tells the model it is only the `nextCursor` a previous snapshot returned, to be left out for the top of the page, and never a URL. A model passed the page's address as the cursor and got a refusal before it could read the page.
|
|
160
|
+
- 2b96136: A `browser_human_required` refusal from a browser host now pauses the turn. The browser tools set `ToolResult.handoff` (`reason` in words such as `https://github.com is showing a sign-in page`; `detail` carries `tool: 'browser'`, `cause`, `origin`, `profile` and `loginCommand`) as well as `data.handoff`, so the kernel stops before the next model call and waits for the person, as it does for any tool handoff. Before this, the model read the refusal and carried on. Nothing changes for other refusals.
|
|
161
|
+
- 2b96136: The coding-agent working doctrine now tells the model never to change git configuration (`user.name`/`user.email`, hooks, remotes, credential helpers) or other persistent settings without asking. When a commit fails because no identity is set, it tells you the command instead of inventing an identity.
|
|
162
|
+
- 2b96136: The `schedule` tool's input schema now says that `budget` limits one run and that `maxIterations` counts model steps, not repetitions of the job. A model proposed `maxIterations: 1` for a job meant to post once per run, and every run stopped after its first model call. The CLI's confirmation of a job, on a terminal or in the TUI, warns when it allows fewer than 10 iterations.
|
|
163
|
+
- 2b96136: The `schedule` tool asks the model to leave optional fields (folder, time zone, execution, budget, a visible browser window) unset unless the user asked for them, and the TUI's confirmation of a proposed job marks every such value the model set that differs from what you would get by default, e.g. `Chosen by the model, not the default: time zone America/New_York, not this machine's Europe/Istanbul`.
|
|
164
|
+
- 2b96136: A job the model proposes, resumes or deletes in the TUI is confirmed once, on the job's own screen. The permission review no longer asks "Do you want to run schedule?" first in `prompt`, `accept-edits` or `auto`. `plan` and `strict` still refuse the call, a `schedule` rule of `ask` or `deny` still applies, and `pause` is still reviewed. The SDK's `schedule` tool no longer declares `delete` destructive, since the host confirms it before anything is removed; a host that relied on that flag to review deletes should add an `ask` rule for `schedule`.
|
|
165
|
+
- 2b96136: The `schedule` tool no longer refuses a proposal that uses the `read-only` preset with web or browser access as "a shell on the host". The preset denies `bash`, but the check looked only at explicit rules and `unmatched`, so `{ preset: 'read-only', unmatched: 'park', browser: … }` was refused. A proposal with `edit-in-folder`, or with a `bash` rule that is not `deny`, is still refused.
|
|
166
|
+
- 2b96136: The `schedule` tool's input schema describes `budget.tokenBudget` as what the whole run may spend, with every model call resending the prompt, and the CLI's confirmation of a job warns when it allows fewer than 50 000 tokens. A model proposed 4 000 tokens for a browser job whose runs each took about 110 000.
|
|
167
|
+
- 2b96136: The `skill` tool now presents its calls as `Read skill <name>` (or `List skills`) and hides a successful result, so a host shows one row instead of the raw input and the skill's body. In the TUI, the Working row says `Waiting for you` while the screen that saves a skill is open, instead of counting on as if the turn were working.
|
|
168
|
+
|
|
3
169
|
## 45.0.0
|
|
4
170
|
|
|
5
171
|
### Major Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthorizationGateConfig, AuthorizationRule, GateEvaluationResult } from '../types/authorization/index.js';
|
|
1
|
+
import type { AuthorizationGateConfig, AuthorizationPredicateCall, AuthorizationRule, GateEvaluationResult } from '../types/authorization/index.js';
|
|
2
2
|
import type { ToolDefinition } from '../types/tool/index.js';
|
|
3
3
|
import type { Logger } from '../utils/logger.js';
|
|
4
4
|
import type { ShellDialect } from './shell-lexer.js';
|
|
@@ -27,8 +27,11 @@ export interface ToolCallContext {
|
|
|
27
27
|
* `git push*`, it can stop, say so, and do something else. A refusal that
|
|
28
28
|
* cannot be reasoned about produces thrashing; one that can produces a route
|
|
29
29
|
* around it.
|
|
30
|
+
*
|
|
31
|
+
* `call`, when given, is the call the rule decided: a `predicate` rule with a
|
|
32
|
+
* `describe` says what in it matched, instead of its fixed `description`.
|
|
30
33
|
*/
|
|
31
|
-
export declare function describeRule(rule: AuthorizationRule): string;
|
|
34
|
+
export declare function describeRule(rule: AuthorizationRule, call?: AuthorizationPredicateCall): string;
|
|
32
35
|
export declare class AuthorizationGate {
|
|
33
36
|
private readonly rules;
|
|
34
37
|
private readonly compiledPatterns;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,iCAAiC,CAAA;AAExC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,CAAA;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,uBAAuB,EACvB,0BAA0B,EAC1B,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,iCAAiC,CAAA;AAExC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,CAAA;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,0BAA0B,GAAG,MAAM,CAoD/F;AAED,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM;IAiHxD,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,oBAAoB;CAkEpD"}
|
|
@@ -17,8 +17,11 @@ import { evaluateRule } from './rules.js';
|
|
|
17
17
|
* `git push*`, it can stop, say so, and do something else. A refusal that
|
|
18
18
|
* cannot be reasoned about produces thrashing; one that can produces a route
|
|
19
19
|
* around it.
|
|
20
|
+
*
|
|
21
|
+
* `call`, when given, is the call the rule decided: a `predicate` rule with a
|
|
22
|
+
* `describe` says what in it matched, instead of its fixed `description`.
|
|
20
23
|
*/
|
|
21
|
-
export function describeRule(rule) {
|
|
24
|
+
export function describeRule(rule, call) {
|
|
22
25
|
switch (rule.type) {
|
|
23
26
|
case 'deny_dangerous_patterns':
|
|
24
27
|
return 'this matches a pattern the operator refuses outright; rewording it will not help';
|
|
@@ -36,14 +39,34 @@ export function describeRule(rule) {
|
|
|
36
39
|
// Names the argument, not just the pattern. That is what tells a
|
|
37
40
|
// model whether a different value could get through — which is the
|
|
38
41
|
// difference between rewording once and rewording forever.
|
|
39
|
-
const verb = rule.decision === 'deny'
|
|
42
|
+
const verb = rule.decision === 'deny'
|
|
43
|
+
? 'denied'
|
|
44
|
+
: rule.decision === 'review'
|
|
45
|
+
? 'sent for review'
|
|
46
|
+
: 'allowed';
|
|
40
47
|
return `${verb} because the \`${rule.argument}\` argument matched ${rule.pattern} (this rule applies to ${rule.toolNames.join(', ')})`;
|
|
41
48
|
}
|
|
42
49
|
case 'custom_pattern': {
|
|
43
50
|
const where = rule.target === 'both' ? 'name or arguments' : rule.target;
|
|
44
|
-
const verb = rule.decision === 'deny'
|
|
51
|
+
const verb = rule.decision === 'deny'
|
|
52
|
+
? 'denied'
|
|
53
|
+
: rule.decision === 'review'
|
|
54
|
+
? 'sent for review'
|
|
55
|
+
: 'allowed';
|
|
45
56
|
return `${verb} by a pattern rule matching the ${where}: ${rule.pattern}`;
|
|
46
57
|
}
|
|
58
|
+
case 'predicate': {
|
|
59
|
+
if (call === undefined || rule.describe === undefined)
|
|
60
|
+
return rule.description;
|
|
61
|
+
// A reason that cannot be computed is no reason to lose the
|
|
62
|
+
// refusal: the fixed one still says what the rule is.
|
|
63
|
+
try {
|
|
64
|
+
return rule.describe(call) || rule.description;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return rule.description;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
47
70
|
default: {
|
|
48
71
|
const exhaustive = rule;
|
|
49
72
|
return `matched an unrecognised rule: ${JSON.stringify(exhaustive)}`;
|
|
@@ -180,7 +203,15 @@ export class AuthorizationGate {
|
|
|
180
203
|
const result = {
|
|
181
204
|
decision,
|
|
182
205
|
matchedRule: rule,
|
|
183
|
-
reason:
|
|
206
|
+
reason: rule.type === 'predicate'
|
|
207
|
+
? describeRule(rule, {
|
|
208
|
+
toolName: ctx.toolName,
|
|
209
|
+
toolInput: ctx.toolInput,
|
|
210
|
+
toolDef: ctx.toolDef,
|
|
211
|
+
// What `evaluateRule` told `decide`.
|
|
212
|
+
commandDialect: ctx.commandDialect ?? 'sh',
|
|
213
|
+
})
|
|
214
|
+
: describeRule(rule),
|
|
184
215
|
};
|
|
185
216
|
if (this.logDecisions) {
|
|
186
217
|
this.log.debug('Gate decision', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAA;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED,wBAAgB,YAAY,CAC3B,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,eAAe,CAAC,EAAE,MAAM,EACxB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,OAAO,GAAE,mBAAwB,GAC/B,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED,wBAAgB,YAAY,CAC3B,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,eAAe,CAAC,EAAE,MAAM,EACxB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,OAAO,GAAE,mBAAwB,GAC/B,YAAY,GAAG,IAAI,CA0LrB"}
|
|
@@ -23,6 +23,14 @@ export function evaluateRule(rule, toolName, toolInput, toolDef, compiledPattern
|
|
|
23
23
|
const category = toolDef?.category;
|
|
24
24
|
if (category && rule.excludeCategories?.includes(category))
|
|
25
25
|
return null;
|
|
26
|
+
// A read that sends the operator's screen to the model provider is
|
|
27
|
+
// the one read a person may want to allow first
|
|
28
|
+
// (`ToolDefinition.capturesScreen`). It falls through to the review
|
|
29
|
+
// policy, which asks once per session when the host keeps a consent
|
|
30
|
+
// record and approves it as the read it is otherwise. An explicit
|
|
31
|
+
// allow rule for the tool still allows it here.
|
|
32
|
+
if (capturesScreen(toolDef, toolInput))
|
|
33
|
+
return null;
|
|
26
34
|
return 'allow';
|
|
27
35
|
}
|
|
28
36
|
case 'deny_dangerous_patterns': {
|
|
@@ -103,20 +111,35 @@ export function evaluateRule(rule, toolName, toolInput, toolDef, compiledPattern
|
|
|
103
111
|
// A command line is not one string, and testing it as one is how a
|
|
104
112
|
// prohibition gets bypassed: `^git push` sees `git push origin main`
|
|
105
113
|
// and does not see `true; git push origin main`. See
|
|
106
|
-
// `decomposeCommandLine` for the measurement and for why the
|
|
114
|
+
// `decomposeCommandLine` for the measurement and for why the
|
|
107
115
|
// decisions must read the result differently.
|
|
108
|
-
|
|
109
|
-
|
|
116
|
+
//
|
|
117
|
+
// An argument the tool declares as a canonical URL is not a command
|
|
118
|
+
// line, and cutting it at `&` would make an `allow` for a site
|
|
119
|
+
// decline every address with a query string. See
|
|
120
|
+
// `ToolDefinition.urlArgument`.
|
|
121
|
+
const isUrl = toolDef?.urlArgument === rule.argument;
|
|
122
|
+
const { segments, opaque } = isUrl
|
|
123
|
+
? { segments: [subject], opaque: false }
|
|
124
|
+
: decomposeCommandLine(subject, dialect);
|
|
125
|
+
if (rule.decision === 'deny' || rule.decision === 'review') {
|
|
110
126
|
// ANY segment. The whole subject is tested first so an
|
|
111
127
|
// unanchored deny keeps matching across a boundary, which
|
|
112
128
|
// splitting alone would have taken away. Then each command's
|
|
113
129
|
// words as bash passes them, so that `'git' push` is `git push`.
|
|
130
|
+
//
|
|
131
|
+
// `review` reads like `deny`, because it is a restriction too: a
|
|
132
|
+
// rule that asks before `git push` must ask before
|
|
133
|
+
// `true; git push` as well. Matching too much costs a prompt;
|
|
134
|
+
// matching too little skips the question the operator asked for.
|
|
114
135
|
if (compiledPattern.test(subject))
|
|
115
|
-
return
|
|
136
|
+
return rule.decision;
|
|
116
137
|
if (segments.some((segment) => compiledPattern.test(segment)))
|
|
117
|
-
return
|
|
138
|
+
return rule.decision;
|
|
139
|
+
if (isUrl)
|
|
140
|
+
return null;
|
|
118
141
|
return decodedCommands(subject, dialect).some((text) => compiledPattern.test(text))
|
|
119
|
-
?
|
|
142
|
+
? rule.decision
|
|
120
143
|
: null;
|
|
121
144
|
}
|
|
122
145
|
// EVERY segment, and nothing that hides one. Permission is a claim
|
|
@@ -133,10 +156,37 @@ export function evaluateRule(rule, toolName, toolInput, toolDef, compiledPattern
|
|
|
133
156
|
}
|
|
134
157
|
return null;
|
|
135
158
|
}
|
|
159
|
+
case 'predicate': {
|
|
160
|
+
// A rule that throws has not decided the call is safe. Reading the
|
|
161
|
+
// exception as "no opinion" would let the next rule, or the mode,
|
|
162
|
+
// approve what this one was written to refuse.
|
|
163
|
+
try {
|
|
164
|
+
return rule.decide({
|
|
165
|
+
toolName,
|
|
166
|
+
toolInput,
|
|
167
|
+
toolDef,
|
|
168
|
+
commandDialect: dialect,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return 'deny';
|
|
173
|
+
}
|
|
174
|
+
}
|
|
136
175
|
default: {
|
|
137
176
|
const _exhaustive = rule;
|
|
138
177
|
throw new Error(`Unhandled verification rule type: ${_exhaustive.type}`);
|
|
139
178
|
}
|
|
140
179
|
}
|
|
141
180
|
}
|
|
181
|
+
function capturesScreen(toolDef, toolInput) {
|
|
182
|
+
if (!toolDef?.capturesScreen)
|
|
183
|
+
return false;
|
|
184
|
+
try {
|
|
185
|
+
return toolDef.capturesScreen(toolInput);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// A declaration that cannot answer is not trusted to say "no".
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
142
192
|
//# sourceMappingURL=rules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -81,6 +81,13 @@ export interface ShellRedirection {
|
|
|
81
81
|
readonly fd?: string;
|
|
82
82
|
/** The target word. For a here-document, its delimiter. */
|
|
83
83
|
readonly target: ShellWord;
|
|
84
|
+
/**
|
|
85
|
+
* A here-document's body as written, up to its delimiter line, once the
|
|
86
|
+
* lexer has read it: the text the command reads on its input, which is
|
|
87
|
+
* a command line of its own when the command is a shell (`bash <<EOF`).
|
|
88
|
+
* Absent for every other operator and for a body the line never reached.
|
|
89
|
+
*/
|
|
90
|
+
readonly body?: string;
|
|
84
91
|
}
|
|
85
92
|
/** One simple command. */
|
|
86
93
|
export interface ShellCommand {
|
|
@@ -114,6 +121,13 @@ export interface ShellLexResult {
|
|
|
114
121
|
* (`{ a; } > f`) that belong to no single simple command.
|
|
115
122
|
*/
|
|
116
123
|
readonly redirections: readonly ShellRedirection[];
|
|
124
|
+
/**
|
|
125
|
+
* Words that belong to no simple command: a `for` or `select` loop's
|
|
126
|
+
* variable and the words of its list, and a `case` statement's subject
|
|
127
|
+
* and patterns. `for d in ~/x; do rm -r "$d"; done` passes `~/x` to `rm`
|
|
128
|
+
* although no command lists it.
|
|
129
|
+
*/
|
|
130
|
+
readonly compoundWords: readonly ShellWord[];
|
|
117
131
|
/** True when {@link commands} may not be everything the line runs. */
|
|
118
132
|
readonly opaque: boolean;
|
|
119
133
|
/** False when parsing stopped early: a syntax error or an unsupported construct. */
|
|
@@ -127,6 +141,30 @@ export interface ShellLexResult {
|
|
|
127
141
|
* is a close approximation, and the line is only as exact as that.
|
|
128
142
|
*/
|
|
129
143
|
export declare const NESTED_SHELLS: ReadonlySet<string>;
|
|
144
|
+
/** What {@link nestedShellCommand} found: the payload the lexer reads, or why it could not. */
|
|
145
|
+
export type NestedShellCommand = {
|
|
146
|
+
/** The shell's basename, one of {@link NESTED_SHELLS}. */
|
|
147
|
+
readonly shell: string;
|
|
148
|
+
/** The `-c` argument, read as a command line of its own. */
|
|
149
|
+
readonly payload: ShellWord;
|
|
150
|
+
} | {
|
|
151
|
+
/** Why the lexer calls the line opaque instead (`nested shell option` …). */
|
|
152
|
+
readonly opaque: string;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Whether the lexer reads a simple command's payload as a command line of
|
|
156
|
+
* its own: `words` are the command's words without its leading assignments.
|
|
157
|
+
* The command must start a shell in {@link NESTED_SHELLS} by basename,
|
|
158
|
+
* exactly as written (`bash`, `/bin/sh`; not `bash.exe`, `BASH` or `fish`),
|
|
159
|
+
* or `busybox` running one, with `-c` among its options; the payload is the
|
|
160
|
+
* first argument that is not an option. `null` when it reads no payload.
|
|
161
|
+
*
|
|
162
|
+
* A host deciding on {@link lexShellCommandLine}'s reading uses this to know
|
|
163
|
+
* which text that reading already includes. Every other text a program runs
|
|
164
|
+
* as code — `powershell -c '…'`, `fish -c '…'`, `bash.exe -c '…'`, a script
|
|
165
|
+
* — is not in it.
|
|
166
|
+
*/
|
|
167
|
+
export declare function nestedShellCommand(words: readonly ShellWord[]): NestedShellCommand | null;
|
|
130
168
|
import type { ShellDialect } from '../types/tool/index.js';
|
|
131
169
|
export type { ShellDialect };
|
|
132
170
|
export interface ShellLexOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-lexer.d.ts","sourceRoot":"","sources":["../../src/authorization/shell-lexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACzB,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAChC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"shell-lexer.d.ts","sourceRoot":"","sources":["../../src/authorization/shell-lexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACzB,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAChC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAClD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,CAAA;IAClD,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,cAAc;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;IAC1C;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAClD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,SAAS,SAAS,EAAE,CAAA;IAC5C,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAQ5C,CAAA;AAEF,+FAA+F;AAC/F,MAAM,MAAM,kBAAkB,GAC3B;IACA,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;CAC1B,GACD;IACA,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACtB,CAAA;AAEJ;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,kBAAkB,GAAG,IAAI,CAsCzF;AAOD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,MAAM,WAAW,eAAe;IAC/B,sBAAsB;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAA;CAC/B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAmB/F;AAqkED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C"}
|