@ashx-j/lunr 0.2.21 → 0.2.23
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 +4 -2
- package/README.md +23 -5
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +1 -0
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/lunr-browser.d.ts +9 -0
- package/dist/builtin-extensions/lunr-browser.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-browser.js +169 -0
- package/dist/builtin-extensions/lunr-browser.js.map +1 -0
- package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-todos.js +15 -0
- package/dist/builtin-extensions/lunr-todos.js.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-intercom/index.js +3 -0
- package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js +5 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +18 -5
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.d.ts +17 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.js +45 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/communication.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js +4 -11
- package/dist/builtin-extensions/pi-subagents/src/intercom/intercom-bridge.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +4 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +160 -51
- package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +5 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +3 -2
- package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.js +2 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/auto-drain.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +11 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +41 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +4 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.js +3 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-control.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts +18 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +48 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.js +11 -7
- package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/install-cli.d.ts.map +1 -1
- package/dist/cli/install-cli.js +15 -45
- package/dist/cli/install-cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +9 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +126 -29
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +22 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +250 -105
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/browser/network.d.ts +9 -0
- package/dist/core/browser/network.d.ts.map +1 -0
- package/dist/core/browser/network.js +146 -0
- package/dist/core/browser/network.js.map +1 -0
- package/dist/core/browser/runtime.d.ts +24 -0
- package/dist/core/browser/runtime.d.ts.map +1 -0
- package/dist/core/browser/runtime.js +289 -0
- package/dist/core/browser/runtime.js.map +1 -0
- package/dist/core/browser/schema.d.ts +16 -0
- package/dist/core/browser/schema.d.ts.map +1 -0
- package/dist/core/browser/schema.js +36 -0
- package/dist/core/browser/schema.js.map +1 -0
- package/dist/core/browser/settings.d.ts +8 -0
- package/dist/core/browser/settings.d.ts.map +1 -0
- package/dist/core/browser/settings.js +30 -0
- package/dist/core/browser/settings.js.map +1 -0
- package/dist/core/browser/setup.d.ts +2 -0
- package/dist/core/browser/setup.d.ts.map +1 -0
- package/dist/core/browser/setup.js +16 -0
- package/dist/core/browser/setup.js.map +1 -0
- package/dist/core/customize.d.ts.map +1 -1
- package/dist/core/customize.js +15 -14
- package/dist/core/customize.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/install-features.d.ts.map +1 -1
- package/dist/core/install-features.js +10 -8
- package/dist/core/install-features.js.map +1 -1
- package/dist/core/memory-cap.d.ts.map +1 -1
- package/dist/core/memory-cap.js +5 -3
- package/dist/core/memory-cap.js.map +1 -1
- package/dist/core/model-tiers.d.ts.map +1 -1
- package/dist/core/model-tiers.js +9 -6
- package/dist/core/model-tiers.js.map +1 -1
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +9 -0
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +3 -0
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/process-registry.d.ts.map +1 -1
- package/dist/core/process-registry.js +6 -4
- package/dist/core/process-registry.js.map +1 -1
- package/dist/core/runtime-scope.d.ts +11 -0
- package/dist/core/runtime-scope.d.ts.map +1 -0
- package/dist/core/runtime-scope.js +3 -0
- package/dist/core/runtime-scope.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +13 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-handoff.d.ts +35 -0
- package/dist/core/session-handoff.d.ts.map +1 -0
- package/dist/core/session-handoff.js +214 -0
- package/dist/core/session-handoff.js.map +1 -0
- package/dist/core/session-manager.d.ts +20 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +184 -22
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-ownership.d.ts +28 -0
- package/dist/core/session-ownership.d.ts.map +1 -0
- package/dist/core/session-ownership.js +138 -0
- package/dist/core/session-ownership.js.map +1 -0
- package/dist/core/session-retention.d.ts.map +1 -1
- package/dist/core/session-retention.js +11 -2
- package/dist/core/session-retention.js.map +1 -1
- package/dist/core/settings-manager.d.ts +11 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +27 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/subagent-wait-interruption.d.ts +11 -0
- package/dist/core/subagent-wait-interruption.d.ts.map +1 -0
- package/dist/core/subagent-wait-interruption.js +19 -0
- package/dist/core/subagent-wait-interruption.js.map +1 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +7 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/todo-settings.d.ts +5 -0
- package/dist/core/todo-settings.d.ts.map +1 -0
- package/dist/core/todo-settings.js +7 -0
- package/dist/core/todo-settings.js.map +1 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +4 -4
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +5 -3
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +4 -4
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -4
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +4 -4
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +4 -4
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +14 -5
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +34 -7
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +4 -4
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/usage-service.d.ts.map +1 -1
- package/dist/core/usage-service.js +5 -3
- package/dist/core/usage-service.js.map +1 -1
- package/dist/gateway/adapters/discord.d.ts +12 -1
- package/dist/gateway/adapters/discord.d.ts.map +1 -1
- package/dist/gateway/adapters/discord.js +112 -17
- package/dist/gateway/adapters/discord.js.map +1 -1
- package/dist/gateway/adapters/telegram.d.ts +4 -2
- package/dist/gateway/adapters/telegram.d.ts.map +1 -1
- package/dist/gateway/adapters/telegram.js +34 -11
- package/dist/gateway/adapters/telegram.js.map +1 -1
- package/dist/gateway/agent-bridge.d.ts +14 -3
- package/dist/gateway/agent-bridge.d.ts.map +1 -1
- package/dist/gateway/agent-bridge.js +252 -60
- package/dist/gateway/agent-bridge.js.map +1 -1
- package/dist/gateway/approval.d.ts +1 -0
- package/dist/gateway/approval.d.ts.map +1 -1
- package/dist/gateway/approval.js +60 -18
- package/dist/gateway/approval.js.map +1 -1
- package/dist/gateway/authz.d.ts +2 -0
- package/dist/gateway/authz.d.ts.map +1 -1
- package/dist/gateway/authz.js +13 -0
- package/dist/gateway/authz.js.map +1 -1
- package/dist/gateway/buttons.d.ts +3 -1
- package/dist/gateway/buttons.d.ts.map +1 -1
- package/dist/gateway/buttons.js +18 -3
- package/dist/gateway/buttons.js.map +1 -1
- package/dist/gateway/command.d.ts.map +1 -1
- package/dist/gateway/command.js +49 -4
- package/dist/gateway/command.js.map +1 -1
- package/dist/gateway/commands.d.ts.map +1 -1
- package/dist/gateway/commands.js +18 -3
- package/dist/gateway/commands.js.map +1 -1
- package/dist/gateway/config.d.ts +5 -0
- package/dist/gateway/config.d.ts.map +1 -1
- package/dist/gateway/config.js +5 -0
- package/dist/gateway/config.js.map +1 -1
- package/dist/gateway/conversations.d.ts +14 -0
- package/dist/gateway/conversations.d.ts.map +1 -0
- package/dist/gateway/conversations.js +30 -0
- package/dist/gateway/conversations.js.map +1 -0
- package/dist/gateway/download.d.ts +2 -0
- package/dist/gateway/download.d.ts.map +1 -0
- package/dist/gateway/download.js +36 -0
- package/dist/gateway/download.js.map +1 -0
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +85 -26
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/mobile-commands.d.ts +24 -0
- package/dist/gateway/mobile-commands.d.ts.map +1 -0
- package/dist/gateway/mobile-commands.js +422 -0
- package/dist/gateway/mobile-commands.js.map +1 -0
- package/dist/gateway/presenter.d.ts +16 -0
- package/dist/gateway/presenter.d.ts.map +1 -0
- package/dist/gateway/presenter.js +210 -0
- package/dist/gateway/presenter.js.map +1 -0
- package/dist/gateway/router.d.ts +1 -0
- package/dist/gateway/router.d.ts.map +1 -1
- package/dist/gateway/router.js +32 -3
- package/dist/gateway/router.js.map +1 -1
- package/dist/gateway/service.d.ts +46 -0
- package/dist/gateway/service.d.ts.map +1 -0
- package/dist/gateway/service.js +395 -0
- package/dist/gateway/service.js.map +1 -0
- package/dist/gateway/setup.d.ts +4 -0
- package/dist/gateway/setup.d.ts.map +1 -0
- package/dist/gateway/setup.js +146 -0
- package/dist/gateway/setup.js.map +1 -0
- package/dist/gateway/types.d.ts +4 -2
- package/dist/gateway/types.d.ts.map +1 -1
- package/dist/gateway/types.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +19 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +78 -17
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/copyable-text.d.ts +27 -0
- package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/copyable-text.js +156 -0
- package/dist/modes/interactive/components/copyable-text.js.map +1 -0
- package/dist/modes/interactive/components/custom-entry.d.ts +1 -0
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +8 -0
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +8 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +16 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +51 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-tail.d.ts +9 -2
- package/dist/modes/interactive/components/thinking-tail.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-tail.js +43 -1
- package/dist/modes/interactive/components/thinking-tail.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +4 -3
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +34 -45
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +9 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +267 -44
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +23 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/node-runtime/agent-session-services-GZVSOGYR.js +49 -0
- package/dist/node-runtime/{builtin-extensions-JCOPAAB5.js → builtin-extensions-QVCXNQT4.js} +6 -5
- package/dist/node-runtime/{chunk-LTYWTR3V.js → chunk-2MI5OPMN.js} +17 -2
- package/dist/node-runtime/{chunk-W3CVH5RX.js → chunk-2TKODGBZ.js} +11 -6
- package/dist/node-runtime/chunk-4EULYYR4.js +62 -0
- package/dist/node-runtime/{chunk-6N22HULO.js → chunk-5D7LC2ZQ.js} +7 -2
- package/dist/node-runtime/{chunk-KBKMCJDU.js → chunk-5ZQXRPMC.js} +19 -4
- package/dist/node-runtime/{chunk-BOHIDQT4.js → chunk-6VYZ5UFP.js} +1 -1
- package/dist/node-runtime/chunk-AZJHNQKQ.js +205 -0
- package/dist/node-runtime/{chunk-A3KMVBZV.js → chunk-BBUVIEZB.js} +1 -10
- package/dist/node-runtime/{chunk-IRPJXI6U.js → chunk-BX2RB477.js} +1 -1
- package/dist/node-runtime/chunk-CCCN2UCX.js +14 -0
- package/dist/node-runtime/{chunk-25I2BHAA.js → chunk-CSUZVNYE.js} +1 -1
- package/dist/node-runtime/chunk-DD5YWFSJ.js +708 -0
- package/dist/node-runtime/chunk-DQMGU675.js +3409 -0
- package/dist/node-runtime/{chunk-QZMODZQ2.js → chunk-E24EO34J.js} +2 -1
- package/dist/node-runtime/chunk-EKVFP6YF.js +355 -0
- package/dist/node-runtime/chunk-GJ2RDBRL.js +672 -0
- package/dist/node-runtime/{chunk-W3SILANP.js → chunk-GMHJCCEN.js} +8 -8
- package/dist/node-runtime/{chunk-DDWHZ633.js → chunk-GS42T6MX.js} +1 -1
- package/dist/node-runtime/chunk-GS66LV4M.js +2830 -0
- package/dist/node-runtime/chunk-H4K3JDRB.js +47 -0
- package/dist/node-runtime/{chunk-2SJB2AWP.js → chunk-HMBGROQK.js} +3 -3
- package/dist/node-runtime/{chunk-GB2MGFLI.js → chunk-HPUP7E4T.js} +216 -201
- package/dist/node-runtime/{chunk-YMEAYRBE.js → chunk-HTFRRDSF.js} +2 -7
- package/dist/node-runtime/{chunk-OPEK5RRY.js → chunk-IF24A3FH.js} +1 -1
- package/dist/node-runtime/chunk-IMLCWLPI.js +9 -0
- package/dist/node-runtime/chunk-KKUTQQV7.js +144 -0
- package/dist/node-runtime/chunk-LFZDVKSP.js +521 -0
- package/dist/node-runtime/{chunk-2BUAYZ7K.js → chunk-LLUIPGDR.js} +581 -197
- package/dist/node-runtime/{chunk-7NBZ5P7I.js → chunk-NAY6UUQZ.js} +1 -1
- package/dist/node-runtime/chunk-OAR4TYZE.js +146 -0
- package/dist/node-runtime/{chunk-STERBGUB.js → chunk-OFKSVRV7.js} +2 -2
- package/dist/node-runtime/{chunk-JZQ7F36T.js → chunk-PCEW76PM.js} +19 -3
- package/dist/node-runtime/{chunk-WLLDXJRT.js → chunk-QAZOULTU.js} +29 -1014
- package/dist/node-runtime/{chunk-6KDIOJL3.js → chunk-QH6YL7VK.js} +3 -3
- package/dist/node-runtime/chunk-R3K2F5GI.js +122 -0
- package/dist/node-runtime/{chunk-RNBHABBA.js → chunk-RDDAZOMU.js} +23 -0
- package/dist/node-runtime/{chunk-SY2TFMLO.js → chunk-RIR5EDDJ.js} +46 -151
- package/dist/node-runtime/chunk-RMQZU2YU.js +117 -0
- package/dist/node-runtime/{chunk-6BEIBLQ3.js → chunk-RWTKOC3B.js} +1 -1
- package/dist/node-runtime/{chunk-G6LRAP36.js → chunk-TQGPP4SC.js} +1 -1
- package/dist/node-runtime/{chunk-Y5KOEMBH.js → chunk-TVJUOJZJ.js} +9 -674
- package/dist/node-runtime/chunk-UAEOTO52.js +119 -0
- package/dist/node-runtime/{chunk-AY6CAJSL.js → chunk-UJOCPOMX.js} +6 -3
- package/dist/node-runtime/chunk-UP2XBVH5.js +40 -0
- package/dist/node-runtime/{chunk-WJVFOIB5.js → chunk-UQUCFAJ3.js} +1 -1
- package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
- package/dist/node-runtime/chunk-US544NN6.js +13 -0
- package/dist/node-runtime/chunk-UWPJL22I.js +341 -0
- package/dist/node-runtime/{chunk-4I23VTC4.js → chunk-VWCE2HSZ.js} +21 -124
- package/dist/node-runtime/{chunk-VZR3NCM7.js → chunk-W64JC4E7.js} +18 -14
- package/dist/node-runtime/{chunk-AWVD5IEY.js → chunk-X3URCYCU.js} +23 -12
- package/dist/node-runtime/{chunk-GKLEQ3I4.js → chunk-XLTL257W.js} +126 -27
- package/dist/node-runtime/{chunk-WKDK4C5P.js → chunk-YDO2F2IA.js} +38 -164
- package/dist/node-runtime/{chunk-PDNXVXMD.js → chunk-YHQ3NBB3.js} +58 -48
- package/dist/node-runtime/chunk-YPHAIRZT.js +10 -0
- package/dist/node-runtime/cli-runtime.js +2 -2
- package/dist/node-runtime/command-PDVTBRWA.js +45 -0
- package/dist/node-runtime/{commands-MV5KOZ64.js → commands-KAMO2T6P.js} +10 -10
- package/dist/node-runtime/commands-XDCFGIGW.js +36 -0
- package/dist/node-runtime/config-RORQUQFG.js +20 -0
- package/dist/node-runtime/{customize-LF5VST47.js → customize-VFJV3U6A.js} +2 -1
- package/dist/node-runtime/{direct-tool-executor-BK7CLEBX.js → direct-tool-executor-YAVOLDFY.js} +8 -8
- package/dist/node-runtime/{export-html-TEXVV5RP.js → export-html-KSOIMVPI.js} +4 -3
- package/dist/node-runtime/{extension-input-O4HSAEM4.js → extension-input-E7BJZ35H.js} +4 -4
- package/dist/node-runtime/{extension-selector-X5FCX43D.js → extension-selector-WU42XDTU.js} +4 -4
- package/dist/node-runtime/{extract-XLQSJN4V.js → extract-EQJE7FZZ.js} +2 -2
- package/dist/node-runtime/{gateway-BM6NLOH4.js → gateway-AYWM5DIO.js} +275 -994
- package/dist/node-runtime/{gemini-search-U7SUMPQA.js → gemini-search-35OCRFLN.js} +1 -1
- package/dist/node-runtime/{gemini-url-context-PXWCBQHK.js → gemini-url-context-UQY3PHHW.js} +2 -2
- package/dist/node-runtime/index.js +104 -65
- package/dist/node-runtime/{init-3C7Z24OI.js → init-X2LIUB2H.js} +3 -3
- package/dist/node-runtime/{install-cli-EXMJQESX.js → install-cli-3BO4MMQ6.js} +21 -82
- package/dist/node-runtime/interactive-mode-4MFRKAHG.js +72 -0
- package/dist/node-runtime/{interactive-view-ILS6TAN5.js → interactive-view-TUZHCQM3.js} +8 -8
- package/dist/node-runtime/lunr-browser-RYFIIVJN.js +174 -0
- package/dist/node-runtime/{lunr-cron-4VHP4E4B.js → lunr-cron-YWXEPZMQ.js} +19 -5
- package/dist/node-runtime/main.js +44 -31
- package/dist/node-runtime/{memory-cap-3S4XRLNP.js → memory-cap-EL3KL4JJ.js} +2 -1
- package/dist/node-runtime/mobile-commands-LVHDAUDP.js +32 -0
- package/dist/node-runtime/model-runtime-PLQKAG4B.js +16 -0
- package/dist/node-runtime/{model-tiers-NJLHUEGK.js → model-tiers-OU3U5CZG.js} +2 -1
- package/dist/node-runtime/{package-manager-cli-N37546V5.js → package-manager-cli-6GT3Z3CK.js} +22 -15
- package/dist/node-runtime/{pi-intercom-NV2LW6X7.js → pi-intercom-HBPK5HSJ.js} +4 -1
- package/dist/node-runtime/{pi-mcp-adapter-GUFZWW54.js → pi-mcp-adapter-E6WULBKF.js} +4 -4
- package/dist/node-runtime/{pi-subagents-6MUIFNDM.js → pi-subagents-CDWK2AKY.js} +236 -79
- package/dist/node-runtime/{pi-web-access-2CQGFLT2.js → pi-web-access-WTGMNZ32.js} +15 -15
- package/dist/node-runtime/process-registry-4FAKZQOL.js +31 -0
- package/dist/node-runtime/{proxy-modes-V6YVFH3C.js → proxy-modes-OSQCWRBI.js} +9 -9
- package/dist/node-runtime/rpc-entry.js +44 -31
- package/dist/node-runtime/{rpc-mode-W5ZTLTMZ.js → rpc-mode-O3XV4SID.js} +2 -2
- package/dist/node-runtime/runtime-4VA6JKNF.js +373 -0
- package/dist/node-runtime/{runtime-bridges-2VQTLPOZ.js → runtime-bridges-3XUQ46XW.js} +6 -5
- package/dist/node-runtime/service-ISSP6VHE.js +36 -0
- package/dist/node-runtime/session-handoff-HC7R5E24.js +33 -0
- package/dist/node-runtime/{session-manager-E7AREDTV.js → session-manager-CFN4UFM2.js} +2 -1
- package/dist/node-runtime/{session-selector-FJ7M2AIX.js → session-selector-GIM4DHQ2.js} +5 -4
- package/dist/node-runtime/{settings-manager-CUGAZWAB.js → settings-manager-6VEMXRDL.js} +7 -2
- package/dist/node-runtime/setup-5SR2J35A.js +155 -0
- package/dist/node-runtime/setup-JBKOLJ6F.js +18 -0
- package/dist/node-runtime/{subagent-executor-MH4A7CCF.js → subagent-executor-M5VWB3D3.js} +26 -18
- package/dist/node-runtime/theme-UOO5RVFN.js +68 -0
- package/dist/node-runtime/trust-manager-MMISNCYO.js +17 -0
- package/dist/node-runtime/{update-cli-XTZMZGOL.js → update-cli-UVKJWRRJ.js} +7 -2
- package/dist/node-runtime/usage-service-LFB2SWYV.js +37 -0
- package/dist/node-runtime/{video-extract-OYT5WKS5.js → video-extract-OOZHR7SU.js} +2 -2
- package/dist/node-runtime/{youtube-extract-TQYKGFGS.js → youtube-extract-FNPAUNHU.js} +6 -6
- package/docs/browser.md +86 -0
- package/docs/extensions.md +2 -0
- package/docs/features.md +96 -16
- package/docs/interactive-startup.md +2 -1
- package/docs/sessions.md +10 -0
- package/docs/settings.md +2 -0
- package/docs/tui.md +2 -0
- package/docs/usage.md +16 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +7 -4
- package/scripts/install-browser.mjs +20 -0
- package/dist/node-runtime/agent-session-services-C743TYQE.js +0 -37
- package/dist/node-runtime/chunk-VGYZ3APQ.js +0 -59
- package/dist/node-runtime/chunk-XI77KVKA.js +0 -6009
- package/dist/node-runtime/command-P4NYCJ2M.js +0 -13
- package/dist/node-runtime/interactive-mode-EVVBA64D.js +0 -59
- package/dist/node-runtime/{chunk-UWQYRSYQ.js → chunk-YJMMG7C6.js} +25 -25
- package/dist/node-runtime/{mcp-panel-IIGMXQGP.js → mcp-panel-KTTFXJZ4.js} +3 -3
- package/dist/node-runtime/{src-BPQFJR76.js → src-IVPNZ2BX.js} +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
lunR is derived from pi. The published npm package is **`@ashx-j/lunr@0.2.
|
|
3
|
+
lunR is derived from pi. The published npm package is **`@ashx-j/lunr@0.2.23`**. Versioned sections below (`0.80.x` and earlier) are **upstream pi history** and do not describe lunR releases.
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [0.2.23] - 2026-09-21
|
|
6
|
+
|
|
7
|
+
## [0.2.22] - 2026-09-20
|
|
6
8
|
|
|
7
9
|
## [0.2.21] - 2026-09-13
|
|
8
10
|
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Extend it with TypeScript [Extensions](#extensions), [Skills](#skills), [Prompt
|
|
|
17
17
|
- [Providers & Models](#providers--models)
|
|
18
18
|
- [Interactive Mode](#interactive-mode)
|
|
19
19
|
- [Editor](#editor)
|
|
20
|
+
- [Copyable response blocks](#copyable-response-blocks)
|
|
20
21
|
- [Commands](#commands)
|
|
21
22
|
- [Keyboard Shortcuts](#keyboard-shortcuts)
|
|
22
23
|
- [Message Queue](#message-queue)
|
|
@@ -45,7 +46,7 @@ Requires **Node.js ≥ 22.19**.
|
|
|
45
46
|
npm i -g @ashx-j/lunr
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
`--ignore-scripts`
|
|
49
|
+
Normal installation also installs matching Chromium for the built-in [browser](docs/browser.md). Turn Browser off in `/settings` if you do not want its tool. `--ignore-scripts` and offline installs skip Chromium; the rest of lunR remains usable, and `lunr browser install` repairs missing binaries later.
|
|
49
50
|
|
|
50
51
|
Then run it in a project directory:
|
|
51
52
|
|
|
@@ -68,7 +69,7 @@ lunr
|
|
|
68
69
|
/login # Then select provider
|
|
69
70
|
```
|
|
70
71
|
|
|
71
|
-
First-run optional
|
|
72
|
+
First-run setup installs Chromium and offers the optional Telegram/Discord gateway:
|
|
72
73
|
|
|
73
74
|
```bash
|
|
74
75
|
lunr setup
|
|
@@ -148,6 +149,20 @@ The editor can be temporarily replaced by other UI, like built-in `/settings` or
|
|
|
148
149
|
|
|
149
150
|
Standard editing keybindings for delete word, undo, etc. See [docs/keybindings.md](docs/keybindings.md).
|
|
150
151
|
|
|
152
|
+
### Copyable response blocks
|
|
153
|
+
|
|
154
|
+
Assistant responses can mark a reusable excerpt, prompt, or code fragment as click-to-copy. The marked section appears in a plain background box. Click anywhere in that box to copy only its contents.
|
|
155
|
+
|
|
156
|
+
The source format is a fenced Markdown block with the exact info string `lunr-copy`:
|
|
157
|
+
|
|
158
|
+
````markdown
|
|
159
|
+
```lunr-copy
|
|
160
|
+
npm test
|
|
161
|
+
```
|
|
162
|
+
````
|
|
163
|
+
|
|
164
|
+
The payload starts after the opening fence's line break and ends before the line break immediately preceding the closing fence. lunR copies it without trimming whitespace and excludes both fence lines. A longer backtick or tilde fence can contain shorter fenced code. Incomplete streamed blocks remain readable but become clickable only after the closing fence arrives. Print, JSON, RPC, and gateway output keep the raw fences and never write to the clipboard.
|
|
165
|
+
|
|
151
166
|
### Commands
|
|
152
167
|
|
|
153
168
|
Type `/` in the editor to trigger commands. [Extensions](#extensions) can register custom commands, [skills](#skills) are available as `/skill:name`, and [prompt templates](#prompt-templates) expand via `/templatename`.
|
|
@@ -219,13 +234,15 @@ Click a thinking or tool card to expand or collapse that item. `app.tools.expand
|
|
|
219
234
|
|
|
220
235
|
Submit messages while the agent is working:
|
|
221
236
|
|
|
222
|
-
- **Enter** queues a *steering* message, delivered after the current assistant turn finishes executing its tool calls
|
|
237
|
+
- **Enter** queues a *steering* message, delivered after the current assistant turn finishes executing its tool calls. If the parent is executing `subagent_wait`, Enter instead ends only that wait. The current tool batch settles, background children keep running, and the text starts a fresh parent turn without appearing in the steering queue.
|
|
223
238
|
- **Alt+Enter** queues a *follow-up* message, delivered only after the agent finishes all work
|
|
224
239
|
- **Escape** aborts and restores queued messages to editor
|
|
225
240
|
- **Alt+Up** retrieves queued messages back to editor
|
|
226
241
|
|
|
227
242
|
On Windows Terminal, `Alt+Enter` is fullscreen by default. Remap it in [docs/terminal-setup.md](docs/terminal-setup.md) so lunR can receive the follow-up shortcut.
|
|
228
243
|
|
|
244
|
+
Parallel tools beside `subagent_wait` finish before the fresh Enter prompt starts. Alt+Enter and Enter outside an executing wait keep their normal queue behavior.
|
|
245
|
+
|
|
229
246
|
Configure delivery in [settings](docs/settings.md): `steeringMode` and `followUpMode` can be `"one-at-a-time"` (default, waits for response) or `"all"` (delivers all queued at once). `transport` selects provider transport preference (`"sse"`, `"websocket"`, or `"auto"`) for providers that support multiple transports.
|
|
230
247
|
|
|
231
248
|
---
|
|
@@ -471,7 +488,7 @@ lunR keeps a small core and still lets you shape the product with [extensions](#
|
|
|
471
488
|
- **Subagents** — always fresh; children use a configured tier by default, or an explicit model when the user names one; 3+ children receive one large-launch confirmation in manual and yolo; default parallel concurrency is unlimited
|
|
472
489
|
- **Permission modes** — `manual | yolo | plan | auto`; Shift+Tab cycles that order
|
|
473
490
|
- **Plan mode** — `/plan` plus the `present_plan` tool
|
|
474
|
-
- **Todos** — lunr-todos
|
|
491
|
+
- **Todos** — lunr-todos is a full-replace list and can be disabled in `/settings`
|
|
475
492
|
- **Background processes** — `/processes`
|
|
476
493
|
- **Cron** — `/cron`, `~/.lunr/agent/cron/` (TUI live session or gateway origin)
|
|
477
494
|
- **Gateway** — `lunr gateway` for Telegram and Discord
|
|
@@ -490,7 +507,8 @@ lunr [options] [@files...] [messages...]
|
|
|
490
507
|
### Product Commands
|
|
491
508
|
|
|
492
509
|
```bash
|
|
493
|
-
lunr setup #
|
|
510
|
+
lunr setup # Install Chromium and configure optional features
|
|
511
|
+
lunr browser install # Repair missing Chromium after a skipped/failed install
|
|
494
512
|
lunr features [list|enable|disable]
|
|
495
513
|
lunr gateway […] # Chat gateway daemon (requires chat-platforms feature)
|
|
496
514
|
lunr uninstall [--purge] # Remove this lunR install (keeps ~/.lunr/agent unless --purge)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAuBrF,yFAAyF;AACzF,eAAO,MAAM,sBAAsB,EAAE,eAAe,EAUnD,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAuBrF,yFAAyF;AACzF,eAAO,MAAM,sBAAsB,EAAE,eAAe,EAUnD,CAAC;AAkBF,eAAO,MAAM,gCAAgC,UAAsD,CAAC;AAEpG,6FAA6F;AAC7F,eAAO,MAAM,sBAAsB,yBAA0B,CAAC;AAE9D,6EAA6E;AAC7E,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAQhF;AAED,yFAAyF;AACzF,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAE3E;AAED,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,EAAE,eAAe,EAA2B,CAAC","sourcesContent":["/**\n * Built-in extensions for lunR.\n *\n * Light factories stay on the first-paint graph. Heavy factories are imported\n * only when attachDeferredBuiltinExtensions() runs after the TUI is up, or\n * immediately for print/RPC/gateway where there is no first-paint window.\n */\n\nimport type { ExtensionFactory, InlineExtension } from \"../core/extensions/types.ts\";\nimport { measureStartup } from \"../core/timings.ts\";\n\nimport simplePiMemory from \"./simple-pi-memory.ts\";\nimport piTps from \"./pi-tps.ts\";\nimport ashxjTui from \"./ashxj-tui.ts\";\nimport ashxjSpinners from \"./ashxj-spinners.ts\";\nimport ashxjThinking from \"./ashxj-thinking.ts\";\nimport lunrLocalProviders from \"./lunr-local-providers/index.ts\";\nimport lunrTodos from \"./lunr-todos.ts\";\nimport lunrPlanTools from \"./lunr-plan-tools.ts\";\nimport lunrSkillCreator from \"./lunr-skill-creator/index.ts\";\n\n/**\n * Wrap a raw factory function as a named InlineExtension.\n * The cast bridges the gap between the source-level ExtensionFactory type\n * (used here) and the dist-level type that extensions import via the package\n * name. The underlying function signatures are structurally identical.\n */\nfunction ext(name: string, factory: unknown): InlineExtension {\n\treturn { name, factory: factory as ExtensionFactory };\n}\n\n/** UI, local providers, and small lunR-native factories. Safe to import at CLI start. */\nexport const lightBuiltinExtensions: InlineExtension[] = [\n\text(\"simple-pi-memory\", simplePiMemory),\n\text(\"pi-tps\", piTps),\n\text(\"ashxj-tui\", ashxjTui),\n\text(\"ashxj-spinners\", ashxjSpinners),\n\text(\"ashxj-thinking\", ashxjThinking),\n\text(\"lunr-local-providers\", lunrLocalProviders),\n\text(\"lunr-todos\", lunrTodos),\n\text(\"lunr-plan-tools\", lunrPlanTools),\n\text(\"lunr-skill-creator\", lunrSkillCreator),\n];\n\nconst DEFERRED_BUILTIN_LOADERS: Array<{\n\tname: string;\n\tload: () => Promise<{ default: unknown }>;\n}> = [\n\t{ name: \"pi-ollama-cloud\", load: () => import(\"./pi-ollama-cloud/index.ts\") },\n\t{ name: \"narumiruna-pi-goal\", load: () => import(\"./narumiruna-pi-goal/src/goal.ts\") },\n\t{ name: \"lunr-cron\", load: () => import(\"./lunr-cron.ts\") },\n\t{ name: \"pi-intercom\", load: () => import(\"./pi-intercom/index.ts\") },\n\t{ name: \"pi-prompt-template-model\", load: () => import(\"./pi-prompt-template-model/index.ts\") },\n\t{ name: \"pi-subagents\", load: () => import(\"./pi-subagents/index.ts\") },\n\t{ name: \"pi-web-access\", load: () => import(\"./pi-web-access/index.ts\") },\n\t{ name: \"lunr-browser\", load: () => import(\"./lunr-browser.ts\") },\n\t{ name: \"pi-lsp-extension\", load: () => import(\"./pi-lsp-extension/src/index.ts\") },\n\t{ name: \"pi-mcp-adapter\", load: () => import(\"./pi-mcp-adapter/index.ts\") },\n];\n\nexport const DEFERRED_BUILTIN_EXTENSION_NAMES = DEFERRED_BUILTIN_LOADERS.map((entry) => entry.name);\n\n/** Flags registered only after deferred builtins attach. Do not fail CLI parse for these. */\nexport const DEFERRED_BUILTIN_FLAGS = [\"mcp-config\"] as const;\n\n/** Import MCP / LSP / web-access / intercom / subagents only when needed. */\nexport async function loadDeferredBuiltinExtensions(): Promise<InlineExtension[]> {\n\tconst loaded = await Promise.all(\n\t\tDEFERRED_BUILTIN_LOADERS.map(async ({ name, load }) => {\n\t\t\tconst module = await measureStartup(name, load, \"imports\");\n\t\t\treturn ext(name, module.default);\n\t\t}),\n\t);\n\treturn loaded;\n}\n\n/** Full roster. Print / RPC / gateway still need every factory before the first turn. */\nexport async function loadAllBuiltinExtensions(): Promise<InlineExtension[]> {\n\treturn [...lightBuiltinExtensions, ...(await loadDeferredBuiltinExtensions())];\n}\n\n/** Eager full roster. Prefer loadAllBuiltinExtensions() so CLI start stays light. */\nexport const builtinExtensions: InlineExtension[] = lightBuiltinExtensions;\n"]}
|
|
@@ -44,6 +44,7 @@ const DEFERRED_BUILTIN_LOADERS = [
|
|
|
44
44
|
{ name: "pi-prompt-template-model", load: () => import("./pi-prompt-template-model/index.js") },
|
|
45
45
|
{ name: "pi-subagents", load: () => import("./pi-subagents/index.js") },
|
|
46
46
|
{ name: "pi-web-access", load: () => import("./pi-web-access/index.js") },
|
|
47
|
+
{ name: "lunr-browser", load: () => import("./lunr-browser.js") },
|
|
47
48
|
{ name: "pi-lsp-extension", load: () => import("./pi-lsp-extension/src/index.js") },
|
|
48
49
|
{ name: "pi-mcp-adapter", load: () => import("./pi-mcp-adapter/index.js") },
|
|
49
50
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builtin-extensions/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Built-in extensions for lunR.\n *\n * Light factories stay on the first-paint graph. Heavy factories are imported\n * only when attachDeferredBuiltinExtensions() runs after the TUI is up, or\n * immediately for print/RPC/gateway where there is no first-paint window.\n */\n\nimport type { ExtensionFactory, InlineExtension } from \"../core/extensions/types.ts\";\nimport { measureStartup } from \"../core/timings.ts\";\n\nimport simplePiMemory from \"./simple-pi-memory.ts\";\nimport piTps from \"./pi-tps.ts\";\nimport ashxjTui from \"./ashxj-tui.ts\";\nimport ashxjSpinners from \"./ashxj-spinners.ts\";\nimport ashxjThinking from \"./ashxj-thinking.ts\";\nimport lunrLocalProviders from \"./lunr-local-providers/index.ts\";\nimport lunrTodos from \"./lunr-todos.ts\";\nimport lunrPlanTools from \"./lunr-plan-tools.ts\";\nimport lunrSkillCreator from \"./lunr-skill-creator/index.ts\";\n\n/**\n * Wrap a raw factory function as a named InlineExtension.\n * The cast bridges the gap between the source-level ExtensionFactory type\n * (used here) and the dist-level type that extensions import via the package\n * name. The underlying function signatures are structurally identical.\n */\nfunction ext(name: string, factory: unknown): InlineExtension {\n\treturn { name, factory: factory as ExtensionFactory };\n}\n\n/** UI, local providers, and small lunR-native factories. Safe to import at CLI start. */\nexport const lightBuiltinExtensions: InlineExtension[] = [\n\text(\"simple-pi-memory\", simplePiMemory),\n\text(\"pi-tps\", piTps),\n\text(\"ashxj-tui\", ashxjTui),\n\text(\"ashxj-spinners\", ashxjSpinners),\n\text(\"ashxj-thinking\", ashxjThinking),\n\text(\"lunr-local-providers\", lunrLocalProviders),\n\text(\"lunr-todos\", lunrTodos),\n\text(\"lunr-plan-tools\", lunrPlanTools),\n\text(\"lunr-skill-creator\", lunrSkillCreator),\n];\n\nconst DEFERRED_BUILTIN_LOADERS: Array<{\n\tname: string;\n\tload: () => Promise<{ default: unknown }>;\n}> = [\n\t{ name: \"pi-ollama-cloud\", load: () => import(\"./pi-ollama-cloud/index.ts\") },\n\t{ name: \"narumiruna-pi-goal\", load: () => import(\"./narumiruna-pi-goal/src/goal.ts\") },\n\t{ name: \"lunr-cron\", load: () => import(\"./lunr-cron.ts\") },\n\t{ name: \"pi-intercom\", load: () => import(\"./pi-intercom/index.ts\") },\n\t{ name: \"pi-prompt-template-model\", load: () => import(\"./pi-prompt-template-model/index.ts\") },\n\t{ name: \"pi-subagents\", load: () => import(\"./pi-subagents/index.ts\") },\n\t{ name: \"pi-web-access\", load: () => import(\"./pi-web-access/index.ts\") },\n\t{ name: \"pi-lsp-extension\", load: () => import(\"./pi-lsp-extension/src/index.ts\") },\n\t{ name: \"pi-mcp-adapter\", load: () => import(\"./pi-mcp-adapter/index.ts\") },\n];\n\nexport const DEFERRED_BUILTIN_EXTENSION_NAMES = DEFERRED_BUILTIN_LOADERS.map((entry) => entry.name);\n\n/** Flags registered only after deferred builtins attach. Do not fail CLI parse for these. */\nexport const DEFERRED_BUILTIN_FLAGS = [\"mcp-config\"] as const;\n\n/** Import MCP / LSP / web-access / intercom / subagents only when needed. */\nexport async function loadDeferredBuiltinExtensions(): Promise<InlineExtension[]> {\n\tconst loaded = await Promise.all(\n\t\tDEFERRED_BUILTIN_LOADERS.map(async ({ name, load }) => {\n\t\t\tconst module = await measureStartup(name, load, \"imports\");\n\t\t\treturn ext(name, module.default);\n\t\t}),\n\t);\n\treturn loaded;\n}\n\n/** Full roster. Print / RPC / gateway still need every factory before the first turn. */\nexport async function loadAllBuiltinExtensions(): Promise<InlineExtension[]> {\n\treturn [...lightBuiltinExtensions, ...(await loadDeferredBuiltinExtensions())];\n}\n\n/** Eager full roster. Prefer loadAllBuiltinExtensions() so CLI start stays light. */\nexport const builtinExtensions: InlineExtension[] = lightBuiltinExtensions;\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builtin-extensions/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Built-in extensions for lunR.\n *\n * Light factories stay on the first-paint graph. Heavy factories are imported\n * only when attachDeferredBuiltinExtensions() runs after the TUI is up, or\n * immediately for print/RPC/gateway where there is no first-paint window.\n */\n\nimport type { ExtensionFactory, InlineExtension } from \"../core/extensions/types.ts\";\nimport { measureStartup } from \"../core/timings.ts\";\n\nimport simplePiMemory from \"./simple-pi-memory.ts\";\nimport piTps from \"./pi-tps.ts\";\nimport ashxjTui from \"./ashxj-tui.ts\";\nimport ashxjSpinners from \"./ashxj-spinners.ts\";\nimport ashxjThinking from \"./ashxj-thinking.ts\";\nimport lunrLocalProviders from \"./lunr-local-providers/index.ts\";\nimport lunrTodos from \"./lunr-todos.ts\";\nimport lunrPlanTools from \"./lunr-plan-tools.ts\";\nimport lunrSkillCreator from \"./lunr-skill-creator/index.ts\";\n\n/**\n * Wrap a raw factory function as a named InlineExtension.\n * The cast bridges the gap between the source-level ExtensionFactory type\n * (used here) and the dist-level type that extensions import via the package\n * name. The underlying function signatures are structurally identical.\n */\nfunction ext(name: string, factory: unknown): InlineExtension {\n\treturn { name, factory: factory as ExtensionFactory };\n}\n\n/** UI, local providers, and small lunR-native factories. Safe to import at CLI start. */\nexport const lightBuiltinExtensions: InlineExtension[] = [\n\text(\"simple-pi-memory\", simplePiMemory),\n\text(\"pi-tps\", piTps),\n\text(\"ashxj-tui\", ashxjTui),\n\text(\"ashxj-spinners\", ashxjSpinners),\n\text(\"ashxj-thinking\", ashxjThinking),\n\text(\"lunr-local-providers\", lunrLocalProviders),\n\text(\"lunr-todos\", lunrTodos),\n\text(\"lunr-plan-tools\", lunrPlanTools),\n\text(\"lunr-skill-creator\", lunrSkillCreator),\n];\n\nconst DEFERRED_BUILTIN_LOADERS: Array<{\n\tname: string;\n\tload: () => Promise<{ default: unknown }>;\n}> = [\n\t{ name: \"pi-ollama-cloud\", load: () => import(\"./pi-ollama-cloud/index.ts\") },\n\t{ name: \"narumiruna-pi-goal\", load: () => import(\"./narumiruna-pi-goal/src/goal.ts\") },\n\t{ name: \"lunr-cron\", load: () => import(\"./lunr-cron.ts\") },\n\t{ name: \"pi-intercom\", load: () => import(\"./pi-intercom/index.ts\") },\n\t{ name: \"pi-prompt-template-model\", load: () => import(\"./pi-prompt-template-model/index.ts\") },\n\t{ name: \"pi-subagents\", load: () => import(\"./pi-subagents/index.ts\") },\n\t{ name: \"pi-web-access\", load: () => import(\"./pi-web-access/index.ts\") },\n\t{ name: \"lunr-browser\", load: () => import(\"./lunr-browser.ts\") },\n\t{ name: \"pi-lsp-extension\", load: () => import(\"./pi-lsp-extension/src/index.ts\") },\n\t{ name: \"pi-mcp-adapter\", load: () => import(\"./pi-mcp-adapter/index.ts\") },\n];\n\nexport const DEFERRED_BUILTIN_EXTENSION_NAMES = DEFERRED_BUILTIN_LOADERS.map((entry) => entry.name);\n\n/** Flags registered only after deferred builtins attach. Do not fail CLI parse for these. */\nexport const DEFERRED_BUILTIN_FLAGS = [\"mcp-config\"] as const;\n\n/** Import MCP / LSP / web-access / intercom / subagents only when needed. */\nexport async function loadDeferredBuiltinExtensions(): Promise<InlineExtension[]> {\n\tconst loaded = await Promise.all(\n\t\tDEFERRED_BUILTIN_LOADERS.map(async ({ name, load }) => {\n\t\t\tconst module = await measureStartup(name, load, \"imports\");\n\t\t\treturn ext(name, module.default);\n\t\t}),\n\t);\n\treturn loaded;\n}\n\n/** Full roster. Print / RPC / gateway still need every factory before the first turn. */\nexport async function loadAllBuiltinExtensions(): Promise<InlineExtension[]> {\n\treturn [...lightBuiltinExtensions, ...(await loadDeferredBuiltinExtensions())];\n}\n\n/** Eager full roster. Prefer loadAllBuiltinExtensions() so CLI start stays light. */\nexport const builtinExtensions: InlineExtension[] = lightBuiltinExtensions;\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Text } from "@ashx-j/lunr-tui";
|
|
2
|
+
import type { ExtensionAPI, ToolRenderContext } from "../core/extensions/types.ts";
|
|
3
|
+
import { type BrowserInput } from "../core/browser/schema.ts";
|
|
4
|
+
import type { Theme } from "../modes/interactive/theme/theme.ts";
|
|
5
|
+
export type BrowserActivityState = "pending" | "success" | "error";
|
|
6
|
+
export declare function describeBrowserActivity(input: BrowserInput, state: BrowserActivityState): string;
|
|
7
|
+
export declare function renderBrowserActivity(args: BrowserInput, theme: Theme, context: ToolRenderContext<unknown, BrowserInput>): Text;
|
|
8
|
+
export default function browserExtension(pi: ExtensionAPI): void;
|
|
9
|
+
//# sourceMappingURL=lunr-browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lunr-browser.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGnF,OAAO,EAAuB,KAAK,YAAY,EAAiB,MAAM,2BAA2B,CAAC;AAElG,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAIjE,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAMnE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAsDhG;AAoDD,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,CAAC,OAAO,EAAE,YAAY,CAAC,GAC/C,IAAI,CAcN;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA8C/D","sourcesContent":["import { Text } from \"@ashx-j/lunr-tui\";\nimport type { ExtensionAPI, ToolRenderContext } from \"../core/extensions/types.ts\";\nimport { toolStatusDotFromContext } from \"../core/tools/render-utils.ts\";\nimport { onBrowserEnabledChange, readBrowserSettings } from \"../core/browser/settings.ts\";\nimport { BROWSER_DESCRIPTION, type BrowserInput, BrowserParams } from \"../core/browser/schema.ts\";\nimport type { BrowserSession } from \"../core/browser/runtime.ts\";\nimport type { Theme } from \"../modes/interactive/theme/theme.ts\";\n\nconst BROWSER_ACTIVITY_TICK_MS = 18;\n\nexport type BrowserActivityState = \"pending\" | \"success\" | \"error\";\n\nfunction browserTarget(input: BrowserInput): string {\n\treturn input.label || input.name || input.role || \"an element\";\n}\n\nexport function describeBrowserActivity(input: BrowserInput, state: BrowserActivityState): string {\n\tconst failed = state === \"error\";\n\tconst pending = state === \"pending\";\n\tif (input.action === \"navigate\") {\n\t\tconst url = input.url || \"the page\";\n\t\treturn failed ? `Failed to open ${url}` : pending ? `Opening ${url}` : `Opened ${url}`;\n\t}\n\tif (input.action === \"inspect\") {\n\t\treturn failed ? \"Failed to inspect the page\" : pending ? \"Inspecting the page\" : \"Inspected the page\";\n\t}\n\tif (input.action === \"screenshot\") {\n\t\treturn failed ? \"Failed to capture a screenshot\" : pending ? \"Capturing a screenshot\" : \"Captured a screenshot\";\n\t}\n\tif (input.action === \"close\") {\n\t\treturn failed ? \"Failed to close the browser\" : pending ? \"Closing the browser\" : \"Closed the browser\";\n\t}\n\tif (input.action === \"tabs\") {\n\t\tif (input.operation === \"create\") {\n\t\t\tconst destination = input.url ? ` at ${input.url}` : \"\";\n\t\t\treturn failed\n\t\t\t\t? `Failed to open a new tab${destination}`\n\t\t\t\t: pending\n\t\t\t\t\t? `Opening a new tab${destination}`\n\t\t\t\t\t: `Opened a new tab${destination}`;\n\t\t}\n\t\tif (input.operation === \"select\") {\n\t\t\tconst tab = input.tab ? ` ${input.tab}` : \"\";\n\t\t\treturn failed ? `Failed to select tab${tab}` : pending ? `Selecting tab${tab}` : `Selected tab${tab}`;\n\t\t}\n\t\tif (input.operation === \"close\") {\n\t\t\tconst tab = input.tab ? ` ${input.tab}` : \"\";\n\t\t\treturn failed ? `Failed to close tab${tab}` : pending ? `Closing tab${tab}` : `Closed tab${tab}`;\n\t\t}\n\t\treturn failed ? \"Failed to list browser tabs\" : pending ? \"Listing browser tabs\" : \"Listed browser tabs\";\n\t}\n\n\tconst target = browserTarget(input);\n\tif (input.interaction === \"fill\") {\n\t\treturn failed ? `Failed to fill ${target}` : pending ? `Filling ${target}` : `Filled ${target}`;\n\t}\n\tif (input.interaction === \"select\") {\n\t\treturn failed ? `Failed to select an option in ${target}` : pending ? `Selecting an option in ${target}` : `Selected an option in ${target}`;\n\t}\n\tif (input.interaction === \"check\") {\n\t\tconst verb = input.checked === false ? \"uncheck\" : \"check\";\n\t\tconst active = input.checked === false ? \"Unchecking\" : \"Checking\";\n\t\tconst done = input.checked === false ? \"Unchecked\" : \"Checked\";\n\t\treturn failed ? `Failed to ${verb} ${target}` : pending ? `${active} ${target}` : `${done} ${target}`;\n\t}\n\tif (input.interaction === \"press\") {\n\t\tconst key = input.value || \"a key\";\n\t\treturn failed ? `Failed to press ${key} on ${target}` : pending ? `Pressing ${key} on ${target}` : `Pressed ${key} on ${target}`;\n\t}\n\treturn failed ? `Failed to click ${target}` : pending ? `Clicking ${target}` : `Clicked ${target}`;\n}\n\nclass BrowserActivityText extends Text {\n\tprivate activity = \"\";\n\tprivate visibleLength = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate format: (text: string) => string = (text) => text;\n\tprivate requestRender: () => void = () => {};\n\n\tconstructor() {\n\t\tsuper(\"\", 0, 0);\n\t}\n\n\tsetActivity(activity: string, format: (text: string) => string, animate: boolean, requestRender?: () => void): void {\n\t\tthis.format = format;\n\t\tthis.requestRender = requestRender ?? (() => {});\n\t\tif (activity === this.activity) {\n\t\t\tthis.paint();\n\t\t\treturn;\n\t\t}\n\t\tthis.stop();\n\t\tthis.activity = activity;\n\t\tthis.visibleLength = animate ? Math.min(1, Array.from(activity).length) : Array.from(activity).length;\n\t\tthis.paint();\n\t\tif (animate && this.visibleLength < Array.from(activity).length) this.schedule();\n\t}\n\n\tdispose(): void {\n\t\tthis.stop();\n\t}\n\n\tprivate schedule(): void {\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.timer = undefined;\n\t\t\tthis.visibleLength++;\n\t\t\tthis.paint();\n\t\t\tthis.requestRender();\n\t\t\tif (this.visibleLength < Array.from(this.activity).length) this.schedule();\n\t\t}, BROWSER_ACTIVITY_TICK_MS);\n\t\tthis.timer.unref?.();\n\t}\n\n\tprivate paint(): void {\n\t\tthis.setText(this.format(Array.from(this.activity).slice(0, this.visibleLength).join(\"\")));\n\t}\n\n\tprivate stop(): void {\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t}\n}\n\nexport function renderBrowserActivity(\n\targs: BrowserInput,\n\ttheme: Theme,\n\tcontext: ToolRenderContext<unknown, BrowserInput>,\n): Text {\n\tconst component = context.lastComponent instanceof BrowserActivityText\n\t\t? context.lastComponent\n\t\t: new BrowserActivityText();\n\tconst state: BrowserActivityState = context.isPartial ? \"pending\" : context.isError ? \"error\" : \"success\";\n\tconst activity = describeBrowserActivity(args, state);\n\tconst animate = context.executionStarted || context.result === undefined;\n\tcomponent.setActivity(\n\t\tactivity,\n\t\t(text) => `${toolStatusDotFromContext(context, theme)} ${theme.fg(state === \"error\" ? \"error\" : \"toolTitle\", text)}`,\n\t\tanimate,\n\t\tcontext.requestRender,\n\t);\n\treturn component;\n}\n\nexport default function browserExtension(pi: ExtensionAPI): void {\n\tlet enabled = readBrowserSettings().enabled;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet session: BrowserSession | undefined;\n\tlet generation = 0;\n\tconst close = async () => {\n\t\tgeneration++;\n\t\tconst previous = session;\n\t\tsession = undefined;\n\t\tawait previous?.close();\n\t};\n\tpi.on(\"session_shutdown\", async () => {\n\t\tunsubscribe?.();\n\t\tunsubscribe = undefined;\n\t\tawait close();\n\t});\n\tpi.on(\"session_start\", async () => {\n\t\tawait close();\n\t\tenabled = readBrowserSettings().enabled;\n\t\tunsubscribe?.();\n\t\tunsubscribe = onBrowserEnabledChange((value) => {\n\t\t\tenabled = value;\n\t\t\tif (!enabled) void close().catch(() => undefined);\n\t\t});\n\t});\n\tpi.on(\"agent_end\", async (event) => {\n\t\tif (event.messages.some((message) => message.role === \"assistant\" && message.stopReason === \"aborted\")) await close();\n\t});\n\tpi.registerTool({\n\t\tname: \"browser\",\n\t\tlabel: \"Browser\",\n\t\tdescription: BROWSER_DESCRIPTION,\n\t\tparameters: BrowserParams,\n\t\tasync execute(_id, input, signal) {\n\t\t\tif (!enabled) {\n\t\t\t\tawait close();\n\t\t\t\tthrow new Error(\"Browser is disabled. The user can enable Browser in /settings.\");\n\t\t\t}\n\t\t\tconst current = generation;\n\t\t\tconst { BrowserSession } = await import(\"../core/browser/runtime.ts\");\n\t\t\tif (current !== generation || signal?.aborted) throw new Error(\"Browser call cancelled during initialization.\");\n\t\t\tsession ??= new BrowserSession(readBrowserSettings().allowPrivate);\n\t\t\treturn session.run(input, signal);\n\t\t},\n\t\trenderCall: renderBrowserActivity,\n\t});\n}\n"]}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { Text } from "@ashx-j/lunr-tui";
|
|
2
|
+
import { toolStatusDotFromContext } from "../core/tools/render-utils.js";
|
|
3
|
+
import { onBrowserEnabledChange, readBrowserSettings } from "../core/browser/settings.js";
|
|
4
|
+
import { BROWSER_DESCRIPTION, BrowserParams } from "../core/browser/schema.js";
|
|
5
|
+
const BROWSER_ACTIVITY_TICK_MS = 18;
|
|
6
|
+
function browserTarget(input) {
|
|
7
|
+
return input.label || input.name || input.role || "an element";
|
|
8
|
+
}
|
|
9
|
+
export function describeBrowserActivity(input, state) {
|
|
10
|
+
const failed = state === "error";
|
|
11
|
+
const pending = state === "pending";
|
|
12
|
+
if (input.action === "navigate") {
|
|
13
|
+
const url = input.url || "the page";
|
|
14
|
+
return failed ? `Failed to open ${url}` : pending ? `Opening ${url}` : `Opened ${url}`;
|
|
15
|
+
}
|
|
16
|
+
if (input.action === "inspect") {
|
|
17
|
+
return failed ? "Failed to inspect the page" : pending ? "Inspecting the page" : "Inspected the page";
|
|
18
|
+
}
|
|
19
|
+
if (input.action === "screenshot") {
|
|
20
|
+
return failed ? "Failed to capture a screenshot" : pending ? "Capturing a screenshot" : "Captured a screenshot";
|
|
21
|
+
}
|
|
22
|
+
if (input.action === "close") {
|
|
23
|
+
return failed ? "Failed to close the browser" : pending ? "Closing the browser" : "Closed the browser";
|
|
24
|
+
}
|
|
25
|
+
if (input.action === "tabs") {
|
|
26
|
+
if (input.operation === "create") {
|
|
27
|
+
const destination = input.url ? ` at ${input.url}` : "";
|
|
28
|
+
return failed
|
|
29
|
+
? `Failed to open a new tab${destination}`
|
|
30
|
+
: pending
|
|
31
|
+
? `Opening a new tab${destination}`
|
|
32
|
+
: `Opened a new tab${destination}`;
|
|
33
|
+
}
|
|
34
|
+
if (input.operation === "select") {
|
|
35
|
+
const tab = input.tab ? ` ${input.tab}` : "";
|
|
36
|
+
return failed ? `Failed to select tab${tab}` : pending ? `Selecting tab${tab}` : `Selected tab${tab}`;
|
|
37
|
+
}
|
|
38
|
+
if (input.operation === "close") {
|
|
39
|
+
const tab = input.tab ? ` ${input.tab}` : "";
|
|
40
|
+
return failed ? `Failed to close tab${tab}` : pending ? `Closing tab${tab}` : `Closed tab${tab}`;
|
|
41
|
+
}
|
|
42
|
+
return failed ? "Failed to list browser tabs" : pending ? "Listing browser tabs" : "Listed browser tabs";
|
|
43
|
+
}
|
|
44
|
+
const target = browserTarget(input);
|
|
45
|
+
if (input.interaction === "fill") {
|
|
46
|
+
return failed ? `Failed to fill ${target}` : pending ? `Filling ${target}` : `Filled ${target}`;
|
|
47
|
+
}
|
|
48
|
+
if (input.interaction === "select") {
|
|
49
|
+
return failed ? `Failed to select an option in ${target}` : pending ? `Selecting an option in ${target}` : `Selected an option in ${target}`;
|
|
50
|
+
}
|
|
51
|
+
if (input.interaction === "check") {
|
|
52
|
+
const verb = input.checked === false ? "uncheck" : "check";
|
|
53
|
+
const active = input.checked === false ? "Unchecking" : "Checking";
|
|
54
|
+
const done = input.checked === false ? "Unchecked" : "Checked";
|
|
55
|
+
return failed ? `Failed to ${verb} ${target}` : pending ? `${active} ${target}` : `${done} ${target}`;
|
|
56
|
+
}
|
|
57
|
+
if (input.interaction === "press") {
|
|
58
|
+
const key = input.value || "a key";
|
|
59
|
+
return failed ? `Failed to press ${key} on ${target}` : pending ? `Pressing ${key} on ${target}` : `Pressed ${key} on ${target}`;
|
|
60
|
+
}
|
|
61
|
+
return failed ? `Failed to click ${target}` : pending ? `Clicking ${target}` : `Clicked ${target}`;
|
|
62
|
+
}
|
|
63
|
+
class BrowserActivityText extends Text {
|
|
64
|
+
activity = "";
|
|
65
|
+
visibleLength = 0;
|
|
66
|
+
timer;
|
|
67
|
+
format = (text) => text;
|
|
68
|
+
requestRender = () => { };
|
|
69
|
+
constructor() {
|
|
70
|
+
super("", 0, 0);
|
|
71
|
+
}
|
|
72
|
+
setActivity(activity, format, animate, requestRender) {
|
|
73
|
+
this.format = format;
|
|
74
|
+
this.requestRender = requestRender ?? (() => { });
|
|
75
|
+
if (activity === this.activity) {
|
|
76
|
+
this.paint();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.stop();
|
|
80
|
+
this.activity = activity;
|
|
81
|
+
this.visibleLength = animate ? Math.min(1, Array.from(activity).length) : Array.from(activity).length;
|
|
82
|
+
this.paint();
|
|
83
|
+
if (animate && this.visibleLength < Array.from(activity).length)
|
|
84
|
+
this.schedule();
|
|
85
|
+
}
|
|
86
|
+
dispose() {
|
|
87
|
+
this.stop();
|
|
88
|
+
}
|
|
89
|
+
schedule() {
|
|
90
|
+
this.timer = setTimeout(() => {
|
|
91
|
+
this.timer = undefined;
|
|
92
|
+
this.visibleLength++;
|
|
93
|
+
this.paint();
|
|
94
|
+
this.requestRender();
|
|
95
|
+
if (this.visibleLength < Array.from(this.activity).length)
|
|
96
|
+
this.schedule();
|
|
97
|
+
}, BROWSER_ACTIVITY_TICK_MS);
|
|
98
|
+
this.timer.unref?.();
|
|
99
|
+
}
|
|
100
|
+
paint() {
|
|
101
|
+
this.setText(this.format(Array.from(this.activity).slice(0, this.visibleLength).join("")));
|
|
102
|
+
}
|
|
103
|
+
stop() {
|
|
104
|
+
if (this.timer)
|
|
105
|
+
clearTimeout(this.timer);
|
|
106
|
+
this.timer = undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function renderBrowserActivity(args, theme, context) {
|
|
110
|
+
const component = context.lastComponent instanceof BrowserActivityText
|
|
111
|
+
? context.lastComponent
|
|
112
|
+
: new BrowserActivityText();
|
|
113
|
+
const state = context.isPartial ? "pending" : context.isError ? "error" : "success";
|
|
114
|
+
const activity = describeBrowserActivity(args, state);
|
|
115
|
+
const animate = context.executionStarted || context.result === undefined;
|
|
116
|
+
component.setActivity(activity, (text) => `${toolStatusDotFromContext(context, theme)} ${theme.fg(state === "error" ? "error" : "toolTitle", text)}`, animate, context.requestRender);
|
|
117
|
+
return component;
|
|
118
|
+
}
|
|
119
|
+
export default function browserExtension(pi) {
|
|
120
|
+
let enabled = readBrowserSettings().enabled;
|
|
121
|
+
let unsubscribe;
|
|
122
|
+
let session;
|
|
123
|
+
let generation = 0;
|
|
124
|
+
const close = async () => {
|
|
125
|
+
generation++;
|
|
126
|
+
const previous = session;
|
|
127
|
+
session = undefined;
|
|
128
|
+
await previous?.close();
|
|
129
|
+
};
|
|
130
|
+
pi.on("session_shutdown", async () => {
|
|
131
|
+
unsubscribe?.();
|
|
132
|
+
unsubscribe = undefined;
|
|
133
|
+
await close();
|
|
134
|
+
});
|
|
135
|
+
pi.on("session_start", async () => {
|
|
136
|
+
await close();
|
|
137
|
+
enabled = readBrowserSettings().enabled;
|
|
138
|
+
unsubscribe?.();
|
|
139
|
+
unsubscribe = onBrowserEnabledChange((value) => {
|
|
140
|
+
enabled = value;
|
|
141
|
+
if (!enabled)
|
|
142
|
+
void close().catch(() => undefined);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
pi.on("agent_end", async (event) => {
|
|
146
|
+
if (event.messages.some((message) => message.role === "assistant" && message.stopReason === "aborted"))
|
|
147
|
+
await close();
|
|
148
|
+
});
|
|
149
|
+
pi.registerTool({
|
|
150
|
+
name: "browser",
|
|
151
|
+
label: "Browser",
|
|
152
|
+
description: BROWSER_DESCRIPTION,
|
|
153
|
+
parameters: BrowserParams,
|
|
154
|
+
async execute(_id, input, signal) {
|
|
155
|
+
if (!enabled) {
|
|
156
|
+
await close();
|
|
157
|
+
throw new Error("Browser is disabled. The user can enable Browser in /settings.");
|
|
158
|
+
}
|
|
159
|
+
const current = generation;
|
|
160
|
+
const { BrowserSession } = await import("../core/browser/runtime.js");
|
|
161
|
+
if (current !== generation || signal?.aborted)
|
|
162
|
+
throw new Error("Browser call cancelled during initialization.");
|
|
163
|
+
session ??= new BrowserSession(readBrowserSettings().allowPrivate);
|
|
164
|
+
return session.run(input, signal);
|
|
165
|
+
},
|
|
166
|
+
renderCall: renderBrowserActivity,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=lunr-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lunr-browser.js","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-browser.ts"],"names":[],"mappings":"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","sourcesContent":["import { Text } from \"@ashx-j/lunr-tui\";\nimport type { ExtensionAPI, ToolRenderContext } from \"../core/extensions/types.ts\";\nimport { toolStatusDotFromContext } from \"../core/tools/render-utils.ts\";\nimport { onBrowserEnabledChange, readBrowserSettings } from \"../core/browser/settings.ts\";\nimport { BROWSER_DESCRIPTION, type BrowserInput, BrowserParams } from \"../core/browser/schema.ts\";\nimport type { BrowserSession } from \"../core/browser/runtime.ts\";\nimport type { Theme } from \"../modes/interactive/theme/theme.ts\";\n\nconst BROWSER_ACTIVITY_TICK_MS = 18;\n\nexport type BrowserActivityState = \"pending\" | \"success\" | \"error\";\n\nfunction browserTarget(input: BrowserInput): string {\n\treturn input.label || input.name || input.role || \"an element\";\n}\n\nexport function describeBrowserActivity(input: BrowserInput, state: BrowserActivityState): string {\n\tconst failed = state === \"error\";\n\tconst pending = state === \"pending\";\n\tif (input.action === \"navigate\") {\n\t\tconst url = input.url || \"the page\";\n\t\treturn failed ? `Failed to open ${url}` : pending ? `Opening ${url}` : `Opened ${url}`;\n\t}\n\tif (input.action === \"inspect\") {\n\t\treturn failed ? \"Failed to inspect the page\" : pending ? \"Inspecting the page\" : \"Inspected the page\";\n\t}\n\tif (input.action === \"screenshot\") {\n\t\treturn failed ? \"Failed to capture a screenshot\" : pending ? \"Capturing a screenshot\" : \"Captured a screenshot\";\n\t}\n\tif (input.action === \"close\") {\n\t\treturn failed ? \"Failed to close the browser\" : pending ? \"Closing the browser\" : \"Closed the browser\";\n\t}\n\tif (input.action === \"tabs\") {\n\t\tif (input.operation === \"create\") {\n\t\t\tconst destination = input.url ? ` at ${input.url}` : \"\";\n\t\t\treturn failed\n\t\t\t\t? `Failed to open a new tab${destination}`\n\t\t\t\t: pending\n\t\t\t\t\t? `Opening a new tab${destination}`\n\t\t\t\t\t: `Opened a new tab${destination}`;\n\t\t}\n\t\tif (input.operation === \"select\") {\n\t\t\tconst tab = input.tab ? ` ${input.tab}` : \"\";\n\t\t\treturn failed ? `Failed to select tab${tab}` : pending ? `Selecting tab${tab}` : `Selected tab${tab}`;\n\t\t}\n\t\tif (input.operation === \"close\") {\n\t\t\tconst tab = input.tab ? ` ${input.tab}` : \"\";\n\t\t\treturn failed ? `Failed to close tab${tab}` : pending ? `Closing tab${tab}` : `Closed tab${tab}`;\n\t\t}\n\t\treturn failed ? \"Failed to list browser tabs\" : pending ? \"Listing browser tabs\" : \"Listed browser tabs\";\n\t}\n\n\tconst target = browserTarget(input);\n\tif (input.interaction === \"fill\") {\n\t\treturn failed ? `Failed to fill ${target}` : pending ? `Filling ${target}` : `Filled ${target}`;\n\t}\n\tif (input.interaction === \"select\") {\n\t\treturn failed ? `Failed to select an option in ${target}` : pending ? `Selecting an option in ${target}` : `Selected an option in ${target}`;\n\t}\n\tif (input.interaction === \"check\") {\n\t\tconst verb = input.checked === false ? \"uncheck\" : \"check\";\n\t\tconst active = input.checked === false ? \"Unchecking\" : \"Checking\";\n\t\tconst done = input.checked === false ? \"Unchecked\" : \"Checked\";\n\t\treturn failed ? `Failed to ${verb} ${target}` : pending ? `${active} ${target}` : `${done} ${target}`;\n\t}\n\tif (input.interaction === \"press\") {\n\t\tconst key = input.value || \"a key\";\n\t\treturn failed ? `Failed to press ${key} on ${target}` : pending ? `Pressing ${key} on ${target}` : `Pressed ${key} on ${target}`;\n\t}\n\treturn failed ? `Failed to click ${target}` : pending ? `Clicking ${target}` : `Clicked ${target}`;\n}\n\nclass BrowserActivityText extends Text {\n\tprivate activity = \"\";\n\tprivate visibleLength = 0;\n\tprivate timer?: ReturnType<typeof setTimeout>;\n\tprivate format: (text: string) => string = (text) => text;\n\tprivate requestRender: () => void = () => {};\n\n\tconstructor() {\n\t\tsuper(\"\", 0, 0);\n\t}\n\n\tsetActivity(activity: string, format: (text: string) => string, animate: boolean, requestRender?: () => void): void {\n\t\tthis.format = format;\n\t\tthis.requestRender = requestRender ?? (() => {});\n\t\tif (activity === this.activity) {\n\t\t\tthis.paint();\n\t\t\treturn;\n\t\t}\n\t\tthis.stop();\n\t\tthis.activity = activity;\n\t\tthis.visibleLength = animate ? Math.min(1, Array.from(activity).length) : Array.from(activity).length;\n\t\tthis.paint();\n\t\tif (animate && this.visibleLength < Array.from(activity).length) this.schedule();\n\t}\n\n\tdispose(): void {\n\t\tthis.stop();\n\t}\n\n\tprivate schedule(): void {\n\t\tthis.timer = setTimeout(() => {\n\t\t\tthis.timer = undefined;\n\t\t\tthis.visibleLength++;\n\t\t\tthis.paint();\n\t\t\tthis.requestRender();\n\t\t\tif (this.visibleLength < Array.from(this.activity).length) this.schedule();\n\t\t}, BROWSER_ACTIVITY_TICK_MS);\n\t\tthis.timer.unref?.();\n\t}\n\n\tprivate paint(): void {\n\t\tthis.setText(this.format(Array.from(this.activity).slice(0, this.visibleLength).join(\"\")));\n\t}\n\n\tprivate stop(): void {\n\t\tif (this.timer) clearTimeout(this.timer);\n\t\tthis.timer = undefined;\n\t}\n}\n\nexport function renderBrowserActivity(\n\targs: BrowserInput,\n\ttheme: Theme,\n\tcontext: ToolRenderContext<unknown, BrowserInput>,\n): Text {\n\tconst component = context.lastComponent instanceof BrowserActivityText\n\t\t? context.lastComponent\n\t\t: new BrowserActivityText();\n\tconst state: BrowserActivityState = context.isPartial ? \"pending\" : context.isError ? \"error\" : \"success\";\n\tconst activity = describeBrowserActivity(args, state);\n\tconst animate = context.executionStarted || context.result === undefined;\n\tcomponent.setActivity(\n\t\tactivity,\n\t\t(text) => `${toolStatusDotFromContext(context, theme)} ${theme.fg(state === \"error\" ? \"error\" : \"toolTitle\", text)}`,\n\t\tanimate,\n\t\tcontext.requestRender,\n\t);\n\treturn component;\n}\n\nexport default function browserExtension(pi: ExtensionAPI): void {\n\tlet enabled = readBrowserSettings().enabled;\n\tlet unsubscribe: (() => void) | undefined;\n\tlet session: BrowserSession | undefined;\n\tlet generation = 0;\n\tconst close = async () => {\n\t\tgeneration++;\n\t\tconst previous = session;\n\t\tsession = undefined;\n\t\tawait previous?.close();\n\t};\n\tpi.on(\"session_shutdown\", async () => {\n\t\tunsubscribe?.();\n\t\tunsubscribe = undefined;\n\t\tawait close();\n\t});\n\tpi.on(\"session_start\", async () => {\n\t\tawait close();\n\t\tenabled = readBrowserSettings().enabled;\n\t\tunsubscribe?.();\n\t\tunsubscribe = onBrowserEnabledChange((value) => {\n\t\t\tenabled = value;\n\t\t\tif (!enabled) void close().catch(() => undefined);\n\t\t});\n\t});\n\tpi.on(\"agent_end\", async (event) => {\n\t\tif (event.messages.some((message) => message.role === \"assistant\" && message.stopReason === \"aborted\")) await close();\n\t});\n\tpi.registerTool({\n\t\tname: \"browser\",\n\t\tlabel: \"Browser\",\n\t\tdescription: BROWSER_DESCRIPTION,\n\t\tparameters: BrowserParams,\n\t\tasync execute(_id, input, signal) {\n\t\t\tif (!enabled) {\n\t\t\t\tawait close();\n\t\t\t\tthrow new Error(\"Browser is disabled. The user can enable Browser in /settings.\");\n\t\t\t}\n\t\t\tconst current = generation;\n\t\t\tconst { BrowserSession } = await import(\"../core/browser/runtime.ts\");\n\t\t\tif (current !== generation || signal?.aborted) throw new Error(\"Browser call cancelled during initialization.\");\n\t\t\tsession ??= new BrowserSession(readBrowserSettings().allowPrivate);\n\t\t\treturn session.run(input, signal);\n\t\t},\n\t\trenderCall: renderBrowserActivity,\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lunr-todos.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-todos.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAStF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAClC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAQ5C,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAWxD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,SAAU,GAAG,cAAc,EAAE,CAsBhH;AASD,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CA8H/C","sourcesContent":["// @ts-nocheck\n/**\n * lunr-todos — lunR-native agent todo list with an above-editor widget.\n *\n * lunR: this file is lunR-native (not an absorbed upstream extension).\n *\n * - One `todo` tool (TypeBox), full-replace semantics: every call sends the\n * ENTIRE list; an empty array clears it. State is per-session, in-memory\n * only (extension closure) — nothing is persisted.\n * - Chat render is a quiet one-liner (renderCall/renderResult), matching the\n * cron tool's minimal footprint.\n * - After every state change the list is mirrored into a `todos` widget above\n * the editor (component factory, so MAX_WIDGET_LINES string truncation does\n * not apply). Collapsed: four active items fit in full; lists of five or\n * more show three rows (in-progress first, then pending). Completed items\n * never appear collapsed. `+N more` still\n * applies to hidden active rows. Expanded: every row, completed included\n * until the next user turn prunes them.\n * - Click the widget to expand/collapse.\n *\n * The pure logic (summarizeTodos / buildTodoWidgetLines) is exported for\n * vitest — see test/lunr-todos.test.ts.\n *\n * `// @ts-nocheck` matches the builtin-extension convention (see lunr-cron).\n * Runtime imports stay on concrete core modules — never the package barrel.\n */\n\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { Text } from \"@ashx-j/lunr-tui\";\nimport { Type } from \"@sinclair/typebox\";\nimport { keyText } from \"../modes/interactive/components/keybinding-hints.ts\";\n\n// ---------------------------------------------------------------------------\n// Pure logic (exported for tests)\n// ---------------------------------------------------------------------------\n\nexport type TodoStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface TodoItem {\n\tid: string;\n\tcontent: string;\n\tstatus: TodoStatus;\n}\n\nexport interface TodoWidgetLine {\n\tkind: \"todo\" | \"summary\" | \"hint\";\n\tstatus?: TodoStatus;\n\ttext: string;\n}\n\n/** Collapsed widgets with five or more active items show this many rows. */\nexport const TODO_WIDGET_COLLAPSED_ROWS = 3;\n\nconst STATUS_GLYPHS: Record<TodoStatus, string> = {\n\tin_progress: \"●\",\n\tpending: \"○\",\n\tcompleted: \"✓\",\n};\n\n/** Short model-facing summary, e.g. \"4 todos: 1 in progress, 2 pending, 1 completed\". */\nexport function summarizeTodos(todos: TodoItem[]): string {\n\tif (todos.length === 0) return \"No todos.\";\n\tconst count = (s: TodoStatus) => todos.filter((t) => t.status === s).length;\n\tconst parts: string[] = [];\n\tconst inProgress = count(\"in_progress\");\n\tconst pending = count(\"pending\");\n\tconst completed = count(\"completed\");\n\tif (inProgress > 0) parts.push(`${inProgress} in progress`);\n\tif (pending > 0) parts.push(`${pending} pending`);\n\tif (completed > 0) parts.push(`${completed} completed`);\n\treturn `${todos.length} todo${todos.length === 1 ? \"\" : \"s\"}: ${parts.join(\", \")}`;\n}\n\n/**\n * Widget lines for the current list. Collapsed mode shows all four active rows,\n * or TODO_WIDGET_COLLAPSED_ROWS when there are five or more (in-progress first, then pending),\n * and never emits a `✓ N done` summary. A `+N more (<expandKey> to expand)`\n * hint is appended when active rows are hidden. Expanded mode shows every\n * row, completed included. Empty list / all-completed collapsed → no lines.\n */\nexport function buildTodoWidgetLines(todos: TodoItem[], expanded: boolean, expandKey = \"click\"): TodoWidgetLine[] {\n\tif (todos.length === 0) return [];\n\tconst row = (t: TodoItem): TodoWidgetLine => ({\n\t\tkind: \"todo\",\n\t\tstatus: t.status,\n\t\ttext: `${STATUS_GLYPHS[t.status]} ${t.content}`,\n\t});\n\tconst active = [\n\t\t...todos.filter((t) => t.status === \"in_progress\"),\n\t\t...todos.filter((t) => t.status === \"pending\"),\n\t];\n\tconst done = todos.filter((t) => t.status === \"completed\");\n\tif (expanded) {\n\t\treturn [...active.map(row), ...done.map(row)];\n\t}\n\tconst visibleRows = active.length === 4 ? 4 : TODO_WIDGET_COLLAPSED_ROWS;\n\tconst lines: TodoWidgetLine[] = active.slice(0, visibleRows).map(row);\n\tconst hidden = active.length - visibleRows;\n\tif (hidden > 0) {\n\t\tlines.push({ kind: \"hint\", text: `+${hidden} more` });\n\t}\n\treturn lines;\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\n\nconst WIDGET_KEY = \"todos\";\nconst EXPANDED_BRIDGE_SYMBOL = Symbol.for(\"@lunr/tools-expanded-changed\");\n\nexport default function (pi: ExtensionAPI): void {\n\tlet todos: TodoItem[] = [];\n\tlet expanded = false;\n\tlet lastCtx: ExtensionContext | null = null;\n\n\tfunction colorize(line: TodoWidgetLine, theme: any): string {\n\t\tif (line.kind === \"summary\" || line.kind === \"hint\") return theme.fg(\"muted\", line.text);\n\t\tif (line.status === \"in_progress\") return theme.fg(\"accent\", line.text);\n\t\tif (line.status === \"completed\") return theme.fg(\"dim\", line.text);\n\t\treturn line.text;\n\t}\n\n\tfunction refreshWidget(): void {\n\t\tconst ctx = lastCtx;\n\t\tif (!ctx?.hasUI) return;\n\t\tconst lines = buildTodoWidgetLines(todos, expanded, keyText(\"app.tools.expand\"));\n\t\tif (todos.length === 0 || lines.length === 0) {\n\t\t\tctx.ui.setWidget(WIDGET_KEY, undefined);\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.setWidget(\n\t\t\tWIDGET_KEY,\n\t\t\t(_tui: unknown, theme: any) => {\n\t\t\t\tconst text = new Text(lines.map((l) => colorize(l, theme)).join(\"\\n\"), 1, 0);\n\t\t\t\treturn {\n\t\t\t\t\trender: (width: number) => text.render(width),\n\t\t\t\t\tinvalidate: () => text.invalidate?.(),\n\t\t\t\t\thandleClick: () => {\n\t\t\t\t\t\texpanded = !expanded;\n\t\t\t\t\t\trefreshWidget();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ placement: \"aboveEditor\" },\n\t\t);\n\t}\n\n\tfunction pruneCompleted(): void {\n\t\tconst next = todos.filter((t) => t.status !== \"completed\");\n\t\tif (next.length === todos.length) return;\n\t\ttodos = next;\n\t\trefreshWidget();\n\t}\n\n\t// --- Expansion bridge (interactive-mode setToolsExpanded invokes this) ---\n\tfunction registerExpandedBridge(): void {\n\t\t(globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL] = (value: boolean) => {\n\t\t\texpanded = Boolean(value);\n\t\t\trefreshWidget();\n\t\t};\n\t}\n\tregisterExpandedBridge();\n\n\t// --- Session lifecycle: per-session in-memory state ---\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tlastCtx = ctx;\n\t\ttodos = [];\n\t\texpanded = ctx.hasUI ? (ctx.ui.getToolsExpanded?.() ?? false) : false;\n\t\tregisterExpandedBridge();\n\t\tif (ctx.hasUI) ctx.ui.setWidget(WIDGET_KEY, undefined);\n\t});\n\n\t// lunr: prune completed items on the next real user message, not slash\n\t// commands or agent follow-up turns.\n\tpi.on(\"message_start\", (event, ctx) => {\n\t\tif (event.message?.role !== \"user\") return;\n\t\tlastCtx = ctx;\n\t\tpruneCompleted();\n\t});\n\n\tpi.on(\"session_shutdown\", () => {\n\t\tif (lastCtx?.hasUI) lastCtx.ui.setWidget(WIDGET_KEY, undefined);\n\t\tlastCtx = null;\n\t\tdelete (globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL];\n\t});\n\n\t// --- todo tool (agent-facing) ---\n\tpi.registerTool({\n\t\tname: \"todo\",\n\t\tlabel: \"Todo\",\n\t\tdescription: [\n\t\t\t\"Manage the session todo list shown above the user's editor. Full-replace semantics:\",\n\t\t\t\"every call must send the ENTIRE list; send an empty array to clear it.\",\n\t\t\t\"Each item: { id, content, status: 'pending' | 'in_progress' | 'completed' }.\",\n\t\t\t\"Use it to track multi-step work; keep exactly one item in_progress at a time.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\ttodos: Type.Array(\n\t\t\t\tType.Object({\n\t\t\t\t\tid: Type.String({ description: \"Stable id for the item.\" }),\n\t\t\t\t\tcontent: Type.String({ description: \"Short description of the task.\" }),\n\t\t\t\t\tstatus: Type.Union([\n\t\t\t\t\t\tType.Literal(\"pending\"),\n\t\t\t\t\t\tType.Literal(\"in_progress\"),\n\t\t\t\t\t\tType.Literal(\"completed\"),\n\t\t\t\t\t]),\n\t\t\t\t}),\n\t\t\t),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst text = (t: string) => ({ content: [{ type: \"text\" as const, text: t }] });\n\t\t\tconst incoming = Array.isArray(params?.todos) ? params.todos : [];\n\t\t\ttodos = incoming\n\t\t\t\t.filter((t: any) => t && typeof t.content === \"string\" && t.content.trim().length > 0)\n\t\t\t\t.map((t: any, i: number) => ({\n\t\t\t\t\tid: typeof t.id === \"string\" && t.id ? t.id : String(i + 1),\n\t\t\t\t\tcontent: t.content.trim(),\n\t\t\t\t\tstatus: t.status === \"in_progress\" || t.status === \"completed\" ? t.status : \"pending\",\n\t\t\t\t}));\n\t\t\tlastCtx = ctx;\n\t\t\trefreshWidget();\n\t\t\treturn text(summarizeTodos(todos));\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\tconst n = Array.isArray(args?.todos) ? args.todos.length : 0;\n\t\t\tconst detail = n === 0 ? \"clear\" : `${n} item${n === 1 ? \"\" : \"s\"}`;\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(\"todo \")) + theme.fg(\"dim\", detail), 0, 0);\n\t\t},\n\t\trenderResult(result, { isPartial }, theme) {\n\t\t\tif (isPartial) return new Text(theme.fg(\"warning\", \"Updating todos...\"), 0, 0);\n\t\t\tconst first = result?.content?.[0];\n\t\t\tconst summary = first?.type === \"text\" ? first.text : \"\";\n\t\t\treturn new Text(theme.fg(\"dim\", summary), 0, 0);\n\t\t},\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lunr-todos.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-todos.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAatF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IAClC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAQ5C,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAWxD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,SAAU,GAAG,cAAc,EAAE,CAsBhH;AASD,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,GAAG,IAAI,CA6I/C","sourcesContent":["// @ts-nocheck\n/**\n * lunr-todos — lunR-native agent todo list with an above-editor widget.\n *\n * lunR: this file is lunR-native (not an absorbed upstream extension).\n *\n * - One `todo` tool (TypeBox), full-replace semantics: every call sends the\n * ENTIRE list; an empty array clears it. State is per-session, in-memory\n * only (extension closure) — nothing is persisted.\n * - Chat render is a quiet one-liner (renderCall/renderResult), matching the\n * cron tool's minimal footprint.\n * - After every state change the list is mirrored into a `todos` widget above\n * the editor (component factory, so MAX_WIDGET_LINES string truncation does\n * not apply). Collapsed: four active items fit in full; lists of five or\n * more show three rows (in-progress first, then pending). Completed items\n * never appear collapsed. `+N more` still\n * applies to hidden active rows. Expanded: every row, completed included\n * until the next user turn prunes them.\n * - Click the widget to expand/collapse.\n *\n * The pure logic (summarizeTodos / buildTodoWidgetLines) is exported for\n * vitest — see test/lunr-todos.test.ts.\n *\n * `// @ts-nocheck` matches the builtin-extension convention (see lunr-cron).\n * Runtime imports stay on concrete core modules — never the package barrel.\n */\n\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { Text } from \"@ashx-j/lunr-tui\";\nimport { Type } from \"@sinclair/typebox\";\nimport {\n\tTODOS_ENABLED_CHANGED_SYMBOL,\n\ttype TodosEnabledChangedHandler,\n} from \"../core/todo-settings.ts\";\nimport { keyText } from \"../modes/interactive/components/keybinding-hints.ts\";\n\n// ---------------------------------------------------------------------------\n// Pure logic (exported for tests)\n// ---------------------------------------------------------------------------\n\nexport type TodoStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface TodoItem {\n\tid: string;\n\tcontent: string;\n\tstatus: TodoStatus;\n}\n\nexport interface TodoWidgetLine {\n\tkind: \"todo\" | \"summary\" | \"hint\";\n\tstatus?: TodoStatus;\n\ttext: string;\n}\n\n/** Collapsed widgets with five or more active items show this many rows. */\nexport const TODO_WIDGET_COLLAPSED_ROWS = 3;\n\nconst STATUS_GLYPHS: Record<TodoStatus, string> = {\n\tin_progress: \"●\",\n\tpending: \"○\",\n\tcompleted: \"✓\",\n};\n\n/** Short model-facing summary, e.g. \"4 todos: 1 in progress, 2 pending, 1 completed\". */\nexport function summarizeTodos(todos: TodoItem[]): string {\n\tif (todos.length === 0) return \"No todos.\";\n\tconst count = (s: TodoStatus) => todos.filter((t) => t.status === s).length;\n\tconst parts: string[] = [];\n\tconst inProgress = count(\"in_progress\");\n\tconst pending = count(\"pending\");\n\tconst completed = count(\"completed\");\n\tif (inProgress > 0) parts.push(`${inProgress} in progress`);\n\tif (pending > 0) parts.push(`${pending} pending`);\n\tif (completed > 0) parts.push(`${completed} completed`);\n\treturn `${todos.length} todo${todos.length === 1 ? \"\" : \"s\"}: ${parts.join(\", \")}`;\n}\n\n/**\n * Widget lines for the current list. Collapsed mode shows all four active rows,\n * or TODO_WIDGET_COLLAPSED_ROWS when there are five or more (in-progress first, then pending),\n * and never emits a `✓ N done` summary. A `+N more (<expandKey> to expand)`\n * hint is appended when active rows are hidden. Expanded mode shows every\n * row, completed included. Empty list / all-completed collapsed → no lines.\n */\nexport function buildTodoWidgetLines(todos: TodoItem[], expanded: boolean, expandKey = \"click\"): TodoWidgetLine[] {\n\tif (todos.length === 0) return [];\n\tconst row = (t: TodoItem): TodoWidgetLine => ({\n\t\tkind: \"todo\",\n\t\tstatus: t.status,\n\t\ttext: `${STATUS_GLYPHS[t.status]} ${t.content}`,\n\t});\n\tconst active = [\n\t\t...todos.filter((t) => t.status === \"in_progress\"),\n\t\t...todos.filter((t) => t.status === \"pending\"),\n\t];\n\tconst done = todos.filter((t) => t.status === \"completed\");\n\tif (expanded) {\n\t\treturn [...active.map(row), ...done.map(row)];\n\t}\n\tconst visibleRows = active.length === 4 ? 4 : TODO_WIDGET_COLLAPSED_ROWS;\n\tconst lines: TodoWidgetLine[] = active.slice(0, visibleRows).map(row);\n\tconst hidden = active.length - visibleRows;\n\tif (hidden > 0) {\n\t\tlines.push({ kind: \"hint\", text: `+${hidden} more` });\n\t}\n\treturn lines;\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\n\nconst WIDGET_KEY = \"todos\";\nconst EXPANDED_BRIDGE_SYMBOL = Symbol.for(\"@lunr/tools-expanded-changed\");\n\nexport default function (pi: ExtensionAPI): void {\n\tlet todos: TodoItem[] = [];\n\tlet expanded = false;\n\tlet lastCtx: ExtensionContext | null = null;\n\n\tfunction colorize(line: TodoWidgetLine, theme: any): string {\n\t\tif (line.kind === \"summary\" || line.kind === \"hint\") return theme.fg(\"muted\", line.text);\n\t\tif (line.status === \"in_progress\") return theme.fg(\"accent\", line.text);\n\t\tif (line.status === \"completed\") return theme.fg(\"dim\", line.text);\n\t\treturn line.text;\n\t}\n\n\tfunction refreshWidget(): void {\n\t\tconst ctx = lastCtx;\n\t\tif (!ctx?.hasUI) return;\n\t\tconst lines = buildTodoWidgetLines(todos, expanded, keyText(\"app.tools.expand\"));\n\t\tif (todos.length === 0 || lines.length === 0) {\n\t\t\tctx.ui.setWidget(WIDGET_KEY, undefined);\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.setWidget(\n\t\t\tWIDGET_KEY,\n\t\t\t(_tui: unknown, theme: any) => {\n\t\t\t\tconst text = new Text(lines.map((l) => colorize(l, theme)).join(\"\\n\"), 1, 0);\n\t\t\t\treturn {\n\t\t\t\t\trender: (width: number) => text.render(width),\n\t\t\t\t\tinvalidate: () => text.invalidate?.(),\n\t\t\t\t\thandleClick: () => {\n\t\t\t\t\t\texpanded = !expanded;\n\t\t\t\t\t\trefreshWidget();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ placement: \"aboveEditor\" },\n\t\t);\n\t}\n\n\tfunction pruneCompleted(): void {\n\t\tconst next = todos.filter((t) => t.status !== \"completed\");\n\t\tif (next.length === todos.length) return;\n\t\ttodos = next;\n\t\trefreshWidget();\n\t}\n\n\tconst handleEnabledChanged: TodosEnabledChangedHandler = (enabled) => {\n\t\tif (enabled) return;\n\t\ttodos = [];\n\t\trefreshWidget();\n\t};\n\n\tfunction registerEnabledBridge(): void {\n\t\t(globalThis as Record<symbol, unknown>)[TODOS_ENABLED_CHANGED_SYMBOL] = handleEnabledChanged;\n\t}\n\tregisterEnabledBridge();\n\n\t// --- Expansion bridge (interactive-mode setToolsExpanded invokes this) ---\n\tfunction registerExpandedBridge(): void {\n\t\t(globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL] = (value: boolean) => {\n\t\t\texpanded = Boolean(value);\n\t\t\trefreshWidget();\n\t\t};\n\t}\n\tregisterExpandedBridge();\n\n\t// --- Session lifecycle: per-session in-memory state ---\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tlastCtx = ctx;\n\t\ttodos = [];\n\t\texpanded = ctx.hasUI ? (ctx.ui.getToolsExpanded?.() ?? false) : false;\n\t\tregisterExpandedBridge();\n\t\tregisterEnabledBridge();\n\t\tif (ctx.hasUI) ctx.ui.setWidget(WIDGET_KEY, undefined);\n\t});\n\n\t// lunr: prune completed items on the next real user message, not slash\n\t// commands or agent follow-up turns.\n\tpi.on(\"message_start\", (event, ctx) => {\n\t\tif (event.message?.role !== \"user\") return;\n\t\tlastCtx = ctx;\n\t\tpruneCompleted();\n\t});\n\n\tpi.on(\"session_shutdown\", () => {\n\t\tif (lastCtx?.hasUI) lastCtx.ui.setWidget(WIDGET_KEY, undefined);\n\t\tlastCtx = null;\n\t\tdelete (globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL];\n\t\tif ((globalThis as Record<symbol, unknown>)[TODOS_ENABLED_CHANGED_SYMBOL] === handleEnabledChanged) {\n\t\t\tdelete (globalThis as Record<symbol, unknown>)[TODOS_ENABLED_CHANGED_SYMBOL];\n\t\t}\n\t});\n\n\t// --- todo tool (agent-facing) ---\n\tpi.registerTool({\n\t\tname: \"todo\",\n\t\tlabel: \"Todo\",\n\t\tdescription: [\n\t\t\t\"Manage the session todo list shown above the user's editor. Full-replace semantics:\",\n\t\t\t\"every call must send the ENTIRE list; send an empty array to clear it.\",\n\t\t\t\"Each item: { id, content, status: 'pending' | 'in_progress' | 'completed' }.\",\n\t\t\t\"Use it to track multi-step work; keep exactly one item in_progress at a time.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\ttodos: Type.Array(\n\t\t\t\tType.Object({\n\t\t\t\t\tid: Type.String({ description: \"Stable id for the item.\" }),\n\t\t\t\t\tcontent: Type.String({ description: \"Short description of the task.\" }),\n\t\t\t\t\tstatus: Type.Union([\n\t\t\t\t\t\tType.Literal(\"pending\"),\n\t\t\t\t\t\tType.Literal(\"in_progress\"),\n\t\t\t\t\t\tType.Literal(\"completed\"),\n\t\t\t\t\t]),\n\t\t\t\t}),\n\t\t\t),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst text = (t: string) => ({ content: [{ type: \"text\" as const, text: t }] });\n\t\t\tconst incoming = Array.isArray(params?.todos) ? params.todos : [];\n\t\t\ttodos = incoming\n\t\t\t\t.filter((t: any) => t && typeof t.content === \"string\" && t.content.trim().length > 0)\n\t\t\t\t.map((t: any, i: number) => ({\n\t\t\t\t\tid: typeof t.id === \"string\" && t.id ? t.id : String(i + 1),\n\t\t\t\t\tcontent: t.content.trim(),\n\t\t\t\t\tstatus: t.status === \"in_progress\" || t.status === \"completed\" ? t.status : \"pending\",\n\t\t\t\t}));\n\t\t\tlastCtx = ctx;\n\t\t\trefreshWidget();\n\t\t\treturn text(summarizeTodos(todos));\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\tconst n = Array.isArray(args?.todos) ? args.todos.length : 0;\n\t\t\tconst detail = n === 0 ? \"clear\" : `${n} item${n === 1 ? \"\" : \"s\"}`;\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(\"todo \")) + theme.fg(\"dim\", detail), 0, 0);\n\t\t},\n\t\trenderResult(result, { isPartial }, theme) {\n\t\t\tif (isPartial) return new Text(theme.fg(\"warning\", \"Updating todos...\"), 0, 0);\n\t\t\tconst first = result?.content?.[0];\n\t\t\tconst summary = first?.type === \"text\" ? first.text : \"\";\n\t\t\treturn new Text(theme.fg(\"dim\", summary), 0, 0);\n\t\t},\n\t});\n}\n"]}
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
import { Text } from "@ashx-j/lunr-tui";
|
|
28
28
|
import { Type } from "@sinclair/typebox";
|
|
29
|
+
import { TODOS_ENABLED_CHANGED_SYMBOL, } from "../core/todo-settings.js";
|
|
29
30
|
import { keyText } from "../modes/interactive/components/keybinding-hints.js";
|
|
30
31
|
/** Collapsed widgets with five or more active items show this many rows. */
|
|
31
32
|
export const TODO_WIDGET_COLLAPSED_ROWS = 3;
|
|
@@ -129,6 +130,16 @@ export default function (pi) {
|
|
|
129
130
|
todos = next;
|
|
130
131
|
refreshWidget();
|
|
131
132
|
}
|
|
133
|
+
const handleEnabledChanged = (enabled) => {
|
|
134
|
+
if (enabled)
|
|
135
|
+
return;
|
|
136
|
+
todos = [];
|
|
137
|
+
refreshWidget();
|
|
138
|
+
};
|
|
139
|
+
function registerEnabledBridge() {
|
|
140
|
+
globalThis[TODOS_ENABLED_CHANGED_SYMBOL] = handleEnabledChanged;
|
|
141
|
+
}
|
|
142
|
+
registerEnabledBridge();
|
|
132
143
|
// --- Expansion bridge (interactive-mode setToolsExpanded invokes this) ---
|
|
133
144
|
function registerExpandedBridge() {
|
|
134
145
|
globalThis[EXPANDED_BRIDGE_SYMBOL] = (value) => {
|
|
@@ -143,6 +154,7 @@ export default function (pi) {
|
|
|
143
154
|
todos = [];
|
|
144
155
|
expanded = ctx.hasUI ? (ctx.ui.getToolsExpanded?.() ?? false) : false;
|
|
145
156
|
registerExpandedBridge();
|
|
157
|
+
registerEnabledBridge();
|
|
146
158
|
if (ctx.hasUI)
|
|
147
159
|
ctx.ui.setWidget(WIDGET_KEY, undefined);
|
|
148
160
|
});
|
|
@@ -159,6 +171,9 @@ export default function (pi) {
|
|
|
159
171
|
lastCtx.ui.setWidget(WIDGET_KEY, undefined);
|
|
160
172
|
lastCtx = null;
|
|
161
173
|
delete globalThis[EXPANDED_BRIDGE_SYMBOL];
|
|
174
|
+
if (globalThis[TODOS_ENABLED_CHANGED_SYMBOL] === handleEnabledChanged) {
|
|
175
|
+
delete globalThis[TODOS_ENABLED_CHANGED_SYMBOL];
|
|
176
|
+
}
|
|
162
177
|
});
|
|
163
178
|
// --- todo tool (agent-facing) ---
|
|
164
179
|
pi.registerTool({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lunr-todos.js","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-todos.ts"],"names":[],"mappings":"AAAA,cAAc;AACd;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,qDAAqD,CAAC;AAoB9E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,MAAM,aAAa,GAA+B;IACjD,WAAW,EAAE,KAAG;IAChB,OAAO,EAAE,KAAG;IACZ,SAAS,EAAE,KAAG;CACd,CAAC;AAEF,yFAAyF;AACzF,MAAM,UAAU,cAAc,CAAC,KAAiB,EAAU;IACzD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,UAAU,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,cAAc,CAAC,CAAC;IAC5D,IAAI,OAAO,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,UAAU,CAAC,CAAC;IAClD,IAAI,SAAS,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,YAAY,CAAC,CAAC;IACxD,OAAO,GAAG,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAAA,CACnF;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAiB,EAAE,QAAiB,EAAE,SAAS,GAAG,OAAO,EAAoB;IACjH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,CAAC,CAAW,EAAkB,EAAE,CAAC,CAAC;QAC7C,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,IAAI,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE;KAC/C,CAAC,CAAC;IACH,MAAM,MAAM,GAAG;QACd,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC;QAClD,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;KAC9C,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IAC3D,IAAI,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC;IACzE,MAAM,KAAK,GAAqB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,UAAU,GAAG,OAAO,CAAC;AAC3B,MAAM,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAE1E,MAAM,CAAC,OAAO,WAAW,EAAgB,EAAQ;IAChD,IAAI,KAAK,GAAe,EAAE,CAAC;IAC3B,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,OAAO,GAA4B,IAAI,CAAC;IAE5C,SAAS,QAAQ,CAAC,IAAoB,EAAE,KAAU,EAAU;QAC3D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACzF,IAAI,IAAI,CAAC,MAAM,KAAK,aAAa;YAAE,OAAO,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACxE,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC,IAAI,CAAC;IAAA,CACjB;IAED,SAAS,aAAa,GAAS;QAC9B,MAAM,GAAG,GAAG,OAAO,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,KAAK;YAAE,OAAO;QACxB,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACjF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACxC,OAAO;QACR,CAAC;QACD,GAAG,CAAC,EAAE,CAAC,SAAS,CACf,UAAU,EACV,CAAC,IAAa,EAAE,KAAU,EAAE,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7E,OAAO;gBACN,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7C,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;gBACrC,WAAW,EAAE,GAAG,EAAE,CAAC;oBAClB,QAAQ,GAAG,CAAC,QAAQ,CAAC;oBACrB,aAAa,EAAE,CAAC;oBAChB,OAAO,IAAI,CAAC;gBAAA,CACZ;aACD,CAAC;QAAA,CACF,EACD,EAAE,SAAS,EAAE,aAAa,EAAE,CAC5B,CAAC;IAAA,CACF;IAED,SAAS,cAAc,GAAS;QAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;QAC3D,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAAE,OAAO;QACzC,KAAK,GAAG,IAAI,CAAC;QACb,aAAa,EAAE,CAAC;IAAA,CAChB;IAED,4EAA4E;IAC5E,SAAS,sBAAsB,GAAS;QACtC,UAAsC,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC;YACrF,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,aAAa,EAAE,CAAC;QAAA,CAChB,CAAC;IAAA,CACF;IACD,sBAAsB,EAAE,CAAC;IAEzB,yDAAyD;IACzD,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QACvC,OAAO,GAAG,GAAG,CAAC;QACd,KAAK,GAAG,EAAE,CAAC;QACX,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,gBAAgB,EAAE,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACtE,sBAAsB,EAAE,CAAC;QACzB,IAAI,GAAG,CAAC,KAAK;YAAE,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAAA,CACvD,CAAC,CAAC;IAEH,uEAAuE;IACvE,qCAAqC;IACrC,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,KAAK,MAAM;YAAE,OAAO;QAC3C,OAAO,GAAG,GAAG,CAAC;QACd,cAAc,EAAE,CAAC;IAAA,CACjB,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC;QAC/B,IAAI,OAAO,EAAE,KAAK;YAAE,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAChE,OAAO,GAAG,IAAI,CAAC;QACf,OAAQ,UAAsC,CAAC,sBAAsB,CAAC,CAAC;IAAA,CACvE,CAAC,CAAC;IAEH,mCAAmC;IACnC,EAAE,CAAC,YAAY,CAAC;QACf,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,MAAM;QACb,WAAW,EAAE;YACZ,qFAAqF;YACrF,wEAAwE;YACxE,8EAA8E;YAC9E,+EAA+E;SAC/E,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK,CAChB,IAAI,CAAC,MAAM,CAAC;gBACX,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;gBAC3D,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;gBACvE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;oBAClB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;oBACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;oBAC3B,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;iBACzB,CAAC;aACF,CAAC,CACF;SACD,CAAC;QACF,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE;YAC3D,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAChF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,KAAK,GAAG,QAAQ;iBACd,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;iBACrF,GAAG,CAAC,CAAC,CAAM,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC;gBAC5B,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC3D,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE;gBACzB,MAAM,EAAE,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;aACrF,CAAC,CAAC,CAAC;YACL,OAAO,GAAG,GAAG,CAAC;YACd,aAAa,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;QAAA,CACnC;QACD,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE;YACvB,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;YACpE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAAA,CAC5F;QACD,YAAY,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE;YAC1C,IAAI,SAAS;gBAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/E,MAAM,KAAK,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAAA,CAChD;KACD,CAAC,CAAC;AAAA,CACH","sourcesContent":["// @ts-nocheck\n/**\n * lunr-todos — lunR-native agent todo list with an above-editor widget.\n *\n * lunR: this file is lunR-native (not an absorbed upstream extension).\n *\n * - One `todo` tool (TypeBox), full-replace semantics: every call sends the\n * ENTIRE list; an empty array clears it. State is per-session, in-memory\n * only (extension closure) — nothing is persisted.\n * - Chat render is a quiet one-liner (renderCall/renderResult), matching the\n * cron tool's minimal footprint.\n * - After every state change the list is mirrored into a `todos` widget above\n * the editor (component factory, so MAX_WIDGET_LINES string truncation does\n * not apply). Collapsed: four active items fit in full; lists of five or\n * more show three rows (in-progress first, then pending). Completed items\n * never appear collapsed. `+N more` still\n * applies to hidden active rows. Expanded: every row, completed included\n * until the next user turn prunes them.\n * - Click the widget to expand/collapse.\n *\n * The pure logic (summarizeTodos / buildTodoWidgetLines) is exported for\n * vitest — see test/lunr-todos.test.ts.\n *\n * `// @ts-nocheck` matches the builtin-extension convention (see lunr-cron).\n * Runtime imports stay on concrete core modules — never the package barrel.\n */\n\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { Text } from \"@ashx-j/lunr-tui\";\nimport { Type } from \"@sinclair/typebox\";\nimport { keyText } from \"../modes/interactive/components/keybinding-hints.ts\";\n\n// ---------------------------------------------------------------------------\n// Pure logic (exported for tests)\n// ---------------------------------------------------------------------------\n\nexport type TodoStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface TodoItem {\n\tid: string;\n\tcontent: string;\n\tstatus: TodoStatus;\n}\n\nexport interface TodoWidgetLine {\n\tkind: \"todo\" | \"summary\" | \"hint\";\n\tstatus?: TodoStatus;\n\ttext: string;\n}\n\n/** Collapsed widgets with five or more active items show this many rows. */\nexport const TODO_WIDGET_COLLAPSED_ROWS = 3;\n\nconst STATUS_GLYPHS: Record<TodoStatus, string> = {\n\tin_progress: \"●\",\n\tpending: \"○\",\n\tcompleted: \"✓\",\n};\n\n/** Short model-facing summary, e.g. \"4 todos: 1 in progress, 2 pending, 1 completed\". */\nexport function summarizeTodos(todos: TodoItem[]): string {\n\tif (todos.length === 0) return \"No todos.\";\n\tconst count = (s: TodoStatus) => todos.filter((t) => t.status === s).length;\n\tconst parts: string[] = [];\n\tconst inProgress = count(\"in_progress\");\n\tconst pending = count(\"pending\");\n\tconst completed = count(\"completed\");\n\tif (inProgress > 0) parts.push(`${inProgress} in progress`);\n\tif (pending > 0) parts.push(`${pending} pending`);\n\tif (completed > 0) parts.push(`${completed} completed`);\n\treturn `${todos.length} todo${todos.length === 1 ? \"\" : \"s\"}: ${parts.join(\", \")}`;\n}\n\n/**\n * Widget lines for the current list. Collapsed mode shows all four active rows,\n * or TODO_WIDGET_COLLAPSED_ROWS when there are five or more (in-progress first, then pending),\n * and never emits a `✓ N done` summary. A `+N more (<expandKey> to expand)`\n * hint is appended when active rows are hidden. Expanded mode shows every\n * row, completed included. Empty list / all-completed collapsed → no lines.\n */\nexport function buildTodoWidgetLines(todos: TodoItem[], expanded: boolean, expandKey = \"click\"): TodoWidgetLine[] {\n\tif (todos.length === 0) return [];\n\tconst row = (t: TodoItem): TodoWidgetLine => ({\n\t\tkind: \"todo\",\n\t\tstatus: t.status,\n\t\ttext: `${STATUS_GLYPHS[t.status]} ${t.content}`,\n\t});\n\tconst active = [\n\t\t...todos.filter((t) => t.status === \"in_progress\"),\n\t\t...todos.filter((t) => t.status === \"pending\"),\n\t];\n\tconst done = todos.filter((t) => t.status === \"completed\");\n\tif (expanded) {\n\t\treturn [...active.map(row), ...done.map(row)];\n\t}\n\tconst visibleRows = active.length === 4 ? 4 : TODO_WIDGET_COLLAPSED_ROWS;\n\tconst lines: TodoWidgetLine[] = active.slice(0, visibleRows).map(row);\n\tconst hidden = active.length - visibleRows;\n\tif (hidden > 0) {\n\t\tlines.push({ kind: \"hint\", text: `+${hidden} more` });\n\t}\n\treturn lines;\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\n\nconst WIDGET_KEY = \"todos\";\nconst EXPANDED_BRIDGE_SYMBOL = Symbol.for(\"@lunr/tools-expanded-changed\");\n\nexport default function (pi: ExtensionAPI): void {\n\tlet todos: TodoItem[] = [];\n\tlet expanded = false;\n\tlet lastCtx: ExtensionContext | null = null;\n\n\tfunction colorize(line: TodoWidgetLine, theme: any): string {\n\t\tif (line.kind === \"summary\" || line.kind === \"hint\") return theme.fg(\"muted\", line.text);\n\t\tif (line.status === \"in_progress\") return theme.fg(\"accent\", line.text);\n\t\tif (line.status === \"completed\") return theme.fg(\"dim\", line.text);\n\t\treturn line.text;\n\t}\n\n\tfunction refreshWidget(): void {\n\t\tconst ctx = lastCtx;\n\t\tif (!ctx?.hasUI) return;\n\t\tconst lines = buildTodoWidgetLines(todos, expanded, keyText(\"app.tools.expand\"));\n\t\tif (todos.length === 0 || lines.length === 0) {\n\t\t\tctx.ui.setWidget(WIDGET_KEY, undefined);\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.setWidget(\n\t\t\tWIDGET_KEY,\n\t\t\t(_tui: unknown, theme: any) => {\n\t\t\t\tconst text = new Text(lines.map((l) => colorize(l, theme)).join(\"\\n\"), 1, 0);\n\t\t\t\treturn {\n\t\t\t\t\trender: (width: number) => text.render(width),\n\t\t\t\t\tinvalidate: () => text.invalidate?.(),\n\t\t\t\t\thandleClick: () => {\n\t\t\t\t\t\texpanded = !expanded;\n\t\t\t\t\t\trefreshWidget();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ placement: \"aboveEditor\" },\n\t\t);\n\t}\n\n\tfunction pruneCompleted(): void {\n\t\tconst next = todos.filter((t) => t.status !== \"completed\");\n\t\tif (next.length === todos.length) return;\n\t\ttodos = next;\n\t\trefreshWidget();\n\t}\n\n\t// --- Expansion bridge (interactive-mode setToolsExpanded invokes this) ---\n\tfunction registerExpandedBridge(): void {\n\t\t(globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL] = (value: boolean) => {\n\t\t\texpanded = Boolean(value);\n\t\t\trefreshWidget();\n\t\t};\n\t}\n\tregisterExpandedBridge();\n\n\t// --- Session lifecycle: per-session in-memory state ---\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tlastCtx = ctx;\n\t\ttodos = [];\n\t\texpanded = ctx.hasUI ? (ctx.ui.getToolsExpanded?.() ?? false) : false;\n\t\tregisterExpandedBridge();\n\t\tif (ctx.hasUI) ctx.ui.setWidget(WIDGET_KEY, undefined);\n\t});\n\n\t// lunr: prune completed items on the next real user message, not slash\n\t// commands or agent follow-up turns.\n\tpi.on(\"message_start\", (event, ctx) => {\n\t\tif (event.message?.role !== \"user\") return;\n\t\tlastCtx = ctx;\n\t\tpruneCompleted();\n\t});\n\n\tpi.on(\"session_shutdown\", () => {\n\t\tif (lastCtx?.hasUI) lastCtx.ui.setWidget(WIDGET_KEY, undefined);\n\t\tlastCtx = null;\n\t\tdelete (globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL];\n\t});\n\n\t// --- todo tool (agent-facing) ---\n\tpi.registerTool({\n\t\tname: \"todo\",\n\t\tlabel: \"Todo\",\n\t\tdescription: [\n\t\t\t\"Manage the session todo list shown above the user's editor. Full-replace semantics:\",\n\t\t\t\"every call must send the ENTIRE list; send an empty array to clear it.\",\n\t\t\t\"Each item: { id, content, status: 'pending' | 'in_progress' | 'completed' }.\",\n\t\t\t\"Use it to track multi-step work; keep exactly one item in_progress at a time.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\ttodos: Type.Array(\n\t\t\t\tType.Object({\n\t\t\t\t\tid: Type.String({ description: \"Stable id for the item.\" }),\n\t\t\t\t\tcontent: Type.String({ description: \"Short description of the task.\" }),\n\t\t\t\t\tstatus: Type.Union([\n\t\t\t\t\t\tType.Literal(\"pending\"),\n\t\t\t\t\t\tType.Literal(\"in_progress\"),\n\t\t\t\t\t\tType.Literal(\"completed\"),\n\t\t\t\t\t]),\n\t\t\t\t}),\n\t\t\t),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst text = (t: string) => ({ content: [{ type: \"text\" as const, text: t }] });\n\t\t\tconst incoming = Array.isArray(params?.todos) ? params.todos : [];\n\t\t\ttodos = incoming\n\t\t\t\t.filter((t: any) => t && typeof t.content === \"string\" && t.content.trim().length > 0)\n\t\t\t\t.map((t: any, i: number) => ({\n\t\t\t\t\tid: typeof t.id === \"string\" && t.id ? t.id : String(i + 1),\n\t\t\t\t\tcontent: t.content.trim(),\n\t\t\t\t\tstatus: t.status === \"in_progress\" || t.status === \"completed\" ? t.status : \"pending\",\n\t\t\t\t}));\n\t\t\tlastCtx = ctx;\n\t\t\trefreshWidget();\n\t\t\treturn text(summarizeTodos(todos));\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\tconst n = Array.isArray(args?.todos) ? args.todos.length : 0;\n\t\t\tconst detail = n === 0 ? \"clear\" : `${n} item${n === 1 ? \"\" : \"s\"}`;\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(\"todo \")) + theme.fg(\"dim\", detail), 0, 0);\n\t\t},\n\t\trenderResult(result, { isPartial }, theme) {\n\t\t\tif (isPartial) return new Text(theme.fg(\"warning\", \"Updating todos...\"), 0, 0);\n\t\t\tconst first = result?.content?.[0];\n\t\t\tconst summary = first?.type === \"text\" ? first.text : \"\";\n\t\t\treturn new Text(theme.fg(\"dim\", summary), 0, 0);\n\t\t},\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lunr-todos.js","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-todos.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * lunr-todos — lunR-native agent todo list with an above-editor widget.\n *\n * lunR: this file is lunR-native (not an absorbed upstream extension).\n *\n * - One `todo` tool (TypeBox), full-replace semantics: every call sends the\n * ENTIRE list; an empty array clears it. State is per-session, in-memory\n * only (extension closure) — nothing is persisted.\n * - Chat render is a quiet one-liner (renderCall/renderResult), matching the\n * cron tool's minimal footprint.\n * - After every state change the list is mirrored into a `todos` widget above\n * the editor (component factory, so MAX_WIDGET_LINES string truncation does\n * not apply). Collapsed: four active items fit in full; lists of five or\n * more show three rows (in-progress first, then pending). Completed items\n * never appear collapsed. `+N more` still\n * applies to hidden active rows. Expanded: every row, completed included\n * until the next user turn prunes them.\n * - Click the widget to expand/collapse.\n *\n * The pure logic (summarizeTodos / buildTodoWidgetLines) is exported for\n * vitest — see test/lunr-todos.test.ts.\n *\n * `// @ts-nocheck` matches the builtin-extension convention (see lunr-cron).\n * Runtime imports stay on concrete core modules — never the package barrel.\n */\n\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { Text } from \"@ashx-j/lunr-tui\";\nimport { Type } from \"@sinclair/typebox\";\nimport {\n\tTODOS_ENABLED_CHANGED_SYMBOL,\n\ttype TodosEnabledChangedHandler,\n} from \"../core/todo-settings.ts\";\nimport { keyText } from \"../modes/interactive/components/keybinding-hints.ts\";\n\n// ---------------------------------------------------------------------------\n// Pure logic (exported for tests)\n// ---------------------------------------------------------------------------\n\nexport type TodoStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface TodoItem {\n\tid: string;\n\tcontent: string;\n\tstatus: TodoStatus;\n}\n\nexport interface TodoWidgetLine {\n\tkind: \"todo\" | \"summary\" | \"hint\";\n\tstatus?: TodoStatus;\n\ttext: string;\n}\n\n/** Collapsed widgets with five or more active items show this many rows. */\nexport const TODO_WIDGET_COLLAPSED_ROWS = 3;\n\nconst STATUS_GLYPHS: Record<TodoStatus, string> = {\n\tin_progress: \"●\",\n\tpending: \"○\",\n\tcompleted: \"✓\",\n};\n\n/** Short model-facing summary, e.g. \"4 todos: 1 in progress, 2 pending, 1 completed\". */\nexport function summarizeTodos(todos: TodoItem[]): string {\n\tif (todos.length === 0) return \"No todos.\";\n\tconst count = (s: TodoStatus) => todos.filter((t) => t.status === s).length;\n\tconst parts: string[] = [];\n\tconst inProgress = count(\"in_progress\");\n\tconst pending = count(\"pending\");\n\tconst completed = count(\"completed\");\n\tif (inProgress > 0) parts.push(`${inProgress} in progress`);\n\tif (pending > 0) parts.push(`${pending} pending`);\n\tif (completed > 0) parts.push(`${completed} completed`);\n\treturn `${todos.length} todo${todos.length === 1 ? \"\" : \"s\"}: ${parts.join(\", \")}`;\n}\n\n/**\n * Widget lines for the current list. Collapsed mode shows all four active rows,\n * or TODO_WIDGET_COLLAPSED_ROWS when there are five or more (in-progress first, then pending),\n * and never emits a `✓ N done` summary. A `+N more (<expandKey> to expand)`\n * hint is appended when active rows are hidden. Expanded mode shows every\n * row, completed included. Empty list / all-completed collapsed → no lines.\n */\nexport function buildTodoWidgetLines(todos: TodoItem[], expanded: boolean, expandKey = \"click\"): TodoWidgetLine[] {\n\tif (todos.length === 0) return [];\n\tconst row = (t: TodoItem): TodoWidgetLine => ({\n\t\tkind: \"todo\",\n\t\tstatus: t.status,\n\t\ttext: `${STATUS_GLYPHS[t.status]} ${t.content}`,\n\t});\n\tconst active = [\n\t\t...todos.filter((t) => t.status === \"in_progress\"),\n\t\t...todos.filter((t) => t.status === \"pending\"),\n\t];\n\tconst done = todos.filter((t) => t.status === \"completed\");\n\tif (expanded) {\n\t\treturn [...active.map(row), ...done.map(row)];\n\t}\n\tconst visibleRows = active.length === 4 ? 4 : TODO_WIDGET_COLLAPSED_ROWS;\n\tconst lines: TodoWidgetLine[] = active.slice(0, visibleRows).map(row);\n\tconst hidden = active.length - visibleRows;\n\tif (hidden > 0) {\n\t\tlines.push({ kind: \"hint\", text: `+${hidden} more` });\n\t}\n\treturn lines;\n}\n\n// ---------------------------------------------------------------------------\n// Extension\n// ---------------------------------------------------------------------------\n\nconst WIDGET_KEY = \"todos\";\nconst EXPANDED_BRIDGE_SYMBOL = Symbol.for(\"@lunr/tools-expanded-changed\");\n\nexport default function (pi: ExtensionAPI): void {\n\tlet todos: TodoItem[] = [];\n\tlet expanded = false;\n\tlet lastCtx: ExtensionContext | null = null;\n\n\tfunction colorize(line: TodoWidgetLine, theme: any): string {\n\t\tif (line.kind === \"summary\" || line.kind === \"hint\") return theme.fg(\"muted\", line.text);\n\t\tif (line.status === \"in_progress\") return theme.fg(\"accent\", line.text);\n\t\tif (line.status === \"completed\") return theme.fg(\"dim\", line.text);\n\t\treturn line.text;\n\t}\n\n\tfunction refreshWidget(): void {\n\t\tconst ctx = lastCtx;\n\t\tif (!ctx?.hasUI) return;\n\t\tconst lines = buildTodoWidgetLines(todos, expanded, keyText(\"app.tools.expand\"));\n\t\tif (todos.length === 0 || lines.length === 0) {\n\t\t\tctx.ui.setWidget(WIDGET_KEY, undefined);\n\t\t\treturn;\n\t\t}\n\t\tctx.ui.setWidget(\n\t\t\tWIDGET_KEY,\n\t\t\t(_tui: unknown, theme: any) => {\n\t\t\t\tconst text = new Text(lines.map((l) => colorize(l, theme)).join(\"\\n\"), 1, 0);\n\t\t\t\treturn {\n\t\t\t\t\trender: (width: number) => text.render(width),\n\t\t\t\t\tinvalidate: () => text.invalidate?.(),\n\t\t\t\t\thandleClick: () => {\n\t\t\t\t\t\texpanded = !expanded;\n\t\t\t\t\t\trefreshWidget();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\t{ placement: \"aboveEditor\" },\n\t\t);\n\t}\n\n\tfunction pruneCompleted(): void {\n\t\tconst next = todos.filter((t) => t.status !== \"completed\");\n\t\tif (next.length === todos.length) return;\n\t\ttodos = next;\n\t\trefreshWidget();\n\t}\n\n\tconst handleEnabledChanged: TodosEnabledChangedHandler = (enabled) => {\n\t\tif (enabled) return;\n\t\ttodos = [];\n\t\trefreshWidget();\n\t};\n\n\tfunction registerEnabledBridge(): void {\n\t\t(globalThis as Record<symbol, unknown>)[TODOS_ENABLED_CHANGED_SYMBOL] = handleEnabledChanged;\n\t}\n\tregisterEnabledBridge();\n\n\t// --- Expansion bridge (interactive-mode setToolsExpanded invokes this) ---\n\tfunction registerExpandedBridge(): void {\n\t\t(globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL] = (value: boolean) => {\n\t\t\texpanded = Boolean(value);\n\t\t\trefreshWidget();\n\t\t};\n\t}\n\tregisterExpandedBridge();\n\n\t// --- Session lifecycle: per-session in-memory state ---\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tlastCtx = ctx;\n\t\ttodos = [];\n\t\texpanded = ctx.hasUI ? (ctx.ui.getToolsExpanded?.() ?? false) : false;\n\t\tregisterExpandedBridge();\n\t\tregisterEnabledBridge();\n\t\tif (ctx.hasUI) ctx.ui.setWidget(WIDGET_KEY, undefined);\n\t});\n\n\t// lunr: prune completed items on the next real user message, not slash\n\t// commands or agent follow-up turns.\n\tpi.on(\"message_start\", (event, ctx) => {\n\t\tif (event.message?.role !== \"user\") return;\n\t\tlastCtx = ctx;\n\t\tpruneCompleted();\n\t});\n\n\tpi.on(\"session_shutdown\", () => {\n\t\tif (lastCtx?.hasUI) lastCtx.ui.setWidget(WIDGET_KEY, undefined);\n\t\tlastCtx = null;\n\t\tdelete (globalThis as Record<symbol, unknown>)[EXPANDED_BRIDGE_SYMBOL];\n\t\tif ((globalThis as Record<symbol, unknown>)[TODOS_ENABLED_CHANGED_SYMBOL] === handleEnabledChanged) {\n\t\t\tdelete (globalThis as Record<symbol, unknown>)[TODOS_ENABLED_CHANGED_SYMBOL];\n\t\t}\n\t});\n\n\t// --- todo tool (agent-facing) ---\n\tpi.registerTool({\n\t\tname: \"todo\",\n\t\tlabel: \"Todo\",\n\t\tdescription: [\n\t\t\t\"Manage the session todo list shown above the user's editor. Full-replace semantics:\",\n\t\t\t\"every call must send the ENTIRE list; send an empty array to clear it.\",\n\t\t\t\"Each item: { id, content, status: 'pending' | 'in_progress' | 'completed' }.\",\n\t\t\t\"Use it to track multi-step work; keep exactly one item in_progress at a time.\",\n\t\t].join(\"\\n\"),\n\t\tparameters: Type.Object({\n\t\t\ttodos: Type.Array(\n\t\t\t\tType.Object({\n\t\t\t\t\tid: Type.String({ description: \"Stable id for the item.\" }),\n\t\t\t\t\tcontent: Type.String({ description: \"Short description of the task.\" }),\n\t\t\t\t\tstatus: Type.Union([\n\t\t\t\t\t\tType.Literal(\"pending\"),\n\t\t\t\t\t\tType.Literal(\"in_progress\"),\n\t\t\t\t\t\tType.Literal(\"completed\"),\n\t\t\t\t\t]),\n\t\t\t\t}),\n\t\t\t),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx) {\n\t\t\tconst text = (t: string) => ({ content: [{ type: \"text\" as const, text: t }] });\n\t\t\tconst incoming = Array.isArray(params?.todos) ? params.todos : [];\n\t\t\ttodos = incoming\n\t\t\t\t.filter((t: any) => t && typeof t.content === \"string\" && t.content.trim().length > 0)\n\t\t\t\t.map((t: any, i: number) => ({\n\t\t\t\t\tid: typeof t.id === \"string\" && t.id ? t.id : String(i + 1),\n\t\t\t\t\tcontent: t.content.trim(),\n\t\t\t\t\tstatus: t.status === \"in_progress\" || t.status === \"completed\" ? t.status : \"pending\",\n\t\t\t\t}));\n\t\t\tlastCtx = ctx;\n\t\t\trefreshWidget();\n\t\t\treturn text(summarizeTodos(todos));\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\tconst n = Array.isArray(args?.todos) ? args.todos.length : 0;\n\t\t\tconst detail = n === 0 ? \"clear\" : `${n} item${n === 1 ? \"\" : \"s\"}`;\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(\"todo \")) + theme.fg(\"dim\", detail), 0, 0);\n\t\t},\n\t\trenderResult(result, { isPartial }, theme) {\n\t\t\tif (isPartial) return new Text(theme.fg(\"warning\", \"Updating todos...\"), 0, 0);\n\t\t\tconst first = result?.content?.[0];\n\t\t\tconst summary = first?.type === \"text\" ? first.text : \"\";\n\t\t\treturn new Text(theme.fg(\"dim\", summary), 0, 0);\n\t\t},\n\t});\n}\n"]}
|