@ashx-j/lunr 0.2.21 → 0.2.22
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 +1 -1
- package/README.md +20 -4
- 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 +3 -0
- package/dist/builtin-extensions/lunr-browser.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-browser.js +56 -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 +1 -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 +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.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 +47 -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 +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +20 -2
- 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 +7 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +18 -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/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +5 -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 +11 -2
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +31 -4
- 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 +11 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +53 -16
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/copyable-text.d.ts +31 -0
- package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/copyable-text.js +165 -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 +5 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +38 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +151 -7
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/node-runtime/agent-session-services-NQ6GKOIK.js +49 -0
- package/dist/node-runtime/{builtin-extensions-JCOPAAB5.js → builtin-extensions-GVC6IFDU.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-5BNJ4JUH.js +672 -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-6KDIOJL3.js → chunk-6427XAWG.js} +3 -3
- package/dist/node-runtime/{chunk-BOHIDQT4.js → chunk-6B2POMK7.js} +1 -1
- package/dist/node-runtime/{chunk-RNBHABBA.js → chunk-7QWNYZDI.js} +7 -0
- 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-BFNXONG3.js +521 -0
- 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-QZMODZQ2.js → chunk-E24EO34J.js} +2 -1
- package/dist/node-runtime/{chunk-2BUAYZ7K.js → chunk-EQ63ANHL.js} +422 -123
- package/dist/node-runtime/{chunk-GB2MGFLI.js → chunk-GJSAD4AB.js} +216 -201
- package/dist/node-runtime/{chunk-W3SILANP.js → chunk-GMHJCCEN.js} +8 -8
- package/dist/node-runtime/{chunk-DDWHZ633.js → chunk-GNN7H3B7.js} +1 -1
- package/dist/node-runtime/chunk-GS66LV4M.js +2830 -0
- package/dist/node-runtime/{chunk-6BEIBLQ3.js → chunk-H3XF4UVQ.js} +1 -1
- package/dist/node-runtime/chunk-H4K3JDRB.js +47 -0
- package/dist/node-runtime/{chunk-YMEAYRBE.js → chunk-HTFRRDSF.js} +2 -7
- package/dist/node-runtime/chunk-IMLCWLPI.js +9 -0
- package/dist/node-runtime/{chunk-Y5KOEMBH.js → chunk-IQIEU7SB.js} +9 -674
- package/dist/node-runtime/{chunk-OPEK5RRY.js → chunk-IVXYUAJE.js} +1 -1
- package/dist/node-runtime/{chunk-PDNXVXMD.js → chunk-IWOWXRWU.js} +58 -48
- package/dist/node-runtime/chunk-KKUTQQV7.js +144 -0
- package/dist/node-runtime/{chunk-AWVD5IEY.js → chunk-LMBNLFXQ.js} +23 -12
- 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-ORH324EP.js} +19 -3
- package/dist/node-runtime/{chunk-2SJB2AWP.js → chunk-PC2Z5TKZ.js} +3 -3
- package/dist/node-runtime/{chunk-SY2TFMLO.js → chunk-QDGKKKUM.js} +46 -151
- package/dist/node-runtime/chunk-R3K2F5GI.js +122 -0
- package/dist/node-runtime/chunk-RMQZU2YU.js +117 -0
- package/dist/node-runtime/{chunk-XI77KVKA.js → chunk-TDL7UWJ7.js} +283 -2999
- package/dist/node-runtime/{chunk-G6LRAP36.js → chunk-TQGPP4SC.js} +1 -1
- package/dist/node-runtime/chunk-UAEOTO52.js +119 -0
- package/dist/node-runtime/{chunk-VZR3NCM7.js → chunk-UAFLNHSH.js} +18 -14
- 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-V2A7CEXK.js +355 -0
- package/dist/node-runtime/chunk-VJPTNWAP.js +708 -0
- package/dist/node-runtime/{chunk-WKDK4C5P.js → chunk-VSSXXL36.js} +38 -164
- package/dist/node-runtime/{chunk-4I23VTC4.js → chunk-VWCE2HSZ.js} +21 -124
- package/dist/node-runtime/{chunk-WLLDXJRT.js → chunk-WADV2VDS.js} +22 -1014
- package/dist/node-runtime/{chunk-GKLEQ3I4.js → chunk-XLTL257W.js} +126 -27
- package/dist/node-runtime/chunk-YPHAIRZT.js +10 -0
- package/dist/node-runtime/cli-runtime.js +2 -2
- package/dist/node-runtime/command-3JHHXOPX.js +45 -0
- package/dist/node-runtime/commands-2JVNFGMQ.js +36 -0
- package/dist/node-runtime/{commands-MV5KOZ64.js → commands-KAMO2T6P.js} +10 -10
- 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-KBFVV63J.js} +4 -3
- package/dist/node-runtime/{extension-input-O4HSAEM4.js → extension-input-K24TVKVW.js} +4 -4
- package/dist/node-runtime/{extension-selector-X5FCX43D.js → extension-selector-SPNF7EDR.js} +4 -4
- package/dist/node-runtime/{extract-XLQSJN4V.js → extract-EQJE7FZZ.js} +2 -2
- package/dist/node-runtime/{gateway-BM6NLOH4.js → gateway-VFO6SFKK.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-C3CF7O7N.js} +21 -82
- package/dist/node-runtime/interactive-mode-LOM6AIF6.js +72 -0
- package/dist/node-runtime/{interactive-view-ILS6TAN5.js → interactive-view-IDSCPPK7.js} +8 -8
- package/dist/node-runtime/lunr-browser-YNW7FTYX.js +87 -0
- package/dist/node-runtime/{lunr-cron-4VHP4E4B.js → lunr-cron-BKHGNBKT.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-HMP25WBC.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-VCK4E2RC.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-FEUDLJOE.js} +201 -78
- 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-P5ODXPEG.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-LHRMJOKT.js} +5 -4
- package/dist/node-runtime/{settings-manager-CUGAZWAB.js → settings-manager-UUZ6NUXI.js} +7 -2
- package/dist/node-runtime/setup-JBKOLJ6F.js +18 -0
- package/dist/node-runtime/setup-NRXVZBLJ.js +155 -0
- package/dist/node-runtime/{subagent-executor-MH4A7CCF.js → subagent-executor-MLUMBWCP.js} +22 -18
- package/dist/node-runtime/theme-U7IGOA7O.js +68 -0
- package/dist/node-runtime/trust-manager-MMISNCYO.js +17 -0
- package/dist/node-runtime/{update-cli-XTZMZGOL.js → update-cli-4TP25CNW.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 +94 -16
- package/docs/interactive-startup.md +2 -1
- package/docs/sessions.md +10 -0
- package/docs/settings.md +1 -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/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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
lunR is derived from pi. The published npm package is **`@ashx-j/lunr@0.2.21`**. Versioned sections below (`0.80.x` and earlier) are **upstream pi history** and do not describe lunR releases.
|
|
4
4
|
|
|
5
|
-
## [
|
|
5
|
+
## [0.2.22] - 2026-09-20
|
|
6
6
|
|
|
7
7
|
## [0.2.21] - 2026-09-13
|
|
8
8
|
|
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 place a Copy button under a selected reusable excerpt, prompt, or code fragment. Clicking it copies only that block. Success or failure appears beside the button.
|
|
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 show their received text but no Copy button. 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`.
|
|
@@ -471,7 +486,7 @@ lunR keeps a small core and still lets you shape the product with [extensions](#
|
|
|
471
486
|
- **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
487
|
- **Permission modes** — `manual | yolo | plan | auto`; Shift+Tab cycles that order
|
|
473
488
|
- **Plan mode** — `/plan` plus the `present_plan` tool
|
|
474
|
-
- **Todos** — lunr-todos
|
|
489
|
+
- **Todos** — lunr-todos is a full-replace list and can be disabled in `/settings`
|
|
475
490
|
- **Background processes** — `/processes`
|
|
476
491
|
- **Cron** — `/cron`, `~/.lunr/agent/cron/` (TUI live session or gateway origin)
|
|
477
492
|
- **Gateway** — `lunr gateway` for Telegram and Discord
|
|
@@ -490,7 +505,8 @@ lunr [options] [@files...] [messages...]
|
|
|
490
505
|
### Product Commands
|
|
491
506
|
|
|
492
507
|
```bash
|
|
493
|
-
lunr setup #
|
|
508
|
+
lunr setup # Install Chromium and configure optional features
|
|
509
|
+
lunr browser install # Repair missing Chromium after a skipped/failed install
|
|
494
510
|
lunr features [list|enable|disable]
|
|
495
511
|
lunr gateway […] # Chat gateway daemon (requires chat-platforms feature)
|
|
496
512
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"lunr-browser.d.ts","sourceRoot":"","sources":["../../src/builtin-extensions/lunr-browser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAgD/D","sourcesContent":["import { Text } from \"@ashx-j/lunr-tui\";\nimport type { ExtensionAPI } from \"../core/extensions/types.ts\";\nimport { onBrowserEnabledChange, readBrowserSettings } from \"../core/browser/settings.ts\";\nimport { BROWSER_DESCRIPTION, BrowserParams } from \"../core/browser/schema.ts\";\nimport type { BrowserSession } from \"../core/browser/runtime.ts\";\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(args, theme) {\n\t\t\treturn new Text(theme.fg(\"toolTitle\", `browser ${args.action ?? \"\"}`), 0, 0);\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Text } from "@ashx-j/lunr-tui";
|
|
2
|
+
import { onBrowserEnabledChange, readBrowserSettings } from "../core/browser/settings.js";
|
|
3
|
+
import { BROWSER_DESCRIPTION, BrowserParams } from "../core/browser/schema.js";
|
|
4
|
+
export default function browserExtension(pi) {
|
|
5
|
+
let enabled = readBrowserSettings().enabled;
|
|
6
|
+
let unsubscribe;
|
|
7
|
+
let session;
|
|
8
|
+
let generation = 0;
|
|
9
|
+
const close = async () => {
|
|
10
|
+
generation++;
|
|
11
|
+
const previous = session;
|
|
12
|
+
session = undefined;
|
|
13
|
+
await previous?.close();
|
|
14
|
+
};
|
|
15
|
+
pi.on("session_shutdown", async () => {
|
|
16
|
+
unsubscribe?.();
|
|
17
|
+
unsubscribe = undefined;
|
|
18
|
+
await close();
|
|
19
|
+
});
|
|
20
|
+
pi.on("session_start", async () => {
|
|
21
|
+
await close();
|
|
22
|
+
enabled = readBrowserSettings().enabled;
|
|
23
|
+
unsubscribe?.();
|
|
24
|
+
unsubscribe = onBrowserEnabledChange((value) => {
|
|
25
|
+
enabled = value;
|
|
26
|
+
if (!enabled)
|
|
27
|
+
void close().catch(() => undefined);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
pi.on("agent_end", async (event) => {
|
|
31
|
+
if (event.messages.some((message) => message.role === "assistant" && message.stopReason === "aborted"))
|
|
32
|
+
await close();
|
|
33
|
+
});
|
|
34
|
+
pi.registerTool({
|
|
35
|
+
name: "browser",
|
|
36
|
+
label: "Browser",
|
|
37
|
+
description: BROWSER_DESCRIPTION,
|
|
38
|
+
parameters: BrowserParams,
|
|
39
|
+
async execute(_id, input, signal) {
|
|
40
|
+
if (!enabled) {
|
|
41
|
+
await close();
|
|
42
|
+
throw new Error("Browser is disabled. The user can enable Browser in /settings.");
|
|
43
|
+
}
|
|
44
|
+
const current = generation;
|
|
45
|
+
const { BrowserSession } = await import("../core/browser/runtime.js");
|
|
46
|
+
if (current !== generation || signal?.aborted)
|
|
47
|
+
throw new Error("Browser call cancelled during initialization.");
|
|
48
|
+
session ??= new BrowserSession(readBrowserSettings().allowPrivate);
|
|
49
|
+
return session.run(input, signal);
|
|
50
|
+
},
|
|
51
|
+
renderCall(args, theme) {
|
|
52
|
+
return new Text(theme.fg("toolTitle", `browser ${args.action ?? ""}`), 0, 0);
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//# 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 } from \"../core/extensions/types.ts\";\nimport { onBrowserEnabledChange, readBrowserSettings } from \"../core/browser/settings.ts\";\nimport { BROWSER_DESCRIPTION, BrowserParams } from \"../core/browser/schema.ts\";\nimport type { BrowserSession } from \"../core/browser/runtime.ts\";\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(args, theme) {\n\t\t\treturn new Text(theme.fg(\"toolTitle\", `browser ${args.action ?? \"\"}`), 0, 0);\n\t\t},\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":"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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 { 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"]}
|