@namzu/cli 29.1.0 → 32.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 +296 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/acp.d.ts +20 -2
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/acp.js +42 -5
- package/dist/commands/acp.js.map +1 -1
- package/dist/commands/drain.d.ts.map +1 -1
- package/dist/commands/drain.js +2 -1
- package/dist/commands/drain.js.map +1 -1
- package/dist/commands/exec-json.d.ts.map +1 -1
- package/dist/commands/exec-json.js +24 -1
- package/dist/commands/exec-json.js.map +1 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +5 -1
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/prior-messages.d.ts.map +1 -1
- package/dist/commands/prior-messages.js +42 -2
- package/dist/commands/prior-messages.js.map +1 -1
- package/dist/commands/schedule.d.ts.map +1 -1
- package/dist/commands/schedule.js +7 -5
- package/dist/commands/schedule.js.map +1 -1
- package/dist/config/composer-triggers.d.ts +41 -0
- package/dist/config/composer-triggers.d.ts.map +1 -0
- package/dist/config/composer-triggers.js +80 -0
- package/dist/config/composer-triggers.js.map +1 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +58 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/context/doctrine.d.ts +3 -3
- package/dist/context/doctrine.d.ts.map +1 -1
- package/dist/context/doctrine.js +3 -3
- package/dist/context/doctrine.js.map +1 -1
- package/dist/context/environment.d.ts +26 -3
- package/dist/context/environment.d.ts.map +1 -1
- package/dist/context/environment.js +68 -9
- package/dist/context/environment.js.map +1 -1
- package/dist/context/runtime-message.d.ts.map +1 -1
- package/dist/context/runtime-message.js +4 -0
- package/dist/context/runtime-message.js.map +1 -1
- package/dist/integrations/mcp/servers.d.ts +72 -5
- package/dist/integrations/mcp/servers.d.ts.map +1 -1
- package/dist/integrations/mcp/servers.js +144 -23
- package/dist/integrations/mcp/servers.js.map +1 -1
- package/dist/integrations/notifications/desktop.d.ts +2 -0
- package/dist/integrations/notifications/desktop.d.ts.map +1 -1
- package/dist/integrations/notifications/desktop.js +6 -5
- package/dist/integrations/notifications/desktop.js.map +1 -1
- package/dist/integrations/plugins/runtime.d.ts +10 -2
- package/dist/integrations/plugins/runtime.d.ts.map +1 -1
- package/dist/integrations/plugins/runtime.js +16 -29
- package/dist/integrations/plugins/runtime.js.map +1 -1
- package/dist/integrations/providers/harness-credentials.d.ts +9 -4
- package/dist/integrations/providers/harness-credentials.d.ts.map +1 -1
- package/dist/integrations/providers/harness-credentials.js +16 -8
- package/dist/integrations/providers/harness-credentials.js.map +1 -1
- package/dist/integrations/resident/session-step.d.ts.map +1 -1
- package/dist/integrations/resident/session-step.js +2 -1
- package/dist/integrations/resident/session-step.js.map +1 -1
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/sessions/store.js +20 -2
- package/dist/integrations/sessions/store.js.map +1 -1
- package/dist/integrations/subagents/NamzuCliAgent.d.ts +8 -0
- package/dist/integrations/subagents/NamzuCliAgent.d.ts.map +1 -0
- package/dist/integrations/subagents/NamzuCliAgent.js +9 -0
- package/dist/integrations/subagents/NamzuCliAgent.js.map +1 -0
- package/dist/integrations/subagents/runtime.d.ts +5 -4
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +46 -11
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/integrations/web/open-url.d.ts +24 -0
- package/dist/integrations/web/open-url.d.ts.map +1 -0
- package/dist/integrations/web/open-url.js +73 -0
- package/dist/integrations/web/open-url.js.map +1 -0
- package/dist/integrations/web/search.d.ts.map +1 -1
- package/dist/integrations/web/search.js +8 -6
- package/dist/integrations/web/search.js.map +1 -1
- package/dist/permissions/rules.d.ts +5 -1
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +85 -3
- package/dist/permissions/rules.js.map +1 -1
- package/dist/schedule/build.d.ts +26 -2
- package/dist/schedule/build.d.ts.map +1 -1
- package/dist/schedule/build.js +139 -20
- package/dist/schedule/build.js.map +1 -1
- package/dist/schedule/changes.d.ts +6 -0
- package/dist/schedule/changes.d.ts.map +1 -1
- package/dist/schedule/changes.js +23 -0
- package/dist/schedule/changes.js.map +1 -1
- package/dist/schedule/commands/add.d.ts +1 -1
- package/dist/schedule/commands/add.d.ts.map +1 -1
- package/dist/schedule/commands/add.js +188 -54
- package/dist/schedule/commands/add.js.map +1 -1
- package/dist/schedule/commands/lifecycle.d.ts.map +1 -1
- package/dist/schedule/commands/lifecycle.js +2 -1
- package/dist/schedule/commands/lifecycle.js.map +1 -1
- package/dist/schedule/commands/list.d.ts +2 -0
- package/dist/schedule/commands/list.d.ts.map +1 -1
- package/dist/schedule/commands/list.js +69 -20
- package/dist/schedule/commands/list.js.map +1 -1
- package/dist/schedule/daemon/daemon.d.ts +1 -1
- package/dist/schedule/daemon/daemon.d.ts.map +1 -1
- package/dist/schedule/daemon/daemon.js +22 -5
- package/dist/schedule/daemon/daemon.js.map +1 -1
- package/dist/schedule/daemon/notify.d.ts +29 -2
- package/dist/schedule/daemon/notify.d.ts.map +1 -1
- package/dist/schedule/daemon/notify.js +71 -2
- package/dist/schedule/daemon/notify.js.map +1 -1
- package/dist/schedule/env.d.ts +8 -4
- package/dist/schedule/env.d.ts.map +1 -1
- package/dist/schedule/env.js +13 -6
- package/dist/schedule/env.js.map +1 -1
- package/dist/schedule/fire/calls.d.ts +49 -0
- package/dist/schedule/fire/calls.d.ts.map +1 -0
- package/dist/schedule/fire/calls.js +114 -0
- package/dist/schedule/fire/calls.js.map +1 -0
- package/dist/schedule/fire/fire.d.ts +1 -1
- package/dist/schedule/fire/fire.d.ts.map +1 -1
- package/dist/schedule/fire/fire.js +209 -15
- package/dist/schedule/fire/fire.js.map +1 -1
- package/dist/schedule/fire/result.d.ts +1 -1
- package/dist/schedule/fire/result.d.ts.map +1 -1
- package/dist/schedule/fire/result.js +2 -1
- package/dist/schedule/fire/result.js.map +1 -1
- package/dist/schedule/fire/run-script.d.ts +46 -0
- package/dist/schedule/fire/run-script.d.ts.map +1 -0
- package/dist/schedule/fire/run-script.js +81 -0
- package/dist/schedule/fire/run-script.js.map +1 -0
- package/dist/schedule/fire/unattended-note.d.ts +8 -0
- package/dist/schedule/fire/unattended-note.d.ts.map +1 -1
- package/dist/schedule/fire/unattended-note.js +5 -0
- package/dist/schedule/fire/unattended-note.js.map +1 -1
- package/dist/schedule/fire/wake-gate.d.ts +39 -0
- package/dist/schedule/fire/wake-gate.d.ts.map +1 -0
- package/dist/schedule/fire/wake-gate.js +90 -0
- package/dist/schedule/fire/wake-gate.js.map +1 -0
- package/dist/schedule/floor.d.ts +28 -8
- package/dist/schedule/floor.d.ts.map +1 -1
- package/dist/schedule/floor.js +624 -114
- package/dist/schedule/floor.js.map +1 -1
- package/dist/schedule/policy.d.ts +40 -0
- package/dist/schedule/policy.d.ts.map +1 -1
- package/dist/schedule/policy.js +36 -0
- package/dist/schedule/policy.js.map +1 -1
- package/dist/schedule/script-check.d.ts +53 -0
- package/dist/schedule/script-check.d.ts.map +1 -0
- package/dist/schedule/script-check.js +145 -0
- package/dist/schedule/script-check.js.map +1 -0
- package/dist/schedule/script-shell.d.ts +3 -0
- package/dist/schedule/script-shell.d.ts.map +1 -0
- package/dist/schedule/script-shell.js +5 -0
- package/dist/schedule/script-shell.js.map +1 -0
- package/dist/schedule/service/index.d.ts +1 -1
- package/dist/schedule/service/index.d.ts.map +1 -1
- package/dist/schedule/service/index.js +20 -11
- package/dist/schedule/service/index.js.map +1 -1
- package/dist/schedule/service/manifest.js +1 -1
- package/dist/schedule/service/manifest.js.map +1 -1
- package/dist/schedule/service/windows-task.d.ts +7 -0
- package/dist/schedule/service/windows-task.d.ts.map +1 -1
- package/dist/schedule/service/windows-task.js +65 -0
- package/dist/schedule/service/windows-task.js.map +1 -1
- package/dist/schedule/service/wsl.d.ts +13 -1
- package/dist/schedule/service/wsl.d.ts.map +1 -1
- package/dist/schedule/service/wsl.js +16 -6
- package/dist/schedule/service/wsl.js.map +1 -1
- package/dist/schedule/store/atomic.d.ts +5 -2
- package/dist/schedule/store/atomic.d.ts.map +1 -1
- package/dist/schedule/store/atomic.js +7 -4
- package/dist/schedule/store/atomic.js.map +1 -1
- package/dist/schedule/store/claims.js +1 -1
- package/dist/schedule/store/claims.js.map +1 -1
- package/dist/schedule/store/history.d.ts +1 -1
- package/dist/schedule/store/history.d.ts.map +1 -1
- package/dist/schedule/store/history.js +4 -1
- package/dist/schedule/store/history.js.map +1 -1
- package/dist/schedule/store/jobs.d.ts +19 -3
- package/dist/schedule/store/jobs.d.ts.map +1 -1
- package/dist/schedule/store/jobs.js +83 -16
- package/dist/schedule/store/jobs.js.map +1 -1
- package/dist/schedule/store/state.js +1 -1
- package/dist/schedule/store/state.js.map +1 -1
- package/dist/schedule/types.d.ts +98 -6
- package/dist/schedule/types.d.ts.map +1 -1
- package/dist/schedule/types.js +25 -1
- package/dist/schedule/types.js.map +1 -1
- package/dist/schedule/visible-source.d.ts +18 -0
- package/dist/schedule/visible-source.d.ts.map +1 -0
- package/dist/schedule/visible-source.js +59 -0
- package/dist/schedule/visible-source.js.map +1 -0
- package/dist/skills/directory.d.ts +38 -0
- package/dist/skills/directory.d.ts.map +1 -0
- package/dist/skills/directory.js +51 -0
- package/dist/skills/directory.js.map +1 -0
- package/dist/test-support/toolset.d.ts +23 -0
- package/dist/test-support/toolset.d.ts.map +1 -0
- package/dist/test-support/toolset.js +27 -0
- package/dist/test-support/toolset.js.map +1 -0
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +343 -64
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/ChoicePicker.d.ts +2 -0
- package/dist/tui/ChoicePicker.d.ts.map +1 -1
- package/dist/tui/ChoicePicker.js +10 -2
- package/dist/tui/ChoicePicker.js.map +1 -1
- package/dist/tui/Composer.d.ts +62 -3
- package/dist/tui/Composer.d.ts.map +1 -1
- package/dist/tui/Composer.js +162 -25
- package/dist/tui/Composer.js.map +1 -1
- package/dist/tui/ComposerFrame.d.ts +1 -1
- package/dist/tui/ComposerFrame.js +3 -3
- package/dist/tui/ComposerFrame.js.map +1 -1
- package/dist/tui/EffortSlider.d.ts +8 -9
- package/dist/tui/EffortSlider.d.ts.map +1 -1
- package/dist/tui/EffortSlider.js +15 -12
- package/dist/tui/EffortSlider.js.map +1 -1
- package/dist/tui/PermissionOverlay.d.ts +13 -1
- package/dist/tui/PermissionOverlay.d.ts.map +1 -1
- package/dist/tui/PermissionOverlay.js +26 -4
- package/dist/tui/PermissionOverlay.js.map +1 -1
- package/dist/tui/StatusBar.d.ts +12 -12
- package/dist/tui/StatusBar.d.ts.map +1 -1
- package/dist/tui/StatusBar.js +15 -15
- package/dist/tui/StatusBar.js.map +1 -1
- package/dist/tui/agent.d.ts +73 -12
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +430 -180
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/hypermode.d.ts +37 -0
- package/dist/tui/hypermode.d.ts.map +1 -0
- package/dist/tui/hypermode.js +58 -0
- package/dist/tui/hypermode.js.map +1 -0
- package/dist/tui/open-browser.d.ts +29 -1
- package/dist/tui/open-browser.d.ts.map +1 -1
- package/dist/tui/open-browser.js +83 -11
- package/dist/tui/open-browser.js.map +1 -1
- package/dist/tui/permission-review.d.ts +11 -2
- package/dist/tui/permission-review.d.ts.map +1 -1
- package/dist/tui/permission-review.js +176 -19
- package/dist/tui/permission-review.js.map +1 -1
- package/dist/tui/schedule/host-commands.d.ts.map +1 -1
- package/dist/tui/schedule/host-commands.js +95 -33
- package/dist/tui/schedule/host-commands.js.map +1 -1
- package/dist/tui/schedule/integration.d.ts +6 -2
- package/dist/tui/schedule/integration.d.ts.map +1 -1
- package/dist/tui/schedule/integration.js +3 -1
- package/dist/tui/schedule/integration.js.map +1 -1
- package/dist/tui/schedule/resume.d.ts.map +1 -1
- package/dist/tui/schedule/resume.js +10 -1
- package/dist/tui/schedule/resume.js.map +1 -1
- package/dist/tui/schedule/tool-host.d.ts +18 -1
- package/dist/tui/schedule/tool-host.d.ts.map +1 -1
- package/dist/tui/schedule/tool-host.js +384 -84
- package/dist/tui/schedule/tool-host.js.map +1 -1
- package/dist/tui/slashCommands.d.ts +23 -5
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +80 -31
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/theme.d.ts +10 -4
- package/dist/tui/theme.d.ts.map +1 -1
- package/dist/tui/theme.js +4 -3
- package/dist/tui/theme.js.map +1 -1
- package/dist/tui/triggers/analyze.d.ts +57 -0
- package/dist/tui/triggers/analyze.d.ts.map +1 -0
- package/dist/tui/triggers/analyze.js +221 -0
- package/dist/tui/triggers/analyze.js.map +1 -0
- package/dist/tui/triggers/context-text.d.ts +21 -0
- package/dist/tui/triggers/context-text.d.ts.map +1 -0
- package/dist/tui/triggers/context-text.js +44 -0
- package/dist/tui/triggers/context-text.js.map +1 -0
- package/dist/tui/triggers/copy.d.ts +38 -0
- package/dist/tui/triggers/copy.d.ts.map +1 -0
- package/dist/tui/triggers/copy.js +163 -0
- package/dist/tui/triggers/copy.js.map +1 -0
- package/dist/tui/triggers/detect.d.ts +83 -0
- package/dist/tui/triggers/detect.d.ts.map +1 -0
- package/dist/tui/triggers/detect.js +295 -0
- package/dist/tui/triggers/detect.js.map +1 -0
- package/dist/tui/triggers/fold.d.ts +34 -0
- package/dist/tui/triggers/fold.d.ts.map +1 -0
- package/dist/tui/triggers/fold.js +44 -0
- package/dist/tui/triggers/fold.js.map +1 -0
- package/dist/tui/triggers/pattern.d.ts +66 -0
- package/dist/tui/triggers/pattern.d.ts.map +1 -0
- package/dist/tui/triggers/pattern.js +243 -0
- package/dist/tui/triggers/pattern.js.map +1 -0
- package/dist/tui/triggers/provenance.d.ts +58 -0
- package/dist/tui/triggers/provenance.d.ts.map +1 -0
- package/dist/tui/triggers/provenance.js +98 -0
- package/dist/tui/triggers/provenance.js.map +1 -0
- package/dist/tui/triggers/registry.d.ts +113 -0
- package/dist/tui/triggers/registry.d.ts.map +1 -0
- package/dist/tui/triggers/registry.js +164 -0
- package/dist/tui/triggers/registry.js.map +1 -0
- package/dist/tui/triggers/setting.d.ts +18 -0
- package/dist/tui/triggers/setting.d.ts.map +1 -0
- package/dist/tui/triggers/setting.js +61 -0
- package/dist/tui/triggers/setting.js.map +1 -0
- package/dist/tui/triggers/verbs.d.ts +29 -0
- package/dist/tui/triggers/verbs.d.ts.map +1 -0
- package/dist/tui/triggers/verbs.js +140 -0
- package/dist/tui/triggers/verbs.js.map +1 -0
- package/dist/tui/types.d.ts +3 -1
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +12 -12
- package/skills/README.md +5 -0
- package/skills/schedule-task/SKILL.md +123 -5
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the TUI names its multi-agent session mode, in one place.
|
|
3
|
+
*
|
|
4
|
+
* Hypermode was called "orchestrate" until the rename; `/orchestrate` still
|
|
5
|
+
* works as a deprecated alias of `/hypermode` (see `slashCommands.ts`). The
|
|
6
|
+
* mode pins reasoning effort to `xhigh` — or, on a model whose menu has no
|
|
7
|
+
* `xhigh`, the level nearest below it (see {@link hypermodeEffort}) — and
|
|
8
|
+
* strengthens the delegation doctrine toward delegating by default
|
|
9
|
+
* (`CODING_AGENT_HYPERMODE_DOCTRINE` in `@namzu/sdk`). "Workflows" is this
|
|
10
|
+
* terminal's word for that phased multi-agent work.
|
|
11
|
+
*/
|
|
12
|
+
import type { ReasoningEffort } from '@namzu/sdk';
|
|
13
|
+
/** The mode's name wherever the operator reads it: footer, border tag, picker. */
|
|
14
|
+
export declare const HYPERMODE = "hypermode";
|
|
15
|
+
/** The one-line description the effort picker shows for the hypermode stop. */
|
|
16
|
+
export declare const HYPERMODE_SUMMARY = "delegates to parallel agents by default";
|
|
17
|
+
/** The level hypermode pins wherever the model publishes it. */
|
|
18
|
+
export declare const HYPERMODE_EFFORT: ReasoningEffort;
|
|
19
|
+
/**
|
|
20
|
+
* The level hypermode pins on a model that publishes `levels`: `xhigh`, or
|
|
21
|
+
* the highest published level below it when the menu has no `xhigh`
|
|
22
|
+
* (`high` on a menu that stops there). `max` and `ultra` are never chosen
|
|
23
|
+
* over a lower level; only a menu made entirely of levels above `xhigh`
|
|
24
|
+
* gets its lowest one, the nearest there is. `undefined` when the model
|
|
25
|
+
* publishes no menu, or an empty one: nothing is pinned.
|
|
26
|
+
*/
|
|
27
|
+
export declare function hypermodeEffort(levels: readonly ReasoningEffort[] | undefined): ReasoningEffort | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* The effort picker's last stop: the level the mode pins, then the mode —
|
|
30
|
+
* `xhigh + hypermode (workflows)`, or `high + hypermode (workflows)` on a
|
|
31
|
+
* model whose menu stops at `high`. Without a published menu there is no
|
|
32
|
+
* level to name.
|
|
33
|
+
*/
|
|
34
|
+
export declare function hypermodeStopLabel(pinned: string | undefined): string;
|
|
35
|
+
/** The deprecation line `/orchestrate` prints before it does what `/hypermode` does. */
|
|
36
|
+
export declare const ORCHESTRATE_ALIAS_NOTICE = "/orchestrate is deprecated: the mode is now called hypermode. Use /hypermode; /orchestrate will be removed in a later major version.";
|
|
37
|
+
//# sourceMappingURL=hypermode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hypermode.d.ts","sourceRoot":"","sources":["../../src/tui/hypermode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,kFAAkF;AAClF,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,4CAA4C,CAAA;AAE1E,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,EAAE,eAAyB,CAAA;AAcxD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,SAAS,eAAe,EAAE,GAAG,SAAS,GAC5C,eAAe,GAAG,SAAS,CAQ7B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAErE;AAED,wFAAwF;AACxF,eAAO,MAAM,wBAAwB,yIACkG,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How the TUI names its multi-agent session mode, in one place.
|
|
3
|
+
*
|
|
4
|
+
* Hypermode was called "orchestrate" until the rename; `/orchestrate` still
|
|
5
|
+
* works as a deprecated alias of `/hypermode` (see `slashCommands.ts`). The
|
|
6
|
+
* mode pins reasoning effort to `xhigh` — or, on a model whose menu has no
|
|
7
|
+
* `xhigh`, the level nearest below it (see {@link hypermodeEffort}) — and
|
|
8
|
+
* strengthens the delegation doctrine toward delegating by default
|
|
9
|
+
* (`CODING_AGENT_HYPERMODE_DOCTRINE` in `@namzu/sdk`). "Workflows" is this
|
|
10
|
+
* terminal's word for that phased multi-agent work.
|
|
11
|
+
*/
|
|
12
|
+
/** The mode's name wherever the operator reads it: footer, border tag, picker. */
|
|
13
|
+
export const HYPERMODE = 'hypermode';
|
|
14
|
+
/** The one-line description the effort picker shows for the hypermode stop. */
|
|
15
|
+
export const HYPERMODE_SUMMARY = 'delegates to parallel agents by default';
|
|
16
|
+
/** The level hypermode pins wherever the model publishes it. */
|
|
17
|
+
export const HYPERMODE_EFFORT = 'xhigh';
|
|
18
|
+
/** Every effort level, low to high: the order of the SDK's `ReasoningEffort` union. */
|
|
19
|
+
const EFFORT_ORDER = [
|
|
20
|
+
'none',
|
|
21
|
+
'minimal',
|
|
22
|
+
'low',
|
|
23
|
+
'medium',
|
|
24
|
+
'high',
|
|
25
|
+
'xhigh',
|
|
26
|
+
'max',
|
|
27
|
+
'ultra',
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* The level hypermode pins on a model that publishes `levels`: `xhigh`, or
|
|
31
|
+
* the highest published level below it when the menu has no `xhigh`
|
|
32
|
+
* (`high` on a menu that stops there). `max` and `ultra` are never chosen
|
|
33
|
+
* over a lower level; only a menu made entirely of levels above `xhigh`
|
|
34
|
+
* gets its lowest one, the nearest there is. `undefined` when the model
|
|
35
|
+
* publishes no menu, or an empty one: nothing is pinned.
|
|
36
|
+
*/
|
|
37
|
+
export function hypermodeEffort(levels) {
|
|
38
|
+
if (!levels || levels.length === 0)
|
|
39
|
+
return undefined;
|
|
40
|
+
const ceiling = EFFORT_ORDER.indexOf(HYPERMODE_EFFORT);
|
|
41
|
+
const rank = (level) => EFFORT_ORDER.indexOf(level);
|
|
42
|
+
const atOrBelow = levels.filter((level) => rank(level) >= 0 && rank(level) <= ceiling);
|
|
43
|
+
if (atOrBelow.length > 0)
|
|
44
|
+
return atOrBelow.reduce((best, level) => (rank(level) > rank(best) ? level : best));
|
|
45
|
+
return levels.reduce((best, level) => (rank(level) < rank(best) ? level : best));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The effort picker's last stop: the level the mode pins, then the mode —
|
|
49
|
+
* `xhigh + hypermode (workflows)`, or `high + hypermode (workflows)` on a
|
|
50
|
+
* model whose menu stops at `high`. Without a published menu there is no
|
|
51
|
+
* level to name.
|
|
52
|
+
*/
|
|
53
|
+
export function hypermodeStopLabel(pinned) {
|
|
54
|
+
return pinned ? `${pinned} + ${HYPERMODE} (workflows)` : `${HYPERMODE} (workflows)`;
|
|
55
|
+
}
|
|
56
|
+
/** The deprecation line `/orchestrate` prints before it does what `/hypermode` does. */
|
|
57
|
+
export const ORCHESTRATE_ALIAS_NOTICE = '/orchestrate is deprecated: the mode is now called hypermode. Use /hypermode; /orchestrate will be removed in a later major version.';
|
|
58
|
+
//# sourceMappingURL=hypermode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hypermode.js","sourceRoot":"","sources":["../../src/tui/hypermode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,kFAAkF;AAClF,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAA;AAEpC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAG,yCAAyC,CAAA;AAE1E,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAoB,OAAO,CAAA;AAExD,uFAAuF;AACvF,MAAM,YAAY,GAA+B;IAChD,MAAM;IACN,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;CACP,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC9B,MAA8C;IAE9C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACpD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACtD,MAAM,IAAI,GAAG,CAAC,KAAsB,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACpE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAA;IACtF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;QACvB,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IACpF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC5D,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,MAAM,SAAS,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,cAAc,CAAA;AACpF,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,MAAM,wBAAwB,GACpC,sIAAsI,CAAA"}
|
|
@@ -12,6 +12,20 @@
|
|
|
12
12
|
* path under the system directory so a same-named executable earlier on `PATH`
|
|
13
13
|
* cannot answer instead.
|
|
14
14
|
*
|
|
15
|
+
* ## WSL: the Windows browser
|
|
16
|
+
*
|
|
17
|
+
* Under WSL the desktop the user looks at is Windows', and `xdg-open` reaches
|
|
18
|
+
* a Linux browser at best (usually nothing). With interop on, the address goes
|
|
19
|
+
* to Windows' own protocol handler through `powershell.exe`, named by absolute
|
|
20
|
+
* path, running a CONSTANT script (`Start-Process -FilePath
|
|
21
|
+
* $env:NAMZU_OPEN_URL`) sent as `-EncodedCommand`: the address reaches it only
|
|
22
|
+
* as an environment variable named in `WSLENV`, so nothing parses it as code
|
|
23
|
+
* — the same shape as the WSL toast in `notifications/desktop/windows-toast.ts`.
|
|
24
|
+
* This is what the `open` package does on WSL too, minus its six dependencies
|
|
25
|
+
* and its quoting of the address into the script text. `cmd.exe /c start` is
|
|
26
|
+
* not used, for the reason above; `explorer.exe` is not used because it exits
|
|
27
|
+
* 1 even when it opened the page.
|
|
28
|
+
*
|
|
15
29
|
* ## Best effort, reported honestly
|
|
16
30
|
*
|
|
17
31
|
* Returns whether a launcher was even STARTED, not whether a browser appeared
|
|
@@ -20,5 +34,19 @@
|
|
|
20
34
|
* stop reading". On a machine with no graphical session there is nothing to
|
|
21
35
|
* start and this says so, which is the case the paste path exists for.
|
|
22
36
|
*/
|
|
23
|
-
|
|
37
|
+
/** Where Windows keeps PowerShell, under a WSL mount root (`/mnt/` by default). */
|
|
38
|
+
export declare function wslPowershell(mountRoot?: string): string;
|
|
39
|
+
/** PowerShell under the default mount root. */
|
|
40
|
+
export declare const WSL_POWERSHELL: string;
|
|
41
|
+
/** The whole WSL script. The address is data in the environment, never text here. */
|
|
42
|
+
export declare const WSL_OPEN_SCRIPT: string;
|
|
43
|
+
/** The machine, injectable so a test can describe one it is not running on. */
|
|
44
|
+
export interface BrowserHost {
|
|
45
|
+
readonly platform?: NodeJS.Platform;
|
|
46
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
47
|
+
readonly exists?: (path: string) => boolean;
|
|
48
|
+
/** Reads `/etc/wsl.conf`, for where the Windows drives are mounted. */
|
|
49
|
+
readonly readFile?: (path: string) => string | undefined;
|
|
50
|
+
}
|
|
51
|
+
export declare function openInBrowser(url: string, host?: BrowserHost): boolean;
|
|
24
52
|
//# sourceMappingURL=open-browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-browser.d.ts","sourceRoot":"","sources":["../../src/tui/open-browser.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"open-browser.d.ts","sourceRoot":"","sources":["../../src/tui/open-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AA+BH,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,SAAS,GAAE,MAA+B,GAAG,MAAM,CAEhF;AAED,+CAA+C;AAC/C,eAAO,MAAM,cAAc,QAAkB,CAAA;AAE7C,qFAAqF;AACrF,eAAO,MAAM,eAAe,QAGhB,CAAA;AAEZ,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAA;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;IAC3C,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;CACxD;AAwDD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CA0B1E"}
|
package/dist/tui/open-browser.js
CHANGED
|
@@ -12,6 +12,20 @@
|
|
|
12
12
|
* path under the system directory so a same-named executable earlier on `PATH`
|
|
13
13
|
* cannot answer instead.
|
|
14
14
|
*
|
|
15
|
+
* ## WSL: the Windows browser
|
|
16
|
+
*
|
|
17
|
+
* Under WSL the desktop the user looks at is Windows', and `xdg-open` reaches
|
|
18
|
+
* a Linux browser at best (usually nothing). With interop on, the address goes
|
|
19
|
+
* to Windows' own protocol handler through `powershell.exe`, named by absolute
|
|
20
|
+
* path, running a CONSTANT script (`Start-Process -FilePath
|
|
21
|
+
* $env:NAMZU_OPEN_URL`) sent as `-EncodedCommand`: the address reaches it only
|
|
22
|
+
* as an environment variable named in `WSLENV`, so nothing parses it as code
|
|
23
|
+
* — the same shape as the WSL toast in `notifications/desktop/windows-toast.ts`.
|
|
24
|
+
* This is what the `open` package does on WSL too, minus its six dependencies
|
|
25
|
+
* and its quoting of the address into the script text. `cmd.exe /c start` is
|
|
26
|
+
* not used, for the reason above; `explorer.exe` is not used because it exits
|
|
27
|
+
* 1 even when it opened the page.
|
|
28
|
+
*
|
|
15
29
|
* ## Best effort, reported honestly
|
|
16
30
|
*
|
|
17
31
|
* Returns whether a launcher was even STARTED, not whether a browser appeared
|
|
@@ -21,12 +35,13 @@
|
|
|
21
35
|
* start and this says so, which is the case the paste path exists for.
|
|
22
36
|
*/
|
|
23
37
|
import { spawn } from 'node:child_process';
|
|
24
|
-
import { constants, accessSync } from 'node:fs';
|
|
38
|
+
import { constants, accessSync, existsSync } from 'node:fs';
|
|
25
39
|
import { platform } from 'node:os';
|
|
26
40
|
import { delimiter, isAbsolute, join } from 'node:path';
|
|
41
|
+
import { DEFAULT_WSL_MOUNT_ROOT, detectWsl, readWslMountRoot, wslSystem32, } from '../context/environment.js';
|
|
27
42
|
/** Resolve a launcher before claiming that one started. */
|
|
28
|
-
function executableOnPath(name) {
|
|
29
|
-
for (const directory of (
|
|
43
|
+
function executableOnPath(name, env) {
|
|
44
|
+
for (const directory of (env.PATH ?? '').split(delimiter)) {
|
|
30
45
|
// An empty or relative PATH member delegates executable authority to the
|
|
31
46
|
// project cwd. Opening an OAuth URL must never run a project-owned helper.
|
|
32
47
|
if (!directory || !isAbsolute(directory))
|
|
@@ -42,23 +57,80 @@ function executableOnPath(name) {
|
|
|
42
57
|
}
|
|
43
58
|
return null;
|
|
44
59
|
}
|
|
45
|
-
|
|
60
|
+
/** Where Windows keeps PowerShell, under a WSL mount root (`/mnt/` by default). */
|
|
61
|
+
export function wslPowershell(mountRoot = DEFAULT_WSL_MOUNT_ROOT) {
|
|
62
|
+
return `${wslSystem32(mountRoot)}/WindowsPowerShell/v1.0/powershell.exe`;
|
|
63
|
+
}
|
|
64
|
+
/** PowerShell under the default mount root. */
|
|
65
|
+
export const WSL_POWERSHELL = wslPowershell();
|
|
66
|
+
/** The whole WSL script. The address is data in the environment, never text here. */
|
|
67
|
+
export const WSL_OPEN_SCRIPT = [
|
|
68
|
+
"$ErrorActionPreference = 'Stop'",
|
|
69
|
+
'Start-Process -FilePath $env:NAMZU_OPEN_URL',
|
|
70
|
+
].join('\n');
|
|
71
|
+
/** Windows' protocol handler through interop, or `null` when this is not a WSL that can reach it. */
|
|
72
|
+
function wslLaunch(url, env, host) {
|
|
73
|
+
const exists = host.exists ?? existsSync;
|
|
74
|
+
// `/etc/wsl.conf` can move the drives (`[automount] root = /win/`), and
|
|
75
|
+
// PowerShell and the directory it starts in move with them.
|
|
76
|
+
const mountRoot = host.readFile ? readWslMountRoot(host.readFile) : readWslMountRoot();
|
|
77
|
+
const wsl = detectWsl(env, { exists, list: () => [], mountRoot });
|
|
78
|
+
if (!wsl?.interop)
|
|
79
|
+
return null;
|
|
80
|
+
const powershell = wslPowershell(mountRoot);
|
|
81
|
+
if (!exists(powershell))
|
|
82
|
+
return null;
|
|
83
|
+
const passed = (env.WSLENV ?? '')
|
|
84
|
+
.split(':')
|
|
85
|
+
.filter((name) => name && !name.startsWith('NAMZU_OPEN_URL'));
|
|
86
|
+
return {
|
|
87
|
+
command: powershell,
|
|
88
|
+
args: [
|
|
89
|
+
'-NoProfile',
|
|
90
|
+
'-NonInteractive',
|
|
91
|
+
'-ExecutionPolicy',
|
|
92
|
+
'Bypass',
|
|
93
|
+
'-EncodedCommand',
|
|
94
|
+
Buffer.from(WSL_OPEN_SCRIPT, 'utf16le').toString('base64'),
|
|
95
|
+
],
|
|
96
|
+
env: { ...env, NAMZU_OPEN_URL: url, WSLENV: [...passed, 'NAMZU_OPEN_URL'].join(':') },
|
|
97
|
+
// A Windows program started from a Linux directory warns about UNC
|
|
98
|
+
// paths; the drive PowerShell lives on is a Windows directory.
|
|
99
|
+
cwd: `${mountRoot}c`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function launchFor(url, host) {
|
|
103
|
+
const currentPlatform = host.platform ?? platform();
|
|
104
|
+
const env = host.env ?? process.env;
|
|
105
|
+
if (currentPlatform === 'win32') {
|
|
106
|
+
return {
|
|
107
|
+
command: join(env.SystemRoot ?? 'C:\\Windows', 'System32', 'rundll32.exe'),
|
|
108
|
+
args: ['url.dll,FileProtocolHandler', url],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (currentPlatform === 'linux') {
|
|
112
|
+
const wsl = wslLaunch(url, env, host);
|
|
113
|
+
if (wsl)
|
|
114
|
+
return wsl;
|
|
115
|
+
}
|
|
116
|
+
const command = executableOnPath(currentPlatform === 'darwin' ? 'open' : 'xdg-open', env);
|
|
117
|
+
return command ? { command, args: [url] } : null;
|
|
118
|
+
}
|
|
119
|
+
export function openInBrowser(url, host = {}) {
|
|
46
120
|
// Refuse anything that is not a web address. This is handed to the
|
|
47
121
|
// machine's protocol handler, and `file:` or a custom scheme reaching it
|
|
48
122
|
// would be this function opening something nobody named.
|
|
49
123
|
if (!/^https?:\/\//i.test(url))
|
|
50
124
|
return false;
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
? join(process.env.SystemRoot ?? 'C:\\Windows', 'System32', 'rundll32.exe')
|
|
54
|
-
: executableOnPath(currentPlatform === 'darwin' ? 'open' : 'xdg-open');
|
|
55
|
-
if (!command)
|
|
125
|
+
const launch = launchFor(url, host);
|
|
126
|
+
if (!launch)
|
|
56
127
|
return false;
|
|
57
|
-
const args = currentPlatform === 'win32' ? ['url.dll,FileProtocolHandler', url] : [url];
|
|
58
128
|
try {
|
|
59
|
-
const child = spawn(command, args, {
|
|
129
|
+
const child = spawn(launch.command, [...launch.args], {
|
|
60
130
|
stdio: 'ignore',
|
|
61
131
|
detached: true,
|
|
132
|
+
...(launch.env ? { env: launch.env } : {}),
|
|
133
|
+
...(launch.cwd ? { cwd: launch.cwd } : {}),
|
|
62
134
|
});
|
|
63
135
|
// A missing launcher — no `xdg-open` in a container — arrives as an
|
|
64
136
|
// async error event, long after this function returned. Swallowing it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-browser.js","sourceRoot":"","sources":["../../src/tui/open-browser.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"open-browser.js","sourceRoot":"","sources":["../../src/tui/open-browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,7 +66,7 @@ export interface PermissionReviewRow {
|
|
|
66
66
|
/**
|
|
67
67
|
* Serialize the exact executable batch without invoking getters or `toJSON`.
|
|
68
68
|
*
|
|
69
|
-
* `
|
|
69
|
+
* `ToolManager.prepareExecution()` already publishes detached JSON values,
|
|
70
70
|
* but this is a host boundary and structural SDK implementations can still
|
|
71
71
|
* supply `unknown`. Ordinary `JSON.stringify` would execute an accessor and
|
|
72
72
|
* could silently turn a Date/Map/custom object into something other than the
|
|
@@ -89,7 +89,16 @@ export declare function buildPermissionReview(calls: readonly PermissionReviewCa
|
|
|
89
89
|
* is the one case that opens exact-first: the formatter is stale, and a
|
|
90
90
|
* reader should see that rather than a projection that happens to be right.
|
|
91
91
|
*/
|
|
92
|
-
|
|
92
|
+
/** What the screen can learn, beyond the envelope, to make a call readable. */
|
|
93
|
+
export interface PermissionSummaryContext {
|
|
94
|
+
/**
|
|
95
|
+
* The control a `computer_use` `ui_act` ref names in the latest UI
|
|
96
|
+
* snapshot (`Button "Beş" (e30)`), from the session's tool. Absent, the
|
|
97
|
+
* ref alone is shown.
|
|
98
|
+
*/
|
|
99
|
+
readonly describeUiRef?: (ref: string) => string | undefined;
|
|
100
|
+
}
|
|
101
|
+
export declare function buildPermissionSummary(review: string, context?: PermissionSummaryContext): PermissionReviewSummary;
|
|
93
102
|
/**
|
|
94
103
|
* Project and wrap exact review text into PHYSICAL terminal rows.
|
|
95
104
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-review.d.ts","sourceRoot":"","sources":["../../src/tui/permission-review.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAA;AAEhD,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,SAAS;IACnB,QAAQ,CAAC,UAAU,CAAC,EAAE;QACrB,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;QAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KACzC,CAAA;CACD,EAAE,GACD,OAAO,CAKT;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAAA;CAAE,CAAA;AAE3E,MAAM,WAAW,uBAAuB;IACvC,sFAAsF;IACtF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC1B;AASD,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,MAAM,CAIvF;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC9B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,oBAAoB,EAAE,EACtC,QAAQ,SAA8B,GACpC,sBAAsB,CAqJxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"permission-review.d.ts","sourceRoot":"","sources":["../../src/tui/permission-review.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAA;AAEhD,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,SAAS;IACnB,QAAQ,CAAC,UAAU,CAAC,EAAE;QACrB,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;QAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KACzC,CAAA;CACD,EAAE,GACD,OAAO,CAKT;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAAA;CAAE,CAAA;AAE3E,MAAM,WAAW,uBAAuB;IACvC,sFAAsF;IACtF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC1B;AASD,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,MAAM,CAIvF;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC9B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,oBAAoB,EAAE,EACtC,QAAQ,SAA8B,GACpC,sBAAsB,CAqJxB;AAED;;;;;;;;;;;;;GAaG;AACH,+EAA+E;AAC/E,MAAM,WAAW,wBAAwB;IACxC;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;CAC5D;AAED,wBAAgB,sBAAsB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,wBAA6B,GACpC,uBAAuB,CA+EzB;AA+kBD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,SAAS,mBAAmB,EAAE,CA6BhC"}
|
|
@@ -45,7 +45,7 @@ class ReviewShapeError extends Error {
|
|
|
45
45
|
/**
|
|
46
46
|
* Serialize the exact executable batch without invoking getters or `toJSON`.
|
|
47
47
|
*
|
|
48
|
-
* `
|
|
48
|
+
* `ToolManager.prepareExecution()` already publishes detached JSON values,
|
|
49
49
|
* but this is a host boundary and structural SDK implementations can still
|
|
50
50
|
* supply `unknown`. Ordinary `JSON.stringify` would execute an accessor and
|
|
51
51
|
* could silently turn a Date/Map/custom object into something other than the
|
|
@@ -200,21 +200,7 @@ export function buildPermissionReview(calls, maxBytes = MAX_PERMISSION_REVIEW_BY
|
|
|
200
200
|
};
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
-
|
|
204
|
-
* Derive a readable review from the immutable exact envelope.
|
|
205
|
-
*
|
|
206
|
-
* This never reads the original tool objects: `buildPermissionReview` has
|
|
207
|
-
* already rejected getters, prototypes and non-JSON values. A summary is
|
|
208
|
-
* `complete` when it shows every key of every call, and callers open the
|
|
209
|
-
* readable view by default only then — so a friendly label can never hide a
|
|
210
|
-
* suffix. Two ways to be complete: a formatter below whose key set and value
|
|
211
|
-
* types are exhaustive, or, for a tool no formatter here knows (`read`,
|
|
212
|
-
* `grep`, a connected server's tool), every key with its full JSON-escaped
|
|
213
|
-
* value. A tool that HAS a formatter but arrives in a shape it does not know
|
|
214
|
-
* is the one case that opens exact-first: the formatter is stale, and a
|
|
215
|
-
* reader should see that rather than a projection that happens to be right.
|
|
216
|
-
*/
|
|
217
|
-
export function buildPermissionSummary(review) {
|
|
203
|
+
export function buildPermissionSummary(review, context = {}) {
|
|
218
204
|
let parsed;
|
|
219
205
|
try {
|
|
220
206
|
parsed = JSON.parse(review);
|
|
@@ -235,7 +221,7 @@ export function buildPermissionSummary(review) {
|
|
|
235
221
|
!Object.hasOwn(call, 'input')) {
|
|
236
222
|
return { text: review, complete: false };
|
|
237
223
|
}
|
|
238
|
-
const readable = summarizeKnownCall(call.name, call.input);
|
|
224
|
+
const readable = summarizeKnownCall(call.name, call.input, context);
|
|
239
225
|
complete &&= readable.complete;
|
|
240
226
|
calls.push({
|
|
241
227
|
name: call.name,
|
|
@@ -289,7 +275,7 @@ function commandLines(command) {
|
|
|
289
275
|
const [first = '', ...rest] = command.replace(/\r/g, '\\u{000d}').split('\n');
|
|
290
276
|
return [`$ ${first}`, ...rest.map((line) => ` ${line}`)];
|
|
291
277
|
}
|
|
292
|
-
function summarizeKnownCall(name, input) {
|
|
278
|
+
function summarizeKnownCall(name, input, context = {}) {
|
|
293
279
|
if (name === 'bash' && isRecord(input)) {
|
|
294
280
|
const allowed = new Set([
|
|
295
281
|
'command',
|
|
@@ -415,6 +401,11 @@ function summarizeKnownCall(name, input) {
|
|
|
415
401
|
if (summary)
|
|
416
402
|
return summary;
|
|
417
403
|
}
|
|
404
|
+
if (name === 'computer_use' && isRecord(input)) {
|
|
405
|
+
const summary = summarizeComputerUse(input, context);
|
|
406
|
+
if (summary)
|
|
407
|
+
return summary;
|
|
408
|
+
}
|
|
418
409
|
if (FORMATTED_TOOLS.has(name)) {
|
|
419
410
|
// A shape this file formats, in a form it does not know: the formatter
|
|
420
411
|
// is stale. Exact-first, so nobody reads a projection that merely
|
|
@@ -471,9 +462,175 @@ function summarizeBrowserOpen(input) {
|
|
|
471
462
|
complete: true,
|
|
472
463
|
};
|
|
473
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* A desktop action, or a batch of them, one numbered line per action in the
|
|
467
|
+
* order they will run: `3 desktop actions, in order` over `1. Click left at
|
|
468
|
+
* (812, 403)`, `2. Type "Bahadır Arda"`, `3. Press ENTER`. Text to be typed is
|
|
469
|
+
* shown whole — it is what lands in whichever window has focus — and the
|
|
470
|
+
* screenshot the coordinates belong to is named, since they are its pixels,
|
|
471
|
+
* not the screen's. An action or field this does not know returns null and
|
|
472
|
+
* the call opens exact-first.
|
|
473
|
+
*/
|
|
474
|
+
function summarizeComputerUse(input, context) {
|
|
475
|
+
if (input.screenshot_id !== undefined && typeof input.screenshot_id !== 'string')
|
|
476
|
+
return null;
|
|
477
|
+
const space = typeof input.screenshot_id === 'string'
|
|
478
|
+
? `Coordinates: pixels of screenshot ${input.screenshot_id}`
|
|
479
|
+
: 'Coordinates: pixels of the latest screenshot';
|
|
480
|
+
if (input.type === 'batch') {
|
|
481
|
+
if (!Object.keys(input).every((key) => ['type', 'actions', 'screenshot_id'].includes(key)))
|
|
482
|
+
return null;
|
|
483
|
+
if (!Array.isArray(input.actions) || input.actions.length === 0)
|
|
484
|
+
return null;
|
|
485
|
+
const lines = [];
|
|
486
|
+
let coordinates = false;
|
|
487
|
+
for (const [index, item] of input.actions.entries()) {
|
|
488
|
+
if (!isRecord(item) || item.type === 'batch' || Object.hasOwn(item, 'screenshot_id'))
|
|
489
|
+
return null;
|
|
490
|
+
const action = computerUseAction(item, [], context);
|
|
491
|
+
if (!action)
|
|
492
|
+
return null;
|
|
493
|
+
coordinates ||= action.coordinates;
|
|
494
|
+
lines.push(`${index + 1}. ${action.line}`);
|
|
495
|
+
}
|
|
496
|
+
const count = input.actions.length;
|
|
497
|
+
return {
|
|
498
|
+
lines: [
|
|
499
|
+
`${count} desktop action${count === 1 ? '' : 's'}, in order; stops at the first that fails`,
|
|
500
|
+
...lines,
|
|
501
|
+
...(coordinates ? [space] : []),
|
|
502
|
+
],
|
|
503
|
+
complete: true,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
if (input.actions !== undefined)
|
|
507
|
+
return null;
|
|
508
|
+
const action = computerUseAction(input, ['screenshot_id'], context);
|
|
509
|
+
if (!action)
|
|
510
|
+
return null;
|
|
511
|
+
return { lines: [action.line, ...(action.coordinates ? [space] : [])], complete: true };
|
|
512
|
+
}
|
|
513
|
+
/** How a person reads each `ui_act` action, before the control it acts on. */
|
|
514
|
+
const UI_ACT_VERBS = {
|
|
515
|
+
invoke: 'Press',
|
|
516
|
+
toggle: 'Toggle',
|
|
517
|
+
select: 'Select',
|
|
518
|
+
expand: 'Expand',
|
|
519
|
+
collapse: 'Collapse',
|
|
520
|
+
focus: 'Focus',
|
|
521
|
+
scroll_into_view: 'Scroll to',
|
|
522
|
+
};
|
|
523
|
+
function computerUseAction(item, extra = [], context = {}) {
|
|
524
|
+
const point = (value) => isRecord(value) &&
|
|
525
|
+
Object.keys(value).every((key) => key === 'x' || key === 'y') &&
|
|
526
|
+
Number.isInteger(value.x) &&
|
|
527
|
+
Number.isInteger(value.y)
|
|
528
|
+
? `(${value.x}, ${value.y})`
|
|
529
|
+
: null;
|
|
530
|
+
const fields = (...names) => Object.keys(item).every((key) => key === 'type' || names.includes(key) || extra.includes(key));
|
|
531
|
+
const text = (value) => typeof value === 'string';
|
|
532
|
+
switch (item.type) {
|
|
533
|
+
case 'screenshot':
|
|
534
|
+
return fields() ? { line: 'Take a screenshot', coordinates: false } : null;
|
|
535
|
+
case 'cursor_position':
|
|
536
|
+
return fields() ? { line: 'Read the cursor position', coordinates: false } : null;
|
|
537
|
+
case 'list_windows':
|
|
538
|
+
return fields() ? { line: 'List the open windows', coordinates: false } : null;
|
|
539
|
+
case 'wait':
|
|
540
|
+
return fields('ms') && Number.isInteger(item.ms)
|
|
541
|
+
? { line: `Wait ${item.ms} ms`, coordinates: false }
|
|
542
|
+
: null;
|
|
543
|
+
case 'focus_window':
|
|
544
|
+
return fields('window_id') && text(item.window_id)
|
|
545
|
+
? {
|
|
546
|
+
line: `Bring window ${JSON.stringify(item.window_id)} to the front`,
|
|
547
|
+
coordinates: false,
|
|
548
|
+
}
|
|
549
|
+
: null;
|
|
550
|
+
case 'type_text':
|
|
551
|
+
return fields('text') && text(item.text)
|
|
552
|
+
? { line: `Type ${JSON.stringify(item.text)}`, coordinates: false }
|
|
553
|
+
: null;
|
|
554
|
+
case 'key':
|
|
555
|
+
return fields('keys') && text(item.keys)
|
|
556
|
+
? { line: `Press ${JSON.stringify(item.keys)}`, coordinates: false }
|
|
557
|
+
: null;
|
|
558
|
+
case 'mouse_move': {
|
|
559
|
+
const to = point(item.to);
|
|
560
|
+
return fields('to') && to ? { line: `Move the pointer to ${to}`, coordinates: true } : null;
|
|
561
|
+
}
|
|
562
|
+
case 'mouse_click': {
|
|
563
|
+
const at = point(item.at);
|
|
564
|
+
return fields('at', 'button') && at && text(item.button)
|
|
565
|
+
? { line: `Click ${item.button} at ${at}`, coordinates: true }
|
|
566
|
+
: null;
|
|
567
|
+
}
|
|
568
|
+
case 'mouse_drag': {
|
|
569
|
+
const from = point(item.from);
|
|
570
|
+
const to = point(item.to);
|
|
571
|
+
return fields('from', 'to', 'button') && from && to && text(item.button)
|
|
572
|
+
? { line: `Drag ${item.button} from ${from} to ${to}`, coordinates: true }
|
|
573
|
+
: null;
|
|
574
|
+
}
|
|
575
|
+
case 'scroll': {
|
|
576
|
+
const at = point(item.at);
|
|
577
|
+
return fields('at', 'direction', 'amount') &&
|
|
578
|
+
at &&
|
|
579
|
+
text(item.direction) &&
|
|
580
|
+
Number.isInteger(item.amount)
|
|
581
|
+
? { line: `Scroll ${item.direction} ${item.amount} at ${at}`, coordinates: true }
|
|
582
|
+
: null;
|
|
583
|
+
}
|
|
584
|
+
case 'ui_snapshot':
|
|
585
|
+
return fields('window_id') && (item.window_id === undefined || text(item.window_id))
|
|
586
|
+
? {
|
|
587
|
+
line: item.window_id === undefined
|
|
588
|
+
? 'Read the controls of the window in front'
|
|
589
|
+
: `Read the controls of window ${JSON.stringify(item.window_id)}`,
|
|
590
|
+
coordinates: false,
|
|
591
|
+
}
|
|
592
|
+
: null;
|
|
593
|
+
case 'ui_act': {
|
|
594
|
+
if (!fields('ref', 'action', 'value') || !text(item.ref) || !text(item.action))
|
|
595
|
+
return null;
|
|
596
|
+
if (item.value !== undefined && !text(item.value))
|
|
597
|
+
return null;
|
|
598
|
+
// The application's own words for the control, as the session's tool
|
|
599
|
+
// last read them; the ref stays, since that is what runs.
|
|
600
|
+
const target = context.describeUiRef?.(item.ref) ?? `control ${item.ref}`;
|
|
601
|
+
if (item.action === 'set_value')
|
|
602
|
+
return {
|
|
603
|
+
line: `Set ${target} to ${JSON.stringify(item.value ?? '')}`,
|
|
604
|
+
coordinates: false,
|
|
605
|
+
};
|
|
606
|
+
const verb = UI_ACT_VERBS[item.action];
|
|
607
|
+
return verb ? { line: `${verb} ${target}`, coordinates: false } : null;
|
|
608
|
+
}
|
|
609
|
+
case 'zoom': {
|
|
610
|
+
const region = item.region;
|
|
611
|
+
return fields('region') &&
|
|
612
|
+
isRecord(region) &&
|
|
613
|
+
Object.keys(region).every((key) => ['x', 'y', 'width', 'height'].includes(key)) &&
|
|
614
|
+
['x', 'y', 'width', 'height'].every((key) => Number.isInteger(region[key]))
|
|
615
|
+
? {
|
|
616
|
+
line: `Zoom into ${region.width}x${region.height} at (${region.x}, ${region.y})`,
|
|
617
|
+
coordinates: true,
|
|
618
|
+
}
|
|
619
|
+
: null;
|
|
620
|
+
}
|
|
621
|
+
default:
|
|
622
|
+
return null;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
474
625
|
const PLAIN_TOOL_NAME = /^[\w.:-]+$/u;
|
|
475
626
|
/** The tools with a formatter above; an evolved shape of one opens exact-first. */
|
|
476
|
-
const FORMATTED_TOOLS = new Set([
|
|
627
|
+
const FORMATTED_TOOLS = new Set([
|
|
628
|
+
'bash',
|
|
629
|
+
'edit',
|
|
630
|
+
'write',
|
|
631
|
+
'Agent',
|
|
632
|
+
'computer_use',
|
|
633
|
+
]);
|
|
477
634
|
/** Labels group only the calls in this approval; they never invent execution phases. */
|
|
478
635
|
function compactAgentPlan(calls) {
|
|
479
636
|
const lines = [];
|