@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
|
@@ -3,6 +3,8 @@ export interface ChoicePickerOption {
|
|
|
3
3
|
readonly description: string;
|
|
4
4
|
readonly current?: boolean;
|
|
5
5
|
readonly default?: boolean;
|
|
6
|
+
/** The asker's recommendation (`ask_user_question`'s `recommended`), drawn as `[recommended]`. */
|
|
7
|
+
readonly recommended?: boolean;
|
|
6
8
|
readonly disabledReason?: string;
|
|
7
9
|
readonly selectedDescription?: string;
|
|
8
10
|
readonly searchText?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChoicePicker.d.ts","sourceRoot":"","sources":["../../src/tui/ChoicePicker.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,8GAA8G;IAC9G,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,sFAAsF;IACtF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,EAC5B,IAAY,EACZ,KAAK,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,UAAU,EACV,OAAO,EAAE,gBAAgB,EACzB,KAAK,EACL,iBAAoC,GACpC,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ChoicePicker.d.ts","sourceRoot":"","sources":["../../src/tui/ChoicePicker.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,kGAAkG;IAClG,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,8GAA8G;IAC9G,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,sFAAsF;IACtF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,EAC5B,IAAY,EACZ,KAAK,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,UAAU,EACV,OAAO,EAAE,gBAAgB,EACzB,KAAK,EACL,iBAAoC,GACpC,EAAE,iBAAiB,2CAmJnB"}
|
package/dist/tui/ChoicePicker.js
CHANGED
|
@@ -25,7 +25,13 @@ export function ChoicePicker({ busy = false, title, notice, options, selected, w
|
|
|
25
25
|
});
|
|
26
26
|
const { start, items: visible } = selectionWindow(options, selected, pageSize);
|
|
27
27
|
const count = `${selectedOption ? selected + 1 : 0}/${options.length}`;
|
|
28
|
-
const markerFor = (option) => [
|
|
28
|
+
const markerFor = (option) => [
|
|
29
|
+
option.current ? '[current]' : '',
|
|
30
|
+
option.default ? '[default]' : '',
|
|
31
|
+
option.recommended ? '[recommended]' : '',
|
|
32
|
+
]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.join(' ');
|
|
29
35
|
const markerWidth = Math.max(0, ...visible.map((option) => choiceDisplayWidth(markerFor(option))));
|
|
30
36
|
const rowWidth = Math.max(1, contentWidth - 4);
|
|
31
37
|
const labelWidth = stacked
|
|
@@ -50,7 +56,9 @@ export function ChoicePicker({ busy = false, title, notice, options, selected, w
|
|
|
50
56
|
? theme.text.muted
|
|
51
57
|
: active
|
|
52
58
|
? theme.text.primary
|
|
53
|
-
: theme.text.secondary, bold: active, children: truncateChoiceText(option.label, labelWidth) }) }), markerWidth > 0 ? (_jsx(Box, { width: markerWidth + 1, flexShrink: 0, paddingLeft: 1, children: _jsx(Text, { color: option.current
|
|
59
|
+
: theme.text.secondary, bold: active, children: truncateChoiceText(option.label, labelWidth) }) }), markerWidth > 0 ? (_jsx(Box, { width: markerWidth + 1, flexShrink: 0, paddingLeft: 1, children: _jsx(Text, { color: option.current || option.recommended
|
|
60
|
+
? theme.accent.assistant
|
|
61
|
+
: theme.text.muted, children: markers }) })) : null, !stacked ? (_jsx(Box, { paddingLeft: 1, flexGrow: 1, minWidth: 0, children: _jsx(Text, { color: theme.text.muted, children: truncateChoiceText(description, descriptionWidth) }) })) : null] }), stacked ? (_jsx(Box, { paddingLeft: 4, children: _jsx(Text, { color: theme.text.muted, children: truncateChoiceText(description, rowWidth) }) })) : null] }, `${option.label}-${index}`));
|
|
54
62
|
}), hasDetail ? (_jsx(Box, { height: 1, children: _jsx(Text, { color: selectedOption?.disabledReason ? theme.status.warn : theme.text.secondary, children: detail ? truncateChoiceText(detail, contentWidth) : '' }) })) : null, _jsx(Text, { color: theme.text.muted, children: truncateChoiceText(footer, contentWidth) })] }));
|
|
55
63
|
}
|
|
56
64
|
//# sourceMappingURL=ChoicePicker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChoicePicker.js","sourceRoot":"","sources":["../../src/tui/ChoicePicker.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AAE9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"ChoicePicker.js","sourceRoot":"","sources":["../../src/tui/ChoicePicker.tsx"],"names":[],"mappings":"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"}
|
package/dist/tui/Composer.d.ts
CHANGED
|
@@ -6,15 +6,18 @@
|
|
|
6
6
|
* autocomplete dropdown is open), Tab completes that command or queues the
|
|
7
7
|
* draft, Esc clears / closes the dropdown, ↑/↓ navigate the dropdown when open
|
|
8
8
|
* else browse history, Ctrl+R/Ctrl+S search history, Ctrl+W rubs out a word,
|
|
9
|
-
* Ctrl+G edits the draft in VISUAL/EDITOR, Backspace deletes
|
|
9
|
+
* Ctrl+G edits the draft in VISUAL/EDITOR, Backspace deletes, Alt+W drops or
|
|
10
|
+
* arms the composer trigger nearest the cursor (`./triggers/`).
|
|
10
11
|
*/
|
|
11
12
|
import type { MessageAttachment } from '@namzu/sdk';
|
|
12
13
|
import type { UserCommand } from '../user-commands/store.js';
|
|
13
14
|
import { type SlashCommand } from './slashCommands.js';
|
|
15
|
+
import { type TriggerContext } from './triggers/detect.js';
|
|
16
|
+
import type { TriggerId, TriggerRegistry } from './triggers/registry.js';
|
|
14
17
|
export interface ComposerProps {
|
|
15
18
|
readonly disabled?: boolean;
|
|
16
19
|
readonly reasoningEffortLevels?: readonly string[];
|
|
17
|
-
readonly onSubmit: (value: string, attachments
|
|
20
|
+
readonly onSubmit: (value: string, attachments: readonly MessageAttachment[] | undefined, mode: ComposerSubmitMode, meta: SubmitMeta) => void;
|
|
18
21
|
readonly history: readonly string[];
|
|
19
22
|
/** Operator-defined commands, offered in the dropdown alongside builtins. */
|
|
20
23
|
readonly userCommands?: readonly UserCommand[];
|
|
@@ -77,9 +80,65 @@ export interface ComposerProps {
|
|
|
77
80
|
readonly onOpenAgentPanel?: () => void;
|
|
78
81
|
/** Shift+Tab. Absent means the key does nothing, which the composer footer then does not advertise. */
|
|
79
82
|
readonly onCycleMode?: () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Composer triggers (`./triggers/`). Absent means the feature is off: no
|
|
85
|
+
* highlight, no tag row, and every submit carries no triggers.
|
|
86
|
+
*/
|
|
87
|
+
readonly triggers?: ComposerTriggerSettings;
|
|
88
|
+
/** A turn is running, so Enter steers into it; the tag row says what that means for a trigger. */
|
|
89
|
+
readonly turnActive?: boolean;
|
|
90
|
+
}
|
|
91
|
+
export interface ComposerTriggerSettings {
|
|
92
|
+
readonly registry: TriggerRegistry;
|
|
93
|
+
/** Show suggestions (`composerTriggers.suggest`). */
|
|
94
|
+
readonly suggest: boolean;
|
|
95
|
+
readonly context: TriggerContext;
|
|
96
|
+
/** The model's highest published effort level, named in the tag row by the max-effort trigger. */
|
|
97
|
+
readonly highestEffort?: string;
|
|
98
|
+
/** The level hypermode pins on this model (`xhigh`, or the nearest below it), named in its tag. */
|
|
99
|
+
readonly hypermodeEffort?: string;
|
|
80
100
|
}
|
|
81
101
|
/** Return addresses the active turn; Tab deliberately addresses the follow-up queue. */
|
|
82
102
|
export type ComposerSubmitMode = 'submit' | 'queue';
|
|
103
|
+
/**
|
|
104
|
+
* Where a submitted line came from. Every caller of the App's submit path
|
|
105
|
+
* names one; none is optional, so a new caller cannot inherit the operator's
|
|
106
|
+
* authority by leaving an argument out.
|
|
107
|
+
*
|
|
108
|
+
* - `composer`: the operator's own keys in this composer, sent with Enter or Tab.
|
|
109
|
+
* - `composer-dropdown`: a command the operator ran from the slash dropdown.
|
|
110
|
+
* - `command-picker`: a command a picker or menu re-entered through the command path.
|
|
111
|
+
* - `operator-loop`: a `/loop` the operator made, firing.
|
|
112
|
+
* - `model-loop`: a loop the model made with `session_loop`, firing. Its text
|
|
113
|
+
* is always a plain prompt: never a `/` command, a `!` shell line, a `#`
|
|
114
|
+
* memory note or a model switch, and never an entry in composer history.
|
|
115
|
+
*/
|
|
116
|
+
export type SubmitSource = 'composer' | 'composer-dropdown' | 'command-picker' | 'operator-loop' | 'model-loop';
|
|
117
|
+
/**
|
|
118
|
+
* A trigger armed when the operator pressed Enter or Tab, with its words'
|
|
119
|
+
* offsets in the message as sent (the trimmed text `onSubmit` receives).
|
|
120
|
+
*/
|
|
121
|
+
export interface ArmedTrigger {
|
|
122
|
+
readonly id: TriggerId;
|
|
123
|
+
readonly start: number;
|
|
124
|
+
readonly end: number;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Only the composer's own submit can carry triggers: the type has no
|
|
128
|
+
* `triggers` for any other source, so a loop, a picker or a menu cannot arm
|
|
129
|
+
* one by passing an argument.
|
|
130
|
+
*/
|
|
131
|
+
export type SubmitMeta = {
|
|
132
|
+
readonly source: 'composer';
|
|
133
|
+
readonly triggers: readonly ArmedTrigger[];
|
|
134
|
+
/**
|
|
135
|
+
* The message is nothing but armed triggers and filler words, with no
|
|
136
|
+
* paste chip or attachment: a standalone trigger runs its command.
|
|
137
|
+
*/
|
|
138
|
+
readonly onlyTriggers: boolean;
|
|
139
|
+
} | {
|
|
140
|
+
readonly source: Exclude<SubmitSource, 'composer'>;
|
|
141
|
+
};
|
|
83
142
|
export interface ComposerDraft {
|
|
84
143
|
readonly token: number;
|
|
85
144
|
readonly text: string;
|
|
@@ -103,5 +162,5 @@ export declare function suggestionWindowSize(rows: number | undefined): number;
|
|
|
103
162
|
* operators already bring to this key.
|
|
104
163
|
*/
|
|
105
164
|
export declare function deletePreviousWord(source: string): string;
|
|
106
|
-
export declare function Composer({ disabled, reasoningEffortLevels, onSubmit, history, userCommands, builtins, mentionCandidates, hidden, escapeInterrupts, onNotice, onStepReasoningEffort, onExternalEdit, onEditPrevious, draftToRestore, onDraftRestored, onDraftPresenceChange, onOpenAgentPanel, onCycleMode, }: ComposerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
165
|
+
export declare function Composer({ disabled, reasoningEffortLevels, onSubmit, history, userCommands, builtins, mentionCandidates, hidden, escapeInterrupts, onNotice, onStepReasoningEffort, onExternalEdit, onEditPrevious, draftToRestore, onDraftRestored, onDraftPresenceChange, onOpenAgentPanel, onCycleMode, triggers, turnActive, }: ComposerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
107
166
|
//# sourceMappingURL=Composer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../src/tui/Composer.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../src/tui/Composer.tsx"],"names":[],"mappings":"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"}
|
package/dist/tui/Composer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Box, Text, useInput, usePaste, useWindowSize } from 'ink';
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { readClipboardImage } from '../integrations/clipboard/image.js';
|
|
@@ -7,6 +7,9 @@ import { parseModelSelectionIntent } from './model-selection-intent.js';
|
|
|
7
7
|
import { matchSlashCommands } from './slashCommands.js';
|
|
8
8
|
import { terminalDisplayText } from './terminal-display.js';
|
|
9
9
|
import { theme } from './theme.js';
|
|
10
|
+
import { tagRow } from './triggers/copy.js';
|
|
11
|
+
import { EMPTY_DETECTION, detectTriggers, } from './triggers/detect.js';
|
|
12
|
+
import { applyEdit, diffEdit, overrideMap, replaceAll, shiftOverrides, } from './triggers/provenance.js';
|
|
10
13
|
const MIN_SUGGESTIONS = 6;
|
|
11
14
|
const MAX_SUGGESTIONS = 12;
|
|
12
15
|
const SUGGESTION_FURNITURE_ROWS = 12;
|
|
@@ -21,6 +24,34 @@ const COMPOSER_DISPLAY_LINES = 8;
|
|
|
21
24
|
const graphemeSegmenter = new Intl.Segmenter(undefined, {
|
|
22
25
|
granularity: 'grapheme',
|
|
23
26
|
});
|
|
27
|
+
/**
|
|
28
|
+
* `source[from, to)` cut at trigger words, each piece made terminal-safe on
|
|
29
|
+
* its own. Escaping after cutting, never before, is what keeps the highlight
|
|
30
|
+
* on the right cells: `terminalDisplayText` turns one unsafe code point into
|
|
31
|
+
* several characters, and offsets into the source would miss them.
|
|
32
|
+
*/
|
|
33
|
+
function displaySegments(source, from, to, styled) {
|
|
34
|
+
const segments = [];
|
|
35
|
+
let at = from;
|
|
36
|
+
for (const span of styled) {
|
|
37
|
+
const start = Math.max(from, span.start);
|
|
38
|
+
const end = Math.min(to, span.end);
|
|
39
|
+
if (end <= start || start < at)
|
|
40
|
+
continue;
|
|
41
|
+
if (start > at)
|
|
42
|
+
segments.push({ text: terminalDisplayText(source.slice(at, start)) });
|
|
43
|
+
segments.push({ text: terminalDisplayText(source.slice(start, end)), style: span.style });
|
|
44
|
+
at = end;
|
|
45
|
+
}
|
|
46
|
+
if (to > at)
|
|
47
|
+
segments.push({ text: terminalDisplayText(source.slice(at, to)) });
|
|
48
|
+
return segments;
|
|
49
|
+
}
|
|
50
|
+
function renderSegments(segments) {
|
|
51
|
+
return segments.map((segment, index) => segment.style ? (_jsx(Text
|
|
52
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: segments of one draft, in order.
|
|
53
|
+
, { color: segment.style === 'armed' ? theme.accent.trigger : theme.status.warn, bold: segment.style === 'armed', underline: segment.style === 'armed', children: segment.text }, index)) : (segment.text));
|
|
54
|
+
}
|
|
24
55
|
/**
|
|
25
56
|
* Visible rows in a completion menu for this terminal height.
|
|
26
57
|
*
|
|
@@ -144,6 +175,8 @@ function composerDisplayValue(source, cursor) {
|
|
|
144
175
|
after: terminalDisplayText(source.slice(cursor, end)),
|
|
145
176
|
leadingEllipsis: start > 0,
|
|
146
177
|
trailingEllipsis: end < source.length,
|
|
178
|
+
start,
|
|
179
|
+
end,
|
|
147
180
|
};
|
|
148
181
|
}
|
|
149
182
|
/**
|
|
@@ -199,7 +232,7 @@ function deleteNextWordAt(source, cursor) {
|
|
|
199
232
|
const end = nextWordBoundary(source, cursor);
|
|
200
233
|
return { value: source.slice(0, cursor) + source.slice(end), cursor };
|
|
201
234
|
}
|
|
202
|
-
export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, history, userCommands = [], builtins, mentionCandidates = [], hidden = false, escapeInterrupts = false, onNotice, onStepReasoningEffort, onExternalEdit, onEditPrevious, draftToRestore = null, onDraftRestored, onDraftPresenceChange, onOpenAgentPanel, onCycleMode, }) {
|
|
235
|
+
export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, history, userCommands = [], builtins, mentionCandidates = [], hidden = false, escapeInterrupts = false, onNotice, onStepReasoningEffort, onExternalEdit, onEditPrevious, draftToRestore = null, onDraftRestored, onDraftPresenceChange, onOpenAgentPanel, onCycleMode, triggers, turnActive = false, }) {
|
|
203
236
|
const terminal = useWindowSize();
|
|
204
237
|
const [value, setValueState] = useState('');
|
|
205
238
|
const valueRef = useRef('');
|
|
@@ -208,6 +241,12 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
208
241
|
const [, setHistoryIndexState] = useState(-1);
|
|
209
242
|
const historyIndexRef = useRef(-1);
|
|
210
243
|
const historyDraftRef = useRef(null);
|
|
244
|
+
// Characters of the draft not typed here, and Alt+W decisions. Refs, so
|
|
245
|
+
// submit reads what the last key left; `triggerVersion` re-renders when
|
|
246
|
+
// only an Alt+W decision changed.
|
|
247
|
+
const spansRef = useRef([]);
|
|
248
|
+
const overridesRef = useRef([]);
|
|
249
|
+
const [triggerVersion, setTriggerVersion] = useState(0);
|
|
211
250
|
const [historySearch, setHistorySearchState] = useState(null);
|
|
212
251
|
const historySearchRef = useRef(null);
|
|
213
252
|
const verticalColumnRef = useRef(null);
|
|
@@ -249,9 +288,16 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
249
288
|
const visibleFileSuggestions = fileSuggestions.slice(suggestionStart, suggestionStart + suggestionWindow);
|
|
250
289
|
const displayValue = composerDisplayValue(value, cursor);
|
|
251
290
|
const commandColumnWidth = Math.min(24, Math.max(10, ...visibleCommandSuggestions.map((command) => command.name.length + 4)));
|
|
252
|
-
|
|
291
|
+
/**
|
|
292
|
+
* Replace the whole draft. `spans` says which characters were not typed
|
|
293
|
+
* here; absent, the whole text counts as `origin`. Alt+W decisions belong
|
|
294
|
+
* to the text they were made on and go with it.
|
|
295
|
+
*/
|
|
296
|
+
const setBuffer = useCallback((nextValue, nextCursor = nextValue.length, origin = 'recalled', spans) => {
|
|
253
297
|
valueRef.current = nextValue;
|
|
254
298
|
cursorRef.current = nextCursor;
|
|
299
|
+
spansRef.current = spans ?? replaceAll(nextValue.length, origin);
|
|
300
|
+
overridesRef.current = [];
|
|
255
301
|
setValueState(nextValue);
|
|
256
302
|
setCursorState(nextCursor);
|
|
257
303
|
}, []);
|
|
@@ -268,18 +314,56 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
268
314
|
selectedRef.current = resolved;
|
|
269
315
|
setSelected(resolved);
|
|
270
316
|
}, []);
|
|
271
|
-
|
|
317
|
+
/** The triggers `draft` names, read with this draft's provenance and Alt+W decisions. */
|
|
318
|
+
const detect = (draft) => triggers
|
|
319
|
+
? detectTriggers(draft, triggers.registry, triggers.context, {
|
|
320
|
+
nonTyped: spansRef.current,
|
|
321
|
+
overrides: overrideMap(overridesRef.current),
|
|
322
|
+
suggest: triggers.suggest,
|
|
323
|
+
})
|
|
324
|
+
: EMPTY_DETECTION;
|
|
325
|
+
const setOverride = (hit, state) => {
|
|
326
|
+
const others = overridesRef.current.filter((override) => !(override.id === hit.id && override.start === hit.start));
|
|
327
|
+
overridesRef.current =
|
|
328
|
+
state === null ? others : [...others, { id: hit.id, start: hit.start, end: hit.end, state }];
|
|
329
|
+
setTriggerVersion((version) => version + 1);
|
|
330
|
+
};
|
|
331
|
+
/** Alt+W: the trigger nearest the cursor changes state. */
|
|
332
|
+
const toggleNearestTrigger = () => {
|
|
333
|
+
const cursor = cursorRef.current;
|
|
334
|
+
const distance = (hit) => cursor < hit.start ? hit.start - cursor : cursor > hit.end ? cursor - hit.end : 0;
|
|
335
|
+
const nearest = [...detect(valueRef.current).hits].sort((a, b) => distance(a) - distance(b))[0];
|
|
336
|
+
if (!nearest)
|
|
337
|
+
return;
|
|
338
|
+
const decided = overridesRef.current.some((override) => override.id === nearest.id && override.start === nearest.start);
|
|
339
|
+
if (decided)
|
|
340
|
+
setOverride(nearest, null);
|
|
341
|
+
else if (nearest.state === 'suggested')
|
|
342
|
+
setOverride(nearest, 'armed');
|
|
343
|
+
else
|
|
344
|
+
setOverride(nearest, 'dropped');
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* One edit of the draft, by the operator (`typed`) or not. The characters
|
|
348
|
+
* it inserts are remembered as typed or not, and the draft's other spans
|
|
349
|
+
* and Alt+W decisions move with it.
|
|
350
|
+
*/
|
|
351
|
+
const editBuffer = useCallback((nextValue, nextCursor = nextValue.length, origin = 'typed') => {
|
|
272
352
|
verticalColumnRef.current = null;
|
|
273
353
|
historyDraftRef.current = null;
|
|
274
354
|
setHistorySearch(null);
|
|
275
355
|
setHistoryIndex(-1);
|
|
276
|
-
|
|
356
|
+
const edit = diffEdit(valueRef.current, nextValue, cursorRef.current);
|
|
357
|
+
const spans = applyEdit(spansRef.current, edit, origin);
|
|
358
|
+
const overrides = shiftOverrides(overridesRef.current, edit);
|
|
359
|
+
setBuffer(nextValue, nextCursor, origin, spans);
|
|
360
|
+
overridesRef.current = overrides;
|
|
277
361
|
}, [setBuffer, setHistoryIndex, setHistorySearch]);
|
|
278
362
|
const reset = useCallback(() => {
|
|
279
363
|
verticalColumnRef.current = null;
|
|
280
364
|
historyDraftRef.current = null;
|
|
281
365
|
setHistorySearch(null);
|
|
282
|
-
setBuffer('', 0);
|
|
366
|
+
setBuffer('', 0, 'typed');
|
|
283
367
|
setHistoryIndex(-1);
|
|
284
368
|
setSelectedIndex(0);
|
|
285
369
|
setPastes([]);
|
|
@@ -290,7 +374,7 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
290
374
|
if (!draftToRestore || restoredTokenRef.current === draftToRestore.token)
|
|
291
375
|
return;
|
|
292
376
|
restoredTokenRef.current = draftToRestore.token;
|
|
293
|
-
setBuffer(draftToRestore.text);
|
|
377
|
+
setBuffer(draftToRestore.text, draftToRestore.text.length, 'restored');
|
|
294
378
|
setHistoryIndex(-1);
|
|
295
379
|
setSelectedIndex(0);
|
|
296
380
|
verticalColumnRef.current = null;
|
|
@@ -322,7 +406,7 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
322
406
|
}
|
|
323
407
|
const position = cursorRef.current;
|
|
324
408
|
setSelectedIndex(0);
|
|
325
|
-
editBuffer(valueRef.current.slice(0, position) + normalized + valueRef.current.slice(position), position + normalized.length);
|
|
409
|
+
editBuffer(valueRef.current.slice(0, position) + normalized + valueRef.current.slice(position), position + normalized.length, 'pasted');
|
|
326
410
|
}, { isActive: !disabled && !hidden });
|
|
327
411
|
useInput((input, key) => {
|
|
328
412
|
// Hidden means the screen belongs to something else, so a keypress
|
|
@@ -356,7 +440,8 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
356
440
|
const liveSelection = Math.min(selectedRef.current, Math.max(0, liveSuggestionCount - 1));
|
|
357
441
|
const acceptSuggestion = () => {
|
|
358
442
|
if (liveSuggestionKind === 'command') {
|
|
359
|
-
|
|
443
|
+
const completed = `/${liveCommandSuggestions[liveSelection]?.name ?? ''} `;
|
|
444
|
+
editBuffer(completed, completed.length, 'completion');
|
|
360
445
|
setSelectedIndex(0);
|
|
361
446
|
return true;
|
|
362
447
|
}
|
|
@@ -367,7 +452,7 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
367
452
|
const replacement = `@${path} `;
|
|
368
453
|
editBuffer(valueRef.current.slice(0, liveMention.start) +
|
|
369
454
|
replacement +
|
|
370
|
-
valueRef.current.slice(liveMention.end), liveMention.start + replacement.length);
|
|
455
|
+
valueRef.current.slice(liveMention.end), liveMention.start + replacement.length, 'completion');
|
|
371
456
|
setSelectedIndex(0);
|
|
372
457
|
return true;
|
|
373
458
|
}
|
|
@@ -395,10 +480,18 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
395
480
|
if (message.length === 0 && attachments.length === 0)
|
|
396
481
|
return false;
|
|
397
482
|
const submittedAttachments = attachments.length > 0 ? attachments : undefined;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
483
|
+
// Read again from what the last key left, not from the last render.
|
|
484
|
+
const detection = detect(valueRef.current);
|
|
485
|
+
// The message is the draft trimmed: offsets move by what the trim took.
|
|
486
|
+
const lead = valueRef.current.length - valueRef.current.trimStart().length;
|
|
487
|
+
const armed = detection.hits
|
|
488
|
+
.filter((hit) => hit.state === 'armed')
|
|
489
|
+
.map((hit) => ({ id: hit.id, start: hit.start - lead, end: hit.end - lead }));
|
|
490
|
+
onSubmit(message, submittedAttachments, mode, {
|
|
491
|
+
source: 'composer',
|
|
492
|
+
triggers: armed,
|
|
493
|
+
onlyTriggers: armed.length > 0 && detection.onlyTriggers && pastes.length === 0 && attachments.length === 0,
|
|
494
|
+
});
|
|
402
495
|
reset();
|
|
403
496
|
return true;
|
|
404
497
|
};
|
|
@@ -420,6 +513,7 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
420
513
|
draft: browsedHistoryDraft ?? {
|
|
421
514
|
value: query,
|
|
422
515
|
cursor: cursorRef.current,
|
|
516
|
+
spans: spansRef.current,
|
|
423
517
|
},
|
|
424
518
|
query,
|
|
425
519
|
matches: [...history]
|
|
@@ -434,15 +528,17 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
434
528
|
const next = { ...search, position };
|
|
435
529
|
setHistorySearch(next);
|
|
436
530
|
if (position < 0)
|
|
437
|
-
setBuffer(next.draft.value, next.draft.cursor);
|
|
531
|
+
setBuffer(next.draft.value, next.draft.cursor, 'typed', next.draft.spans);
|
|
438
532
|
else
|
|
439
|
-
setBuffer(next.matches[position] ?? next.draft.value);
|
|
533
|
+
setBuffer(next.matches[position] ?? next.draft.value, undefined, 'recalled');
|
|
440
534
|
return;
|
|
441
535
|
}
|
|
442
536
|
if (key.return) {
|
|
443
537
|
if (liveSuggestionKind === 'command') {
|
|
444
538
|
// Run the highlighted command.
|
|
445
|
-
onSubmit(`/${liveCommandSuggestions[liveSelection]?.name ?? ''}
|
|
539
|
+
onSubmit(`/${liveCommandSuggestions[liveSelection]?.name ?? ''}`, undefined, 'submit', {
|
|
540
|
+
source: 'composer-dropdown',
|
|
541
|
+
});
|
|
446
542
|
reset();
|
|
447
543
|
return;
|
|
448
544
|
}
|
|
@@ -471,7 +567,7 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
471
567
|
return;
|
|
472
568
|
const activeSearch = historySearchRef.current;
|
|
473
569
|
if (activeSearch) {
|
|
474
|
-
setBuffer(activeSearch.draft.value, activeSearch.draft.cursor);
|
|
570
|
+
setBuffer(activeSearch.draft.value, activeSearch.draft.cursor, 'typed', activeSearch.draft.spans);
|
|
475
571
|
setHistorySearch(null);
|
|
476
572
|
return;
|
|
477
573
|
}
|
|
@@ -510,6 +606,13 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
510
606
|
return;
|
|
511
607
|
}
|
|
512
608
|
const position = cursorRef.current;
|
|
609
|
+
// Right after an armed keyword, Backspace drops the trigger first
|
|
610
|
+
// and deletes nothing; the next Backspace deletes as usual.
|
|
611
|
+
const keyword = detect(valueRef.current).hits.find((hit) => hit.state === 'armed' && hit.id === 'hypermode' && hit.end === position);
|
|
612
|
+
if (keyword && keyword.end - keyword.start === 'hypermode'.length) {
|
|
613
|
+
setOverride(keyword, 'dropped');
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
513
616
|
const previous = previousGraphemeBoundary(valueRef.current, position);
|
|
514
617
|
editBuffer(valueRef.current.slice(0, previous) + valueRef.current.slice(position), previous);
|
|
515
618
|
return;
|
|
@@ -592,11 +695,12 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
592
695
|
historyDraftRef.current = {
|
|
593
696
|
value: valueRef.current,
|
|
594
697
|
cursor: cursorRef.current,
|
|
698
|
+
spans: spansRef.current,
|
|
595
699
|
};
|
|
596
700
|
}
|
|
597
701
|
const next = Math.min(historyIndexRef.current + 1, history.length - 1);
|
|
598
702
|
setHistoryIndex(next);
|
|
599
|
-
setBuffer(history[history.length - 1 - next] ?? '');
|
|
703
|
+
setBuffer(history[history.length - 1 - next] ?? '', undefined, 'recalled');
|
|
600
704
|
return;
|
|
601
705
|
}
|
|
602
706
|
if (key.downArrow || (key.ctrl && input === 'n')) {
|
|
@@ -622,12 +726,12 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
622
726
|
const draft = historyDraftRef.current;
|
|
623
727
|
historyDraftRef.current = null;
|
|
624
728
|
setHistoryIndex(-1);
|
|
625
|
-
setBuffer(draft?.value ?? '', draft?.cursor ?? 0);
|
|
729
|
+
setBuffer(draft?.value ?? '', draft?.cursor ?? 0, 'typed', draft?.spans ?? []);
|
|
626
730
|
return;
|
|
627
731
|
}
|
|
628
732
|
const next = historyIndexRef.current - 1;
|
|
629
733
|
setHistoryIndex(next);
|
|
630
|
-
setBuffer(history[history.length - 1 - next] ?? '');
|
|
734
|
+
setBuffer(history[history.length - 1 - next] ?? '', undefined, 'recalled');
|
|
631
735
|
return;
|
|
632
736
|
}
|
|
633
737
|
if (key.ctrl && input === 'g') {
|
|
@@ -646,7 +750,9 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
646
750
|
setHistoryIndex(-1);
|
|
647
751
|
setHistorySearch(null);
|
|
648
752
|
setSelectedIndex(0);
|
|
649
|
-
|
|
753
|
+
historyDraftRef.current = null;
|
|
754
|
+
verticalColumnRef.current = null;
|
|
755
|
+
setBuffer(cleaned, cleaned.length, 'editor');
|
|
650
756
|
})
|
|
651
757
|
.catch((error) => {
|
|
652
758
|
onNotice?.(`Cannot open external editor: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -713,7 +819,13 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
713
819
|
if (killed.length === 0)
|
|
714
820
|
return;
|
|
715
821
|
const position = cursorRef.current;
|
|
716
|
-
editBuffer(valueRef.current.slice(0, position) + killed + valueRef.current.slice(position), position + killed.length);
|
|
822
|
+
editBuffer(valueRef.current.slice(0, position) + killed + valueRef.current.slice(position), position + killed.length, 'yank');
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
// Alt+W: drop the trigger nearest the cursor, or bring one back, or
|
|
826
|
+
// arm one the row only suggested.
|
|
827
|
+
if (key.meta && input === 'w') {
|
|
828
|
+
toggleNearestTrigger();
|
|
717
829
|
return;
|
|
718
830
|
}
|
|
719
831
|
if (key.ctrl || key.meta)
|
|
@@ -734,7 +846,14 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
734
846
|
}
|
|
735
847
|
setSelectedIndex(0);
|
|
736
848
|
const position = cursorRef.current;
|
|
737
|
-
|
|
849
|
+
// One grapheme is a key. More in one chunk is queued keys or a paste
|
|
850
|
+
// without bracketed-paste markers; nothing here can tell which, so it
|
|
851
|
+
// does not count as typed.
|
|
852
|
+
let graphemes = 0;
|
|
853
|
+
for (const _ of graphemeSegmenter.segment(input))
|
|
854
|
+
if (++graphemes > 1)
|
|
855
|
+
break;
|
|
856
|
+
editBuffer(valueRef.current.slice(0, position) + input + valueRef.current.slice(position), position + input.length, graphemes > 1 ? 'burst' : 'typed');
|
|
738
857
|
}, { isActive: !disabled && !hidden });
|
|
739
858
|
// After every hook, so the component keeps its state while it is off screen.
|
|
740
859
|
// This is the whole fix: React preserves a mounted component's state, and
|
|
@@ -747,12 +866,30 @@ export function Composer({ disabled = false, reasoningEffortLevels, onSubmit, hi
|
|
|
747
866
|
: undefined;
|
|
748
867
|
const effortAvailable = effortIntent === 'default' ||
|
|
749
868
|
(effortIntent !== undefined && reasoningEffortLevels?.includes(effortIntent));
|
|
869
|
+
void triggerVersion;
|
|
870
|
+
const detection = !modelIntent && !effortIntent && !disabled ? detect(value) : EMPTY_DETECTION;
|
|
871
|
+
const triggerRow = triggers
|
|
872
|
+
? tagRow(detection, {
|
|
873
|
+
columns: Math.max(1, (terminal.columns ?? 80) - 4),
|
|
874
|
+
turnActive,
|
|
875
|
+
highestEffort: triggers.highestEffort,
|
|
876
|
+
hypermodeEffort: triggers.hypermodeEffort,
|
|
877
|
+
standaloneAllowed: pastes.length === 0 && attachments.length === 0,
|
|
878
|
+
})
|
|
879
|
+
: null;
|
|
880
|
+
const styledSpans = detection.hits.flatMap((hit) => hit.state === 'armed' || hit.state === 'unavailable'
|
|
881
|
+
? [{ start: hit.start, end: hit.end, style: hit.state }]
|
|
882
|
+
: []);
|
|
883
|
+
const beforeSegments = displaySegments(value, displayValue.start, cursor, styledSpans);
|
|
884
|
+
const afterSegments = displaySegments(value, cursor, displayValue.end, styledSpans);
|
|
750
885
|
const promptGlyph = disabled ? '…' : '›';
|
|
751
886
|
const showPlaceholder = !disabled && value.length === 0 && !editPreviousArmed;
|
|
752
887
|
const historySearchQuery = historySearch
|
|
753
888
|
? composerDisplayValue(historySearch.query, historySearch.query.length)
|
|
754
889
|
: null;
|
|
755
|
-
return (_jsxs(Box, { flexDirection: "column", children: [effortIntent ? (_jsx(Box, { paddingX: 1, children: _jsxs(Text, { color: effortAvailable ? theme.accent.tool : theme.status.warn, children: ["Effort: ", effortIntent, " \u00B7 ", effortAvailable ? 'requested' : 'unavailable for this model'] }) })) : null, modelIntent ? (_jsx(Box, { paddingX: 1, children: _jsxs(Text, { color: theme.accent.tool, children: ["Model: ", modelIntent.query, " \u00B7 requested"] }) })) : null,
|
|
890
|
+
return (_jsxs(Box, { flexDirection: "column", children: [effortIntent ? (_jsx(Box, { paddingX: 1, children: _jsxs(Text, { color: effortAvailable ? theme.accent.tool : theme.status.warn, children: ["Effort: ", effortIntent, " \u00B7 ", effortAvailable ? 'requested' : 'unavailable for this model'] }) })) : null, modelIntent ? (_jsx(Box, { paddingX: 1, children: _jsxs(Text, { color: theme.accent.tool, children: ["Model: ", modelIntent.query, " \u00B7 requested"] }) })) : null, triggerRow ? (_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: detection.hits.some((hit) => hit.state === 'armed')
|
|
891
|
+
? theme.accent.trigger
|
|
892
|
+
: theme.text.muted, wrap: "truncate-end", children: triggerRow }) })) : null, pastes.length > 0 || attachments.length > 0 ? (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingBottom: 1, children: [attachments.map((attachment, i) => (_jsxs(Text, { color: theme.accent.tool, children: ["\u2398 ", attachmentLabel(attachment, i)] }, `attachment-${i}`))), pastes.map((p, i) => (_jsxs(Text, { color: theme.text.secondary, children: ["\u2398 Pasted text #", i + 1, " \u00B7 ", Array.from(p).length, " chars"] }, `paste-${i}`)))] })) : null, _jsxs(Box, { paddingX: 1, children: [_jsx(Box, { width: 2, flexShrink: 0, children: _jsx(Text, { color: disabled ? theme.text.muted : theme.accent.user, bold: true, children: promptGlyph }) }), _jsx(Box, { flexGrow: 1, children: showPlaceholder ? (_jsx(Text, { color: theme.text.muted, children: "Type a message\u2026 (/help for commands)" })) : editPreviousArmed ? (_jsx(Text, { color: theme.text.muted, children: "Press Esc again to edit a previous prompt" })) : (_jsxs(Text, { color: disabled ? theme.text.muted : theme.text.primary, wrap: "wrap", children: [displayValue.leadingEllipsis ? '… ' : '', renderSegments(beforeSegments), disabled ? null : _jsx(Text, { color: theme.border.focus, children: "\u258F" }), renderSegments(afterSegments), displayValue.trailingEllipsis ? ' …' : ''] })) })] }), historySearch && historySearchQuery ? (_jsx(Box, { paddingX: 1, paddingTop: 1, children: _jsxs(Text, { color: theme.text.muted, children: ["history \u201C", historySearchQuery.leadingEllipsis ? '… ' : '', historySearchQuery.before, "\u201D \u00B7", ' ', historySearch.position < 0
|
|
756
893
|
? `draft · ${historySearch.matches.length} match${historySearch.matches.length === 1 ? '' : 'es'}`
|
|
757
894
|
: `${historySearch.position + 1}/${historySearch.matches.length}`, ' ', "\u00B7 Ctrl+R older \u00B7 Ctrl+S newer \u00B7 Esc restore"] }) })) : null, suggestionKind === 'command' ? (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingTop: 1, width: "100%", children: [visibleCommandSuggestions.map((cmd, i) => {
|
|
758
895
|
const absoluteIndex = suggestionStart + i;
|