@apholdings/jensen-code 0.0.1 → 0.0.2
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 +21 -20
- package/README.md +6 -5
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/file-processor.d.ts +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +2 -2
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +2 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +2 -2
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +2 -2
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -1
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +15 -15
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -3
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +5 -5
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts +3 -3
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +2 -2
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +2 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +2 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/header.d.ts +1 -1
- package/dist/modes/interactive/components/header.d.ts.map +1 -1
- package/dist/modes/interactive/components/header.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +2 -2
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -2
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -2
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +2 -2
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +2 -2
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -3
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +1 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +1 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts +2 -2
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +1 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/top-bar.d.ts +1 -1
- package/dist/modes/interactive/components/top-bar.d.ts.map +1 -1
- package/dist/modes/interactive/components/top-bar.js +1 -1
- package/dist/modes/interactive/components/top-bar.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +2 -2
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +1 -1
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +2 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -2
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/image-resize.d.ts +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/docs/compaction.md +3 -2
- package/docs/custom-provider.md +4 -3
- package/docs/extensions.md +25 -24
- package/docs/packages.md +2 -1
- package/docs/rpc.md +2 -1
- package/docs/sdk.md +25 -24
- package/docs/session.md +2 -1
- package/docs/termux.md +2 -1
- package/docs/tui.md +21 -20
- package/examples/extensions/README.md +3 -2
- package/examples/extensions/antigravity-image-gen.ts +3 -2
- package/examples/extensions/auto-commit-on-exit.ts +2 -1
- package/examples/extensions/bash-spawn-hook.ts +3 -2
- package/examples/extensions/bookmark.ts +2 -1
- package/examples/extensions/built-in-tool-renderer.ts +4 -3
- package/examples/extensions/claude-rules.ts +2 -1
- package/examples/extensions/commands.ts +2 -1
- package/examples/extensions/confirm-destructive.ts +2 -1
- package/examples/extensions/custom-compaction.ts +4 -3
- package/examples/extensions/custom-footer.ts +4 -3
- package/examples/extensions/custom-header.ts +3 -2
- package/examples/extensions/custom-provider-anthropic/index.ts +3 -2
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +3 -2
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +1 -1
- package/examples/extensions/custom-provider-qwen-cli/index.ts +3 -2
- package/examples/extensions/dirty-repo-guard.ts +2 -1
- package/examples/extensions/doom-overlay/doom-component.ts +2 -2
- package/examples/extensions/doom-overlay/doom-keys.ts +1 -1
- package/examples/extensions/doom-overlay/index.ts +2 -1
- package/examples/extensions/dynamic-resources/index.ts +2 -1
- package/examples/extensions/dynamic-tools.ts +2 -1
- package/examples/extensions/event-bus.ts +2 -1
- package/examples/extensions/file-trigger.ts +2 -1
- package/examples/extensions/git-checkpoint.ts +2 -1
- package/examples/extensions/handoff.ts +4 -3
- package/examples/extensions/hello.ts +3 -2
- package/examples/extensions/inline-bash.ts +2 -1
- package/examples/extensions/input-transform.ts +2 -1
- package/examples/extensions/interactive-shell.ts +2 -1
- package/examples/extensions/mac-system-theme.ts +2 -1
- package/examples/extensions/message-renderer.ts +3 -2
- package/examples/extensions/minimal-mode.ts +4 -3
- package/examples/extensions/modal-editor.ts +3 -2
- package/examples/extensions/model-status.ts +2 -1
- package/examples/extensions/notify.ts +2 -1
- package/examples/extensions/overlay-qa-tests.ts +4 -3
- package/examples/extensions/overlay-test.ts +3 -2
- package/examples/extensions/permission-gate.ts +2 -1
- package/examples/extensions/pirate.ts +2 -1
- package/examples/extensions/plan-mode/index.ts +5 -4
- package/examples/extensions/preset.ts +4 -3
- package/examples/extensions/protected-paths.ts +2 -1
- package/examples/extensions/provider-payload.ts +2 -1
- package/examples/extensions/qna.ts +4 -3
- package/examples/extensions/question.ts +3 -2
- package/examples/extensions/questionnaire.ts +3 -2
- package/examples/extensions/rainbow-editor.ts +2 -1
- package/examples/extensions/reload-runtime.ts +2 -1
- package/examples/extensions/rpc-demo.ts +2 -1
- package/examples/extensions/sandbox/index.ts +3 -2
- package/examples/extensions/send-user-message.ts +2 -1
- package/examples/extensions/session-name.ts +2 -1
- package/examples/extensions/shutdown-command.ts +2 -1
- package/examples/extensions/snake.ts +3 -2
- package/examples/extensions/space-invaders.ts +3 -2
- package/examples/extensions/ssh.ts +3 -2
- package/examples/extensions/status-line.ts +2 -1
- package/examples/extensions/subagent/agents.ts +2 -1
- package/examples/extensions/subagent/index.ts +6 -5
- package/examples/extensions/summarize.ts +5 -4
- package/examples/extensions/system-prompt-header.ts +2 -1
- package/examples/extensions/timed-confirm.ts +2 -1
- package/examples/extensions/titlebar-spinner.ts +2 -1
- package/examples/extensions/todo.ts +4 -3
- package/examples/extensions/tool-override.ts +3 -2
- package/examples/extensions/tools.ts +4 -3
- package/examples/extensions/trigger-compact.ts +2 -1
- package/examples/extensions/truncated-tool.ts +4 -3
- package/examples/extensions/widget-placement.ts +2 -1
- package/examples/extensions/with-deps/index.ts +2 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/01-minimal.ts +2 -1
- package/examples/sdk/02-custom-model.ts +3 -2
- package/examples/sdk/03-custom-prompt.ts +2 -1
- package/examples/sdk/04-skills.ts +2 -1
- package/examples/sdk/05-tools.ts +2 -1
- package/examples/sdk/06-extensions.ts +3 -2
- package/examples/sdk/07-context-files.ts +2 -1
- package/examples/sdk/08-prompt-templates.ts +2 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +2 -1
- package/examples/sdk/10-settings.ts +2 -1
- package/examples/sdk/11-sessions.ts +2 -1
- package/examples/sdk/12-full-control.ts +3 -2
- package/examples/sdk/README.md +3 -2
- package/package.json +7 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daxnuts.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/daxnuts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * POWERED BY DAXNUTS - Easter egg for OpenCode + Kimi K2.5\n *\n * A heartfelt tribute to dax (@thdxr) for providing free Kimi K2.5 access via OpenCode.\n */\n\nimport type { Component, TUI } from \"@mariozechner/pi-tui\";\nimport { theme } from \"../theme/theme.js\";\n\n// 32x32 RGB image of dax, hex encoded (3 bytes per pixel)\nconst DAX_HEX =\n\t\"bbbab8b9b9b6b9b8b5bcbbb8b8b7b4b7b5b2b6b5b2b8b7b4b7b6b3b6b4b1bdbcb8bab8b6bbb8b5b8b5b1bbb8b4c2bebbc1bebac0bdbabfbcb9c1bebabfbebbc0bfbcc0bdbabbb8b5c1bfbcbfbcb8bbb9b6bfbcb8c2bfbcc1bfbcbfbbb8bdb9b6b8b7b5b9b8b5b8b8b5b5b5b2b6b5b2b8b7b4b9b8b5b9b8b5b6b5b3bab8b5bcbab7bbb9b6bbb8b5bfb9b5bdb2abbcb0a8beb2aabeb5afbfbab6bebab7c0bfbcbebdbabebbb8c0bdbabfbebbc2bebbbdbab7c3c0bdc3c0bdc1bebbc2bebabfbcb8bab9b6b7b6b3b2b1aeb6b5b2b5b4b1b5b4b2b6b5b2b7b6b4b9b8b6b7b6b3bbbab7b2afaba5988fb49e90b09481b79a88b39683b09583b7a395bfb6b0c0bdbabdbbb8bebcb9c1bfbcc0bebbbdbab7bebbb8c2bfbcc0bdbac0bcb9bdb9b6c0bcb8b5b4b2b4b3b0bab9b6b9b9b6b5b4b1b5b4b1b6b5b3b9b8b5b9b8b6b9b8b6b2aeaa968174a6836eaa856eab846eaf8973ac8973b08f79b18f7ab39786b7a89dbbb3aebfbab6c2c0bdbebcb9bfbdbac3c1bdc2bebbc0bcb9bdb9b6c1bdbabfbbb8b4b3b0b9b8b5b8b7b5b4b3b1b5b4b1b8b7b4b8b7b5bab9b6bbbab7b1afad8c7a719d735ca47860a87d65a98069ae8972ae8c75af8d77aa826ba98067aa8974b39e90b6a79dbbb2adc0bdbac1bfbdbfbbb8c1bdb9bebab6c0bdb9bfbbb8c1bdbab4b2b0b7b6b4b7b6b3b4b2b0bab9b7b6b5b2b6b5b2bab9b6bab9b6958c87977663aa836bac8772b08f7aad8c77b2917db0917db0907cac8971a77d64a87f67ac8972b29887b8a89dbfbab5bfbdbac1bebac0bcb9c0bcb9c0bcb9c1bebabebab7b8b7b4b7b6b4b5b4b1b5b4b2b7b6b3b5b4b2bab9b7bab9b6b4b1ada88f7fad8973ae8d78b19684b19685b29786b69a89b29582b1917daa856ea87e66a97e66ad866ea9826baf9280b8ada6bdbbb8bebab7bfbbb8c1bdbabfbbb8bcb8b4bcb8b5b6b4b2b7b5b3b6b5b2b8b7b4b3b2afb8b7b4b6b5b2b3b2b0b3a59aab856fad8d78b0917eb19886b49b8bb49a89b39785b0917eaf8f7cab866fa77d65a77a61a87d64a9816ab08f79b5a296c1bcb8c3bfbcc2bebbbebab7bfbbb7bdbab6c2bebab8b7b4b7b6b4b6b5b3b7b6b3b6b5b2b9b8b6b4b3b1b6b1acac8f7ca9826bae8f7aaf9583b49c8cb49c8bb79d8cb59987b19380ad8e79ae8c77af8e78ac8771a3775faa826bae8972b39888bbb6b2bebbb8bfbbb8bfbbb8c0bdb9bebbb7c0bdb9b6b5b2b9b8b5b4b3b1b8b7b5b4b3b0b7b6b4b6b5b3b1a7a0aa8772a77d65a88570b49887b19b8d9c887c907a6d987f71aa907faf917daf8e7aad8c78ac8b77a8836ca9836cac8770b49b8abdb6b2c0bcb9c0bdb9bfbbb8bebab7bfbcb9bebab7b9b8b6b5b4b2b9b8b5b8b7b5b8b7b4b7b6b4b5b4b2b3a9a2ad8973a1755da9856fb398858c776a65544b776358725d526e594d9c7f6eb1907ba68672ad8e7aab8771ac856db18f79b3a092beb9b5c1bdbabdb9b5bebab7bfbbb7bebab7bcb9b6b7b6b4b6b6b3b8b7b4b5b4b2b8b6b4b7b6b3b4b3b0b4aba4a6826ba3775fb08e79b19584a88e7daa8e7db29481ad8f7c997e6da38674ac8d79ac8e7aae917f9a7c6a896a599a7c6ab3a398c1bdbabdb9b6bcb8b5bebab6bebab7bdb9b5bdb9b6b5b4b1b7b5b3b5b4b2b7b6b3b7b6b4b3b3b0b3b2b0b4aca5a7846fa97f68ae8f7bae9383b59c8bb2937fae8e79ac8b76af927eaf927eb29683b39885b2988891786a72594c6e594d978d86bdbab7bab7b3c0bcb9c0bcb9bebab7bebbb7bdb9b6b3b2b0b4b3b0b5b4b2b4b4b1b4b3b1b4b3b1b4b3b0b6ada5aa8670a57a62ad8e7ab29b8cb69d8dab856fa9826aa88069ab8771af907db49987b19684b29886b59987b39480b09787b5a9a1bcb8b5bebab7bdb9b5bebab7bfbbb8bfbbb7bbb7b4b3b2afb8b7b5b8b7b5b3b2b0b5b4b2b6b5b3b6b4b1afa299a98975a9826baf907cb39988b49a89af8e7aac8973aa856eaf8c74b1917dae907dac907db39988b29785b49785b7a090b9aca3bfbab7bcb8b5bdb9b6bcb8b4bcb8b5bdb9b5bcb8b4b5b4b2b6b5b3b4b3b0b4b3b0b9b8b5b8b6b4908b88887467aa8f7ea78976ad8973b08b74b59885b69e8eb29888b1917cb1917db1937fae907cb19686b39a8ab29886b59b8ab8a192b6aaa3b7b2afbcb8b4bcb8b5bbb7b4c0bcb9bebab7c0bcb9b6b5b2b6b5b3b4b3b0bab9b7b7b6b4b1b0ae7b716ba083709b806f716158967764b08870b29481b69b8ab69f8fb39a89b69f90b49d8db39a89b29988b49c8cb6a090b8a496baa49593867f8f8986bfbbb7bdb9b5bcb7b4bab6b3b9b5b2bab6b2b4b3b1b3b3b0b6b5b3b8b7b5b4b2b0a7a5a38f837dae917ea084725a504c63544da28370b39784b59e8db2a093a698909b918b998e8790857e95877dad998bb39c8cb5a091b9a2938d827c95908dbebab6bbb7b3bdbab7bbb7b4bdb9b6bbb7b4b4b3b0b5b4b1b8b7b5b6b5b3b8b8b5b4b2af968f8ab29a8bab9485544b483a323073655d96887f70655f61595547403e453e3c453f3d57504f655e5b90847db39c8db7a090b6a09189807aaba6a3bdb9b6c0bcb9bebab7bcb7b4bebab7bbb7b4b3b2b0b6b5b3b2b1afb7b6b4b8b7b4b5b4b1aeaba8b5a89fac998d4d44412d25244d46444e4744322b293a3230423937433a37352d2a59504c534b48524a48988a81b59f8fb19c8d827974b2afacbdb9b5bcb8b4bdb9b5bcb8b5bdb9b6bab6b2b8b7b5b5b4b2b6b6b3b9b8b5b7b6b3b6b5b2b8b6b3b9b4b1b2a9a26c64612d25242d2625312a28352d2c453d3a78675c8d7a6ea09792aea6a0615854332b29524a479f8e82b09d90a49b96c1bdb9bebab7bfbbb8bbb8b4b9b5b1b8b4b0b9b4b0b7b6b4b8b7b5b8b7b4b6b5b3b8b6b3bab9b6b9b8b5b4b3b0b7b5b2a5a29f453d3b261e1d261f1e2e2625413936857268977865b19482b5a69caca5a07c7572453d3b746963a0948cc5bfbbc0bbb8beb9b6bbb7b3bbb6b3b7b3afb8b4b0b9b5b1b7b6b3b6b5b3b5b4b2b5b4b2b7b6b3b7b6b3b8b6b3b4b2afb7b6b3b3b1ae6d6765251f1e1e18172a22212d2523443b3971625ab19888b09482a89182877e792c25243e3634766d6abeb9b5bfbbb7bebab6bcb7b3bbb6b3b9b5b1b7b3afb8b4b0b4b3b0b5b4b1b5b4b1b4b3b1b5b4b2b8b6b4b5b3b0b9b6b4b5b4b1b6b4b27f79762a2322221c1b2d2524221b1a443e3c47413f6f676281766f867971675e5a3e37352a222166605dbab7b3bdb9b5beb9b5bcb7b3bcb7b3b9b4b0bab6b2bab6b2b5b3b0b6b4b2b3b2afb7b6b3b4b4b1b4b3b0b6b4b1b5b4b1b4b3b0b9b6b29a8c8252474230292828201f181212322c2c231e1d1c16162c26252923222d26252d2523332b2a8e8885bcb8b5bcb7b3bbb6b2bcb7b3b9b4b1b9b5b1b7b2afb7b2ae7a838e9b9b9caeadacb3b2b0b3b2afb7b7b4b6b5b3b6b6b3b7b6b3b9ada4a991808e7b6f50453f2b24231a14142923221f19181d17161f18182620201d17162a22215d5654b7b3b0bbb7b3bbb6b2b8b4b0bab5b1bbb6b2bab5b1b8b4b0bab6b22c496b4c5d735f68766e727a828285929090adaba8b7b2aeb6a59ab39682a28470a387748e76674e403a1a14141d1716181211221c1c1f1918221c1b2f2827342d2c8d8884bab6b3b9b5b2bab5b1bab5b1b9b4b0bab6b2b8b4b0b9b4b0b7b2ae325e8b365f8a3a5d833f5b7a545f70646469706b6aa08f84b08e78b18e769f7e689e7f6b9e816d907766584940362d2a1c1615201b1a1a1413201a1a251e1d393331a39e9bbab5b1bcb7b3bab6b2b8b3afb8b4b0b9b4b0b9b4b1bab5b2b5b0ac3d6c9843729d44719c426e98415f805a64716f6a699d8677b1927eb3947faa89749d7a649f7f6ba487749e837186716454463f2c25231e181837302e3a33317a7471beb9b6bcb8b4bbb6b2b6b2aebab5b1b9b5b1b8b3afbab6b2b6b1adb5aeaa4877a14c7aa44e7ba345719a3a5d80586b7f767475927b6eb1927faf8e79b08e78a78169a07861a17f6aa58570a688749b83738270666f66618a8480a49e99b7b2aebab6b2bcb8b4b9b5b1b7b2aebab5b1b9b4b0b6b1aeb6b1adb2aca8b2aca84876a04a78a2517fa74771973a5d80405c7a6161677c695fac8a75b08d77b4917aaf8971ad876fa5816aa6846ea78670a98a76ac9484ab9f96b2aca8bdb8b4bcb7b3bcb8b4bcb8b4b8b3afb7b2aeb9b4b0b8b3afb8b2aeb6afabb3aeaab2aeaa4878a14b7aa34c7ba44a759b3d63873b5f825b67766f5f569c7e6caf8c77b18f79b28f78b5927caf8e78a98872aa8a76a98a76ac917fada199b7b0acb9b3afbfb9b5c1bab6bdb6b2b8b3afbab5b1b9b4b0b6afabb7b1adb3ada9b3aeaab0aba8\";\n\nconst WIDTH = 32;\nconst HEIGHT = 32;\n\nfunction parseImage(): number[][][] {\n\tconst pixels: number[][][] = [];\n\tfor (let y = 0; y < HEIGHT; y++) {\n\t\tconst row: number[][] = [];\n\t\tfor (let x = 0; x < WIDTH; x++) {\n\t\t\tconst idx = (y * WIDTH + x) * 6;\n\t\t\tconst r = parseInt(DAX_HEX.slice(idx, idx + 2), 16);\n\t\t\tconst g = parseInt(DAX_HEX.slice(idx + 2, idx + 4), 16);\n\t\t\tconst b = parseInt(DAX_HEX.slice(idx + 4, idx + 6), 16);\n\t\t\trow.push([r, g, b]);\n\t\t}\n\t\tpixels.push(row);\n\t}\n\treturn pixels;\n}\n\nfunction rgb(r: number, g: number, b: number, bg = false): string {\n\treturn `\\x1b[${bg ? 48 : 38};2;${r};${g};${b}m`;\n}\n\nconst RESET = \"\\x1b[0m\";\n\nfunction buildImage(): string[] {\n\tconst pixels = parseImage();\n\tconst lines: string[] = [];\n\n\t// Use half-block chars: ▄ with bg=top pixel, fg=bottom pixel\n\tfor (let row = 0; row < HEIGHT; row += 2) {\n\t\tlet line = \"\";\n\t\tfor (let x = 0; x < WIDTH; x++) {\n\t\t\tconst top = pixels[row][x];\n\t\t\tconst bottom = pixels[row + 1]?.[x] ?? top;\n\t\t\tline += `${rgb(bottom[0], bottom[1], bottom[2])}${rgb(top[0], top[1], top[2], true)}▄`;\n\t\t}\n\t\tline += RESET;\n\t\tlines.push(line);\n\t}\n\treturn lines;\n}\n\nexport class DaxnutsComponent implements Component {\n\tprivate ui: TUI;\n\tprivate image: string[];\n\tprivate interval: ReturnType<typeof setInterval> | null = null;\n\tprivate tick = 0;\n\tprivate maxTicks = 25; // ~2 seconds at 80ms\n\tprivate cachedLines: string[] = [];\n\tprivate cachedWidth = 0;\n\tprivate cachedTick = -1;\n\n\tconstructor(ui: TUI) {\n\t\tthis.ui = ui;\n\t\tthis.image = buildImage();\n\t\tthis.startAnimation();\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedWidth = 0;\n\t}\n\n\tprivate startAnimation(): void {\n\t\tthis.interval = setInterval(() => {\n\t\t\tthis.tick++;\n\t\t\tif (this.tick >= this.maxTicks) {\n\t\t\t\tthis.stopAnimation();\n\t\t\t}\n\t\t\tthis.cachedWidth = 0;\n\t\t\tthis.ui.requestRender();\n\t\t}, 80);\n\t}\n\n\tprivate stopAnimation(): void {\n\t\tif (this.interval) {\n\t\t\tclearInterval(this.interval);\n\t\t\tthis.interval = null;\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width === this.cachedWidth && this.cachedTick === this.tick) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\tconst t = theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst center = (s: string) => {\n\t\t\tconst visible = s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n\t\t\tconst left = Math.max(0, Math.floor((width - visible) / 2));\n\t\t\treturn \" \".repeat(left) + s;\n\t\t};\n\n\t\tlines.push(\"\");\n\n\t\t// Scanline reveal effect: show rows progressively\n\t\tconst revealedRows = Math.min(\n\t\t\tthis.image.length,\n\t\t\tMath.floor((this.tick / this.maxTicks) * (this.image.length + 3)),\n\t\t);\n\n\t\tfor (let i = 0; i < this.image.length; i++) {\n\t\t\tif (i < revealedRows) {\n\t\t\t\tlines.push(center(this.image[i]));\n\t\t\t} else {\n\t\t\t\t// Show scan line\n\t\t\t\tif (i === revealedRows) {\n\t\t\t\t\tconst scanline = \"▓\".repeat(WIDTH);\n\t\t\t\t\tlines.push(center(rgb(100, 200, 255) + scanline + RESET));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(center(\" \".repeat(WIDTH)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlines.push(\"\");\n\n\t\t// Fade in text after image is revealed\n\t\tconst textPhase = Math.max(0, this.tick - this.maxTicks * 0.6);\n\t\tif (textPhase > 0 || this.tick >= this.maxTicks) {\n\t\t\tlines.push(center(t.fg(\"accent\", \"Free Kimi K2.5 via OpenCode Zen\")));\n\t\t\tlines.push(center(t.fg(\"success\", '\"Powered by daxnuts\"')));\n\t\t\tlines.push(center(t.fg(\"muted\", \"— @thdxr\")));\n\t\t} else {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tif (textPhase > 2 || this.tick >= this.maxTicks) {\n\t\t\tlines.push(center(t.fg(\"dim\", \"Try OpenCode\")));\n\t\t\tlines.push(center(t.fg(\"mdLink\", \"https://mistral.ai/news/mistral-vibe-2-0\")));\n\t\t} else {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tlines.push(\"\");\n\n\t\tthis.cachedLines = lines;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedTick = this.tick;\n\t\treturn lines;\n\t}\n\n\tdispose(): void {\n\t\tthis.stopAnimation();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"daxnuts.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/daxnuts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,0DAA0D;AAC1D,MAAM,OAAO,GACZ,kgMAAkgM,CAAC;AAEpgM,MAAM,KAAK,GAAG,EAAE,CAAC;AACjB,MAAM,MAAM,GAAG,EAAE,CAAC;AAElB,SAAS,UAAU,GAAiB;IACnC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,GAAG,GAAe,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpD,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxD,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE,GAAG,KAAK,EAAU;IACjE,OAAO,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAAA,CAChD;AAED,MAAM,KAAK,GAAG,SAAS,CAAC;AAExB,SAAS,UAAU,GAAa;IAC/B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,+DAA6D;IAC7D,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAC1C,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;YAC3C,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAG,CAAC;QACxF,CAAC;QACD,IAAI,IAAI,KAAK,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,OAAO,gBAAgB;IACpB,EAAE,CAAM;IACR,KAAK,CAAW;IAChB,QAAQ,GAA0C,IAAI,CAAC;IACvD,IAAI,GAAG,CAAC,CAAC;IACT,QAAQ,GAAG,EAAE,CAAC,CAAC,qBAAqB;IACpC,WAAW,GAAa,EAAE,CAAC;IAC3B,WAAW,GAAG,CAAC,CAAC;IAChB,UAAU,GAAG,CAAC,CAAC,CAAC;IAExB,YAAY,EAAO,EAAE;QACpB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,UAAU,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,EAAE,CAAC;IAAA,CACtB;IAED,UAAU,GAAS;QAClB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IAAA,CACrB;IAEO,cAAc,GAAS;QAC9B,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;YACrB,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;QAAA,CACxB,EAAE,EAAE,CAAC,CAAC;IAAA,CACP;IAEO,aAAa,GAAS;QAC7B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACtB,CAAC;IAAA,CACD;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,IAAI,KAAK,KAAK,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YACjE,OAAO,IAAI,CAAC,WAAW,CAAC;QACzB,CAAC;QAED,MAAM,CAAC,GAAG,KAAK,CAAC;QAChB,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;YACxD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAAA,CAC5B,CAAC;QAEF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,kDAAkD;QAClD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EACjB,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CACjE,CAAC;QAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACP,iBAAiB;gBACjB,IAAI,CAAC,KAAK,YAAY,EAAE,CAAC;oBACxB,MAAM,QAAQ,GAAG,KAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACnC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;gBAC3D,CAAC;qBAAM,CAAC;oBACP,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvC,CAAC;YACF,CAAC;QACF,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,uCAAuC;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC;QAC/D,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,iCAAiC,CAAC,CAAC,CAAC,CAAC;YACtE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,YAAU,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,0CAA0C,CAAC,CAAC,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;QAC5B,OAAO,KAAK,CAAC;IAAA,CACb;IAED,OAAO,GAAS;QACf,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;CACD","sourcesContent":["/**\n * POWERED BY DAXNUTS - Easter egg for OpenCode + Kimi K2.5\n *\n * A heartfelt tribute to dax (@thdxr) for providing free Kimi K2.5 access via OpenCode.\n */\n\nimport type { Component, TUI } from \"@apholdings/jensen-tui\";\nimport { theme } from \"../theme/theme.js\";\n\n// 32x32 RGB image of dax, hex encoded (3 bytes per pixel)\nconst DAX_HEX =\n\t\"bbbab8b9b9b6b9b8b5bcbbb8b8b7b4b7b5b2b6b5b2b8b7b4b7b6b3b6b4b1bdbcb8bab8b6bbb8b5b8b5b1bbb8b4c2bebbc1bebac0bdbabfbcb9c1bebabfbebbc0bfbcc0bdbabbb8b5c1bfbcbfbcb8bbb9b6bfbcb8c2bfbcc1bfbcbfbbb8bdb9b6b8b7b5b9b8b5b8b8b5b5b5b2b6b5b2b8b7b4b9b8b5b9b8b5b6b5b3bab8b5bcbab7bbb9b6bbb8b5bfb9b5bdb2abbcb0a8beb2aabeb5afbfbab6bebab7c0bfbcbebdbabebbb8c0bdbabfbebbc2bebbbdbab7c3c0bdc3c0bdc1bebbc2bebabfbcb8bab9b6b7b6b3b2b1aeb6b5b2b5b4b1b5b4b2b6b5b2b7b6b4b9b8b6b7b6b3bbbab7b2afaba5988fb49e90b09481b79a88b39683b09583b7a395bfb6b0c0bdbabdbbb8bebcb9c1bfbcc0bebbbdbab7bebbb8c2bfbcc0bdbac0bcb9bdb9b6c0bcb8b5b4b2b4b3b0bab9b6b9b9b6b5b4b1b5b4b1b6b5b3b9b8b5b9b8b6b9b8b6b2aeaa968174a6836eaa856eab846eaf8973ac8973b08f79b18f7ab39786b7a89dbbb3aebfbab6c2c0bdbebcb9bfbdbac3c1bdc2bebbc0bcb9bdb9b6c1bdbabfbbb8b4b3b0b9b8b5b8b7b5b4b3b1b5b4b1b8b7b4b8b7b5bab9b6bbbab7b1afad8c7a719d735ca47860a87d65a98069ae8972ae8c75af8d77aa826ba98067aa8974b39e90b6a79dbbb2adc0bdbac1bfbdbfbbb8c1bdb9bebab6c0bdb9bfbbb8c1bdbab4b2b0b7b6b4b7b6b3b4b2b0bab9b7b6b5b2b6b5b2bab9b6bab9b6958c87977663aa836bac8772b08f7aad8c77b2917db0917db0907cac8971a77d64a87f67ac8972b29887b8a89dbfbab5bfbdbac1bebac0bcb9c0bcb9c0bcb9c1bebabebab7b8b7b4b7b6b4b5b4b1b5b4b2b7b6b3b5b4b2bab9b7bab9b6b4b1ada88f7fad8973ae8d78b19684b19685b29786b69a89b29582b1917daa856ea87e66a97e66ad866ea9826baf9280b8ada6bdbbb8bebab7bfbbb8c1bdbabfbbb8bcb8b4bcb8b5b6b4b2b7b5b3b6b5b2b8b7b4b3b2afb8b7b4b6b5b2b3b2b0b3a59aab856fad8d78b0917eb19886b49b8bb49a89b39785b0917eaf8f7cab866fa77d65a77a61a87d64a9816ab08f79b5a296c1bcb8c3bfbcc2bebbbebab7bfbbb7bdbab6c2bebab8b7b4b7b6b4b6b5b3b7b6b3b6b5b2b9b8b6b4b3b1b6b1acac8f7ca9826bae8f7aaf9583b49c8cb49c8bb79d8cb59987b19380ad8e79ae8c77af8e78ac8771a3775faa826bae8972b39888bbb6b2bebbb8bfbbb8bfbbb8c0bdb9bebbb7c0bdb9b6b5b2b9b8b5b4b3b1b8b7b5b4b3b0b7b6b4b6b5b3b1a7a0aa8772a77d65a88570b49887b19b8d9c887c907a6d987f71aa907faf917daf8e7aad8c78ac8b77a8836ca9836cac8770b49b8abdb6b2c0bcb9c0bdb9bfbbb8bebab7bfbcb9bebab7b9b8b6b5b4b2b9b8b5b8b7b5b8b7b4b7b6b4b5b4b2b3a9a2ad8973a1755da9856fb398858c776a65544b776358725d526e594d9c7f6eb1907ba68672ad8e7aab8771ac856db18f79b3a092beb9b5c1bdbabdb9b5bebab7bfbbb7bebab7bcb9b6b7b6b4b6b6b3b8b7b4b5b4b2b8b6b4b7b6b3b4b3b0b4aba4a6826ba3775fb08e79b19584a88e7daa8e7db29481ad8f7c997e6da38674ac8d79ac8e7aae917f9a7c6a896a599a7c6ab3a398c1bdbabdb9b6bcb8b5bebab6bebab7bdb9b5bdb9b6b5b4b1b7b5b3b5b4b2b7b6b3b7b6b4b3b3b0b3b2b0b4aca5a7846fa97f68ae8f7bae9383b59c8bb2937fae8e79ac8b76af927eaf927eb29683b39885b2988891786a72594c6e594d978d86bdbab7bab7b3c0bcb9c0bcb9bebab7bebbb7bdb9b6b3b2b0b4b3b0b5b4b2b4b4b1b4b3b1b4b3b1b4b3b0b6ada5aa8670a57a62ad8e7ab29b8cb69d8dab856fa9826aa88069ab8771af907db49987b19684b29886b59987b39480b09787b5a9a1bcb8b5bebab7bdb9b5bebab7bfbbb8bfbbb7bbb7b4b3b2afb8b7b5b8b7b5b3b2b0b5b4b2b6b5b3b6b4b1afa299a98975a9826baf907cb39988b49a89af8e7aac8973aa856eaf8c74b1917dae907dac907db39988b29785b49785b7a090b9aca3bfbab7bcb8b5bdb9b6bcb8b4bcb8b5bdb9b5bcb8b4b5b4b2b6b5b3b4b3b0b4b3b0b9b8b5b8b6b4908b88887467aa8f7ea78976ad8973b08b74b59885b69e8eb29888b1917cb1917db1937fae907cb19686b39a8ab29886b59b8ab8a192b6aaa3b7b2afbcb8b4bcb8b5bbb7b4c0bcb9bebab7c0bcb9b6b5b2b6b5b3b4b3b0bab9b7b7b6b4b1b0ae7b716ba083709b806f716158967764b08870b29481b69b8ab69f8fb39a89b69f90b49d8db39a89b29988b49c8cb6a090b8a496baa49593867f8f8986bfbbb7bdb9b5bcb7b4bab6b3b9b5b2bab6b2b4b3b1b3b3b0b6b5b3b8b7b5b4b2b0a7a5a38f837dae917ea084725a504c63544da28370b39784b59e8db2a093a698909b918b998e8790857e95877dad998bb39c8cb5a091b9a2938d827c95908dbebab6bbb7b3bdbab7bbb7b4bdb9b6bbb7b4b4b3b0b5b4b1b8b7b5b6b5b3b8b8b5b4b2af968f8ab29a8bab9485544b483a323073655d96887f70655f61595547403e453e3c453f3d57504f655e5b90847db39c8db7a090b6a09189807aaba6a3bdb9b6c0bcb9bebab7bcb7b4bebab7bbb7b4b3b2b0b6b5b3b2b1afb7b6b4b8b7b4b5b4b1aeaba8b5a89fac998d4d44412d25244d46444e4744322b293a3230423937433a37352d2a59504c534b48524a48988a81b59f8fb19c8d827974b2afacbdb9b5bcb8b4bdb9b5bcb8b5bdb9b6bab6b2b8b7b5b5b4b2b6b6b3b9b8b5b7b6b3b6b5b2b8b6b3b9b4b1b2a9a26c64612d25242d2625312a28352d2c453d3a78675c8d7a6ea09792aea6a0615854332b29524a479f8e82b09d90a49b96c1bdb9bebab7bfbbb8bbb8b4b9b5b1b8b4b0b9b4b0b7b6b4b8b7b5b8b7b4b6b5b3b8b6b3bab9b6b9b8b5b4b3b0b7b5b2a5a29f453d3b261e1d261f1e2e2625413936857268977865b19482b5a69caca5a07c7572453d3b746963a0948cc5bfbbc0bbb8beb9b6bbb7b3bbb6b3b7b3afb8b4b0b9b5b1b7b6b3b6b5b3b5b4b2b5b4b2b7b6b3b7b6b3b8b6b3b4b2afb7b6b3b3b1ae6d6765251f1e1e18172a22212d2523443b3971625ab19888b09482a89182877e792c25243e3634766d6abeb9b5bfbbb7bebab6bcb7b3bbb6b3b9b5b1b7b3afb8b4b0b4b3b0b5b4b1b5b4b1b4b3b1b5b4b2b8b6b4b5b3b0b9b6b4b5b4b1b6b4b27f79762a2322221c1b2d2524221b1a443e3c47413f6f676281766f867971675e5a3e37352a222166605dbab7b3bdb9b5beb9b5bcb7b3bcb7b3b9b4b0bab6b2bab6b2b5b3b0b6b4b2b3b2afb7b6b3b4b4b1b4b3b0b6b4b1b5b4b1b4b3b0b9b6b29a8c8252474230292828201f181212322c2c231e1d1c16162c26252923222d26252d2523332b2a8e8885bcb8b5bcb7b3bbb6b2bcb7b3b9b4b1b9b5b1b7b2afb7b2ae7a838e9b9b9caeadacb3b2b0b3b2afb7b7b4b6b5b3b6b6b3b7b6b3b9ada4a991808e7b6f50453f2b24231a14142923221f19181d17161f18182620201d17162a22215d5654b7b3b0bbb7b3bbb6b2b8b4b0bab5b1bbb6b2bab5b1b8b4b0bab6b22c496b4c5d735f68766e727a828285929090adaba8b7b2aeb6a59ab39682a28470a387748e76674e403a1a14141d1716181211221c1c1f1918221c1b2f2827342d2c8d8884bab6b3b9b5b2bab5b1bab5b1b9b4b0bab6b2b8b4b0b9b4b0b7b2ae325e8b365f8a3a5d833f5b7a545f70646469706b6aa08f84b08e78b18e769f7e689e7f6b9e816d907766584940362d2a1c1615201b1a1a1413201a1a251e1d393331a39e9bbab5b1bcb7b3bab6b2b8b3afb8b4b0b9b4b0b9b4b1bab5b2b5b0ac3d6c9843729d44719c426e98415f805a64716f6a699d8677b1927eb3947faa89749d7a649f7f6ba487749e837186716454463f2c25231e181837302e3a33317a7471beb9b6bcb8b4bbb6b2b6b2aebab5b1b9b5b1b8b3afbab6b2b6b1adb5aeaa4877a14c7aa44e7ba345719a3a5d80586b7f767475927b6eb1927faf8e79b08e78a78169a07861a17f6aa58570a688749b83738270666f66618a8480a49e99b7b2aebab6b2bcb8b4b9b5b1b7b2aebab5b1b9b4b0b6b1aeb6b1adb2aca8b2aca84876a04a78a2517fa74771973a5d80405c7a6161677c695fac8a75b08d77b4917aaf8971ad876fa5816aa6846ea78670a98a76ac9484ab9f96b2aca8bdb8b4bcb7b3bcb8b4bcb8b4b8b3afb7b2aeb9b4b0b8b3afb8b2aeb6afabb3aeaab2aeaa4878a14b7aa34c7ba44a759b3d63873b5f825b67766f5f569c7e6caf8c77b18f79b28f78b5927caf8e78a98872aa8a76a98a76ac917fada199b7b0acb9b3afbfb9b5c1bab6bdb6b2b8b3afbab5b1b9b4b0b6afabb7b1adb3ada9b3aeaab0aba8\";\n\nconst WIDTH = 32;\nconst HEIGHT = 32;\n\nfunction parseImage(): number[][][] {\n\tconst pixels: number[][][] = [];\n\tfor (let y = 0; y < HEIGHT; y++) {\n\t\tconst row: number[][] = [];\n\t\tfor (let x = 0; x < WIDTH; x++) {\n\t\t\tconst idx = (y * WIDTH + x) * 6;\n\t\t\tconst r = parseInt(DAX_HEX.slice(idx, idx + 2), 16);\n\t\t\tconst g = parseInt(DAX_HEX.slice(idx + 2, idx + 4), 16);\n\t\t\tconst b = parseInt(DAX_HEX.slice(idx + 4, idx + 6), 16);\n\t\t\trow.push([r, g, b]);\n\t\t}\n\t\tpixels.push(row);\n\t}\n\treturn pixels;\n}\n\nfunction rgb(r: number, g: number, b: number, bg = false): string {\n\treturn `\\x1b[${bg ? 48 : 38};2;${r};${g};${b}m`;\n}\n\nconst RESET = \"\\x1b[0m\";\n\nfunction buildImage(): string[] {\n\tconst pixels = parseImage();\n\tconst lines: string[] = [];\n\n\t// Use half-block chars: ▄ with bg=top pixel, fg=bottom pixel\n\tfor (let row = 0; row < HEIGHT; row += 2) {\n\t\tlet line = \"\";\n\t\tfor (let x = 0; x < WIDTH; x++) {\n\t\t\tconst top = pixels[row][x];\n\t\t\tconst bottom = pixels[row + 1]?.[x] ?? top;\n\t\t\tline += `${rgb(bottom[0], bottom[1], bottom[2])}${rgb(top[0], top[1], top[2], true)}▄`;\n\t\t}\n\t\tline += RESET;\n\t\tlines.push(line);\n\t}\n\treturn lines;\n}\n\nexport class DaxnutsComponent implements Component {\n\tprivate ui: TUI;\n\tprivate image: string[];\n\tprivate interval: ReturnType<typeof setInterval> | null = null;\n\tprivate tick = 0;\n\tprivate maxTicks = 25; // ~2 seconds at 80ms\n\tprivate cachedLines: string[] = [];\n\tprivate cachedWidth = 0;\n\tprivate cachedTick = -1;\n\n\tconstructor(ui: TUI) {\n\t\tthis.ui = ui;\n\t\tthis.image = buildImage();\n\t\tthis.startAnimation();\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedWidth = 0;\n\t}\n\n\tprivate startAnimation(): void {\n\t\tthis.interval = setInterval(() => {\n\t\t\tthis.tick++;\n\t\t\tif (this.tick >= this.maxTicks) {\n\t\t\t\tthis.stopAnimation();\n\t\t\t}\n\t\t\tthis.cachedWidth = 0;\n\t\t\tthis.ui.requestRender();\n\t\t}, 80);\n\t}\n\n\tprivate stopAnimation(): void {\n\t\tif (this.interval) {\n\t\t\tclearInterval(this.interval);\n\t\t\tthis.interval = null;\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width === this.cachedWidth && this.cachedTick === this.tick) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\tconst t = theme;\n\t\tconst lines: string[] = [];\n\n\t\tconst center = (s: string) => {\n\t\t\tconst visible = s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n\t\t\tconst left = Math.max(0, Math.floor((width - visible) / 2));\n\t\t\treturn \" \".repeat(left) + s;\n\t\t};\n\n\t\tlines.push(\"\");\n\n\t\t// Scanline reveal effect: show rows progressively\n\t\tconst revealedRows = Math.min(\n\t\t\tthis.image.length,\n\t\t\tMath.floor((this.tick / this.maxTicks) * (this.image.length + 3)),\n\t\t);\n\n\t\tfor (let i = 0; i < this.image.length; i++) {\n\t\t\tif (i < revealedRows) {\n\t\t\t\tlines.push(center(this.image[i]));\n\t\t\t} else {\n\t\t\t\t// Show scan line\n\t\t\t\tif (i === revealedRows) {\n\t\t\t\t\tconst scanline = \"▓\".repeat(WIDTH);\n\t\t\t\t\tlines.push(center(rgb(100, 200, 255) + scanline + RESET));\n\t\t\t\t} else {\n\t\t\t\t\tlines.push(center(\" \".repeat(WIDTH)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlines.push(\"\");\n\n\t\t// Fade in text after image is revealed\n\t\tconst textPhase = Math.max(0, this.tick - this.maxTicks * 0.6);\n\t\tif (textPhase > 0 || this.tick >= this.maxTicks) {\n\t\t\tlines.push(center(t.fg(\"accent\", \"Free Kimi K2.5 via OpenCode Zen\")));\n\t\t\tlines.push(center(t.fg(\"success\", '\"Powered by daxnuts\"')));\n\t\t\tlines.push(center(t.fg(\"muted\", \"— @thdxr\")));\n\t\t} else {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"\");\n\t\t}\n\n\t\tlines.push(\"\");\n\t\tif (textPhase > 2 || this.tick >= this.maxTicks) {\n\t\t\tlines.push(center(t.fg(\"dim\", \"Try OpenCode\")));\n\t\t\tlines.push(center(t.fg(\"mdLink\", \"https://mistral.ai/news/mistral-vibe-2-0\")));\n\t\t} else {\n\t\t\tlines.push(\"\");\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tlines.push(\"\");\n\n\t\tthis.cachedLines = lines;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedTick = this.tick;\n\t\treturn lines;\n\t}\n\n\tdispose(): void {\n\t\tthis.stopAnimation();\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-border.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"dynamic-border.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGxD;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC9C,OAAO,CAAC,KAAK,CAA0B;IAEvC,YAAY,KAAK,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAyC,EAE5E;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9B;CACD","sourcesContent":["import type { Component } from \"@apholdings/jensen-tui\";\nimport { theme } from \"../theme/theme.js\";\n\n/**\n * Dynamic border component that adjusts to viewport width.\n *\n * Note: When used from extensions loaded via jiti, the global `theme` may be undefined\n * because jiti creates a separate module cache. Always pass an explicit color\n * function when using DynamicBorder in components exported for extension use.\n */\nexport class DynamicBorder implements Component {\n\tprivate color: (str: string) => string;\n\n\tconstructor(color: (str: string) => string = (str) => theme.fg(\"border\", str)) {\n\t\tthis.color = color;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\treturn [this.color(\"─\".repeat(Math.max(1, width)))];\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-border.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IACjB,KAAK,CAA0B;IAEvC,YAAY,KAAK,GAA4B,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE;QAC9E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAAA,CACnB;IAED,UAAU,GAAS;QAClB,0CAA0C;IADvB,CAEnB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAAA,CACpD;CACD","sourcesContent":["import type { Component } from \"@
|
|
1
|
+
{"version":3,"file":"dynamic-border.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IACjB,KAAK,CAA0B;IAEvC,YAAY,KAAK,GAA4B,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE;QAC9E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAAA,CACnB;IAED,UAAU,GAAS;QAClB,0CAA0C;IADvB,CAEnB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAAA,CACpD;CACD","sourcesContent":["import type { Component } from \"@apholdings/jensen-tui\";\nimport { theme } from \"../theme/theme.js\";\n\n/**\n * Dynamic border component that adjusts to viewport width.\n *\n * Note: When used from extensions loaded via jiti, the global `theme` may be undefined\n * because jiti creates a separate module cache. Always pass an explicit color\n * function when using DynamicBorder in components exported for extension use.\n */\nexport class DynamicBorder implements Component {\n\tprivate color: (str: string) => string;\n\n\tconstructor(color: (str: string) => string = (str) => theme.fg(\"border\", str)) {\n\t\tthis.color = color;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\treturn [this.color(\"─\".repeat(Math.max(1, width)))];\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Multi-line editor component for extensions.
|
|
3
3
|
* Supports Ctrl+G for external editor.
|
|
4
4
|
*/
|
|
5
|
-
import { Container, type EditorOptions, type Focusable, type TUI } from "@
|
|
5
|
+
import { Container, type EditorOptions, type Focusable, type TUI } from "@apholdings/jensen-tui";
|
|
6
6
|
import type { KeybindingsManager } from "../../../core/keybindings.js";
|
|
7
7
|
export declare class ExtensionEditorComponent extends Container implements Focusable {
|
|
8
8
|
private editor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,SAAS,EAId,KAAK,GAAG,EACR,MAAM,
|
|
1
|
+
{"version":3,"file":"extension-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,SAAS,EAId,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAKvE,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,SAAS;IAC3E,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,WAAW,CAAqB;IAExC,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,CAAC,EAAE,aAAa,EA6CvB;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAgBjC;IAED,OAAO,CAAC,kBAAkB;CAkC1B","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetEditorKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@apholdings/jensen-tui\";\nimport { FILE_PREFIX } from \"../../../config.js\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.js\";\nimport { getEditorTheme, theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { appKeyHint, keyHint } from \"./keybinding-hints.js\";\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: EditorOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create editor\n\t\tthis.editor = new Editor(tui, getEditorTheme(), options);\n\t\tif (prefill) {\n\t\t\tthis.editor.setText(prefill);\n\t\t}\n\t\t// Wire up Enter to submit (Shift+Enter for newlines, like the main editor)\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint\n\t\tconst hasExternalEditor = !!(process.env.VISUAL || process.env.EDITOR);\n\t\tconst hint =\n\t\t\tkeyHint(\"selectConfirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"selectCancel\", \"cancel\") +\n\t\t\t(hasExternalEditor ? ` ${appKeyHint(this.keybindings, \"externalEditor\", \"external editor\")}` : \"\");\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\t// Escape or Ctrl+C to cancel\n\t\tif (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn;\n\t\t}\n\n\t\t// External editor (app keybinding)\n\t\tif (this.keybindings.matches(keyData, \"externalEditor\")) {\n\t\t\tthis.openExternalEditor();\n\t\t\treturn;\n\t\t}\n\n\t\t// Forward to editor\n\t\tthis.editor.handleInput(keyData);\n\t}\n\n\tprivate openExternalEditor(): void {\n\t\tconst editorCmd = process.env.VISUAL || process.env.EDITOR;\n\t\tif (!editorCmd) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentText = this.editor.getText();\n\t\tconst tmpFile = path.join(os.tmpdir(), `${FILE_PREFIX}-extension-editor-${Date.now()}.md`);\n\n\t\ttry {\n\t\t\tfs.writeFileSync(tmpFile, currentText, \"utf-8\");\n\t\t\tthis.tui.stop();\n\n\t\t\tconst [editor, ...editorArgs] = editorCmd.split(\" \");\n\t\t\tconst result = spawnSync(editor, [...editorArgs, tmpFile], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t\tshell: process.platform === \"win32\",\n\t\t\t});\n\n\t\t\tif (result.status === 0) {\n\t\t\t\tconst newContent = fs.readFileSync(tmpFile, \"utf-8\").replace(/\\n$/, \"\");\n\t\t\t\tthis.editor.setText(newContent);\n\t\t\t}\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t} catch {\n\t\t\t\t// Ignore cleanup errors\n\t\t\t}\n\t\t\tthis.tui.start();\n\t\t\t// Force full re-render since external editor uses alternate screen\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -6,7 +6,7 @@ import { spawnSync } from "node:child_process";
|
|
|
6
6
|
import * as fs from "node:fs";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
-
import { Container, Editor, getEditorKeybindings, Spacer, Text, } from "@
|
|
9
|
+
import { Container, Editor, getEditorKeybindings, Spacer, Text, } from "@apholdings/jensen-tui";
|
|
10
10
|
import { FILE_PREFIX } from "../../../config.js";
|
|
11
11
|
import { getEditorTheme, theme } from "../theme/theme.js";
|
|
12
12
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACN,SAAS,EACT,MAAM,EAGN,oBAAoB,EACpB,MAAM,EACN,IAAI,GAEJ,MAAM,
|
|
1
|
+
{"version":3,"file":"extension-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport { spawnSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetEditorKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@apholdings/jensen-tui\";\nimport { FILE_PREFIX } from \"../../../config.js\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.js\";\nimport { getEditorTheme, theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { appKeyHint, keyHint } from \"./keybinding-hints.js\";\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: EditorOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create editor\n\t\tthis.editor = new Editor(tui, getEditorTheme(), options);\n\t\tif (prefill) {\n\t\t\tthis.editor.setText(prefill);\n\t\t}\n\t\t// Wire up Enter to submit (Shift+Enter for newlines, like the main editor)\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint\n\t\tconst hasExternalEditor = !!(process.env.VISUAL || process.env.EDITOR);\n\t\tconst hint =\n\t\t\tkeyHint(\"selectConfirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"selectCancel\", \"cancel\") +\n\t\t\t(hasExternalEditor ? ` ${appKeyHint(this.keybindings, \"externalEditor\", \"external editor\")}` : \"\");\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\t// Escape or Ctrl+C to cancel\n\t\tif (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn;\n\t\t}\n\n\t\t// External editor (app keybinding)\n\t\tif (this.keybindings.matches(keyData, \"externalEditor\")) {\n\t\t\tthis.openExternalEditor();\n\t\t\treturn;\n\t\t}\n\n\t\t// Forward to editor\n\t\tthis.editor.handleInput(keyData);\n\t}\n\n\tprivate openExternalEditor(): void {\n\t\tconst editorCmd = process.env.VISUAL || process.env.EDITOR;\n\t\tif (!editorCmd) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentText = this.editor.getText();\n\t\tconst tmpFile = path.join(os.tmpdir(), `${FILE_PREFIX}-extension-editor-${Date.now()}.md`);\n\n\t\ttry {\n\t\t\tfs.writeFileSync(tmpFile, currentText, \"utf-8\");\n\t\t\tthis.tui.stop();\n\n\t\t\tconst [editor, ...editorArgs] = editorCmd.split(\" \");\n\t\t\tconst result = spawnSync(editor, [...editorArgs, tmpFile], {\n\t\t\t\tstdio: \"inherit\",\n\t\t\t\tshell: process.platform === \"win32\",\n\t\t\t});\n\n\t\t\tif (result.status === 0) {\n\t\t\t\tconst newContent = fs.readFileSync(tmpFile, \"utf-8\").replace(/\\n$/, \"\");\n\t\t\t\tthis.editor.setText(newContent);\n\t\t\t}\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t} catch {\n\t\t\t\t// Ignore cleanup errors\n\t\t\t}\n\t\t\tthis.tui.start();\n\t\t\t// Force full re-render since external editor uses alternate screen\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Simple text input component for extensions.
|
|
3
3
|
*/
|
|
4
|
-
import { Container, type Focusable, type TUI } from "@
|
|
4
|
+
import { Container, type Focusable, type TUI } from "@apholdings/jensen-tui";
|
|
5
5
|
export interface ExtensionInputOptions {
|
|
6
6
|
tui?: TUI;
|
|
7
7
|
timeout?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-input.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-input.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAA6C,KAAK,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"extension-input.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-input.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAA6C,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAMxH,MAAM,WAAW,qBAAqB;IACrC,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,uBAAwB,SAAQ,SAAU,YAAW,SAAS;IAC1E,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA6B;IAG9C,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,IAAI,CAAC,EAAE,qBAAqB,EA8B5B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CASjC;IAED,OAAO,IAAI,IAAI,CAEd;CACD","sourcesContent":["/**\n * Simple text input component for extensions.\n */\n\nimport { Container, type Focusable, getEditorKeybindings, Input, Spacer, Text, type TUI } from \"@apholdings/jensen-tui\";\nimport { theme } from \"../theme/theme.js\";\nimport { CountdownTimer } from \"./countdown-timer.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { keyHint } from \"./keybinding-hints.js\";\n\nexport interface ExtensionInputOptions {\n\ttui?: TUI;\n\ttimeout?: number;\n}\n\nexport class ExtensionInputComponent extends Container implements Focusable {\n\tprivate input: Input;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate titleText: Text;\n\tprivate baseTitle: string;\n\tprivate countdown: CountdownTimer | undefined;\n\n\t// Focusable implementation - propagate to input for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.input.focused = value;\n\t}\n\n\tconstructor(\n\t\ttitle: string,\n\t\t_placeholder: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\topts?: ExtensionInputOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.baseTitle = title;\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.titleText = new Text(theme.fg(\"accent\", title), 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (opts?.timeout && opts.timeout > 0 && opts.tui) {\n\t\t\tthis.countdown = new CountdownTimer(\n\t\t\t\topts.timeout,\n\t\t\t\topts.tui,\n\t\t\t\t(s) => this.titleText.setText(theme.fg(\"accent\", `${this.baseTitle} (${s}s)`)),\n\t\t\t\t() => this.onCancelCallback(),\n\t\t\t);\n\t\t}\n\n\t\tthis.input = new Input();\n\t\tthis.addChild(this.input);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(`${keyHint(\"selectConfirm\", \"submit\")} ${keyHint(\"selectCancel\", \"cancel\")}`, 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\tif (kb.matches(keyData, \"selectConfirm\") || keyData === \"\\n\") {\n\t\t\tthis.onSubmitCallback(this.input.getValue());\n\t\t} else if (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t} else {\n\t\t\tthis.input.handleInput(keyData);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis.countdown?.dispose();\n\t}\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Simple text input component for extensions.
|
|
3
3
|
*/
|
|
4
|
-
import { Container, getEditorKeybindings, Input, Spacer, Text } from "@
|
|
4
|
+
import { Container, getEditorKeybindings, Input, Spacer, Text } from "@apholdings/jensen-tui";
|
|
5
5
|
import { theme } from "../theme/theme.js";
|
|
6
6
|
import { CountdownTimer } from "./countdown-timer.js";
|
|
7
7
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-input.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-input.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAkB,oBAAoB,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"extension-input.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-input.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Simple text input component for extensions.\n */\n\nimport { Container, type Focusable, getEditorKeybindings, Input, Spacer, Text, type TUI } from \"@apholdings/jensen-tui\";\nimport { theme } from \"../theme/theme.js\";\nimport { CountdownTimer } from \"./countdown-timer.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { keyHint } from \"./keybinding-hints.js\";\n\nexport interface ExtensionInputOptions {\n\ttui?: TUI;\n\ttimeout?: number;\n}\n\nexport class ExtensionInputComponent extends Container implements Focusable {\n\tprivate input: Input;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate titleText: Text;\n\tprivate baseTitle: string;\n\tprivate countdown: CountdownTimer | undefined;\n\n\t// Focusable implementation - propagate to input for IME cursor positioning\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.input.focused = value;\n\t}\n\n\tconstructor(\n\t\ttitle: string,\n\t\t_placeholder: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\topts?: ExtensionInputOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.baseTitle = title;\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.titleText = new Text(theme.fg(\"accent\", title), 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (opts?.timeout && opts.timeout > 0 && opts.tui) {\n\t\t\tthis.countdown = new CountdownTimer(\n\t\t\t\topts.timeout,\n\t\t\t\topts.tui,\n\t\t\t\t(s) => this.titleText.setText(theme.fg(\"accent\", `${this.baseTitle} (${s}s)`)),\n\t\t\t\t() => this.onCancelCallback(),\n\t\t\t);\n\t\t}\n\n\t\tthis.input = new Input();\n\t\tthis.addChild(this.input);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(`${keyHint(\"selectConfirm\", \"submit\")} ${keyHint(\"selectCancel\", \"cancel\")}`, 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\tif (kb.matches(keyData, \"selectConfirm\") || keyData === \"\\n\") {\n\t\t\tthis.onSubmitCallback(this.input.getValue());\n\t\t} else if (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t} else {\n\t\t\tthis.input.handleInput(keyData);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis.countdown?.dispose();\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Generic selector component for extensions.
|
|
3
3
|
* Displays a list of string options with keyboard navigation.
|
|
4
4
|
*/
|
|
5
|
-
import { Container, type TUI } from "@
|
|
5
|
+
import { Container, type TUI } from "@apholdings/jensen-tui";
|
|
6
6
|
export interface ExtensionSelectorOptions {
|
|
7
7
|
tui?: TUI;
|
|
8
8
|
timeout?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-selector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAsC,KAAK,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"extension-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-selector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAsC,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAMjG,MAAM,WAAW,wBAAwB;IACxC,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,0BAA2B,SAAQ,SAAS;IACxD,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA6B;IAE9C,YACC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAClC,QAAQ,EAAE,MAAM,IAAI,EACpB,IAAI,CAAC,EAAE,wBAAwB,EA2C/B;IAED,OAAO,CAAC,UAAU;IAWlB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAcjC;IAED,OAAO,IAAI,IAAI,CAEd;CACD","sourcesContent":["/**\n * Generic selector component for extensions.\n * Displays a list of string options with keyboard navigation.\n */\n\nimport { Container, getEditorKeybindings, Spacer, Text, type TUI } from \"@apholdings/jensen-tui\";\nimport { theme } from \"../theme/theme.js\";\nimport { CountdownTimer } from \"./countdown-timer.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.js\";\n\nexport interface ExtensionSelectorOptions {\n\ttui?: TUI;\n\ttimeout?: number;\n}\n\nexport class ExtensionSelectorComponent extends Container {\n\tprivate options: string[];\n\tprivate selectedIndex = 0;\n\tprivate listContainer: Container;\n\tprivate onSelectCallback: (option: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate titleText: Text;\n\tprivate baseTitle: string;\n\tprivate countdown: CountdownTimer | undefined;\n\n\tconstructor(\n\t\ttitle: string,\n\t\toptions: string[],\n\t\tonSelect: (option: string) => void,\n\t\tonCancel: () => void,\n\t\topts?: ExtensionSelectorOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.options = options;\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.baseTitle = title;\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.titleText = new Text(theme.fg(\"accent\", title), 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (opts?.timeout && opts.timeout > 0 && opts.tui) {\n\t\t\tthis.countdown = new CountdownTimer(\n\t\t\t\topts.timeout,\n\t\t\t\topts.tui,\n\t\t\t\t(s) => this.titleText.setText(theme.fg(\"accent\", `${this.baseTitle} (${s}s)`)),\n\t\t\t\t() => this.onCancelCallback(),\n\t\t\t);\n\t\t}\n\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\trawKeyHint(\"↑↓\", \"navigate\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"selectConfirm\", \"select\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"selectCancel\", \"cancel\"),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tthis.updateList();\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\t\tfor (let i = 0; i < this.options.length; i++) {\n\t\t\tconst isSelected = i === this.selectedIndex;\n\t\t\tconst text = isSelected\n\t\t\t\t? theme.fg(\"accent\", \"→ \") + theme.fg(\"accent\", this.options[i])\n\t\t\t\t: ` ${theme.fg(\"text\", this.options[i])}`;\n\t\t\tthis.listContainer.addChild(new Text(text, 1, 0));\n\t\t}\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\tif (kb.matches(keyData, \"selectUp\") || keyData === \"k\") {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.updateList();\n\t\t} else if (kb.matches(keyData, \"selectDown\") || keyData === \"j\") {\n\t\t\tthis.selectedIndex = Math.min(this.options.length - 1, this.selectedIndex + 1);\n\t\t\tthis.updateList();\n\t\t} else if (kb.matches(keyData, \"selectConfirm\") || keyData === \"\\n\") {\n\t\t\tconst selected = this.options[this.selectedIndex];\n\t\t\tif (selected) this.onSelectCallback(selected);\n\t\t} else if (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis.countdown?.dispose();\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Generic selector component for extensions.
|
|
3
3
|
* Displays a list of string options with keyboard navigation.
|
|
4
4
|
*/
|
|
5
|
-
import { Container, getEditorKeybindings, Spacer, Text } from "@
|
|
5
|
+
import { Container, getEditorKeybindings, Spacer, Text } from "@apholdings/jensen-tui";
|
|
6
6
|
import { theme } from "../theme/theme.js";
|
|
7
7
|
import { CountdownTimer } from "./countdown-timer.js";
|
|
8
8
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-selector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,EAAE,IAAI,EAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"extension-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-selector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generic selector component for extensions.\n * Displays a list of string options with keyboard navigation.\n */\n\nimport { Container, getEditorKeybindings, Spacer, Text, type TUI } from \"@apholdings/jensen-tui\";\nimport { theme } from \"../theme/theme.js\";\nimport { CountdownTimer } from \"./countdown-timer.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { keyHint, rawKeyHint } from \"./keybinding-hints.js\";\n\nexport interface ExtensionSelectorOptions {\n\ttui?: TUI;\n\ttimeout?: number;\n}\n\nexport class ExtensionSelectorComponent extends Container {\n\tprivate options: string[];\n\tprivate selectedIndex = 0;\n\tprivate listContainer: Container;\n\tprivate onSelectCallback: (option: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate titleText: Text;\n\tprivate baseTitle: string;\n\tprivate countdown: CountdownTimer | undefined;\n\n\tconstructor(\n\t\ttitle: string,\n\t\toptions: string[],\n\t\tonSelect: (option: string) => void,\n\t\tonCancel: () => void,\n\t\topts?: ExtensionSelectorOptions,\n\t) {\n\t\tsuper();\n\n\t\tthis.options = options;\n\t\tthis.onSelectCallback = onSelect;\n\t\tthis.onCancelCallback = onCancel;\n\t\tthis.baseTitle = title;\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.titleText = new Text(theme.fg(\"accent\", title), 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (opts?.timeout && opts.timeout > 0 && opts.tui) {\n\t\t\tthis.countdown = new CountdownTimer(\n\t\t\t\topts.timeout,\n\t\t\t\topts.tui,\n\t\t\t\t(s) => this.titleText.setText(theme.fg(\"accent\", `${this.baseTitle} (${s}s)`)),\n\t\t\t\t() => this.onCancelCallback(),\n\t\t\t);\n\t\t}\n\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(\n\t\t\tnew Text(\n\t\t\t\trawKeyHint(\"↑↓\", \"navigate\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"selectConfirm\", \"select\") +\n\t\t\t\t\t\" \" +\n\t\t\t\t\tkeyHint(\"selectCancel\", \"cancel\"),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\n\t\tthis.updateList();\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\t\tfor (let i = 0; i < this.options.length; i++) {\n\t\t\tconst isSelected = i === this.selectedIndex;\n\t\t\tconst text = isSelected\n\t\t\t\t? theme.fg(\"accent\", \"→ \") + theme.fg(\"accent\", this.options[i])\n\t\t\t\t: ` ${theme.fg(\"text\", this.options[i])}`;\n\t\t\tthis.listContainer.addChild(new Text(text, 1, 0));\n\t\t}\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getEditorKeybindings();\n\t\tif (kb.matches(keyData, \"selectUp\") || keyData === \"k\") {\n\t\t\tthis.selectedIndex = Math.max(0, this.selectedIndex - 1);\n\t\t\tthis.updateList();\n\t\t} else if (kb.matches(keyData, \"selectDown\") || keyData === \"j\") {\n\t\t\tthis.selectedIndex = Math.min(this.options.length - 1, this.selectedIndex + 1);\n\t\t\tthis.updateList();\n\t\t} else if (kb.matches(keyData, \"selectConfirm\") || keyData === \"\\n\") {\n\t\t\tconst selected = this.options[this.selectedIndex];\n\t\t\tif (selected) this.onSelectCallback(selected);\n\t\t} else if (kb.matches(keyData, \"selectCancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tthis.countdown?.dispose();\n\t}\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Component } from "@
|
|
1
|
+
import { type Component } from "@apholdings/jensen-tui";
|
|
2
2
|
import type { AgentSession } from "../../../core/agent-session.js";
|
|
3
3
|
import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.js";
|
|
4
4
|
export declare class FooterComponent implements Component {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,wBAAwB,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAwExF,qBAAa,eAAgB,YAAW,SAAS;IAK/C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IALnB,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAyB;IAEzC,YACS,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B,EAC3C;IAEJ,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5C;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,OAAO,IAAI,IAAI,CAEd;IAED,OAAO,CAAC,UAAU;IAuDlB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,wBAAwB;IAMhC,OAAO,CAAC,sBAAsB;IAQ9B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAwF9B;CACD","sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { type Component, truncateToWidth, visibleWidth } from \"@apholdings/jensen-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { theme } from \"../theme/theme.js\";\n\ntype GitInfo = {\n\tinGitRepo: boolean;\n\trepoName?: string;\n\tbranch?: string;\n\tdirty?: boolean;\n};\n\ntype GitCache = {\n\tcwd: string;\n\tinfo: GitInfo;\n\tfetchedAt: number;\n};\n\nconst GIT_CACHE_TTL_MS = 5000;\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\nfunction formatTokenCount(value: number): string {\n\tif (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n\tif (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`;\n\treturn String(value);\n}\n\nfunction shortenPath(input: string): string {\n\tconst home = os.homedir();\n\tlet p = input;\n\n\tif (home && p.startsWith(home)) {\n\t\tp = `~${p.slice(home.length)}`;\n\t}\n\n\tif (p === \"/\") return \"/\";\n\n\tconst parts = p.split(\"/\").filter(Boolean);\n\tif (parts.length <= 4) return p;\n\n\tconst tail = parts.slice(-3).join(\"/\");\n\treturn p.startsWith(\"~\") ? `~/…/${tail}` : `/…/${tail}`;\n}\n\nfunction shortenPathForWidth(input: string, maxWidth: number): string {\n\tif (maxWidth <= 0) return \"\";\n\n\tconst base = shortenPath(input);\n\tif (visibleWidth(base) <= maxWidth) return base;\n\n\tconst root = base.startsWith(\"~\") ? \"~/\" : \"/\";\n\tconst parts = base.replace(/^~?\\//, \"\").split(\"/\").filter(Boolean);\n\tif (parts.length === 0) return truncateToWidth(base, maxWidth, \"...\");\n\n\tconst compactParts = parts.map((part, i) => (i === parts.length - 1 ? part : (part[0] ?? part)));\n\tconst compact = `${root}${compactParts.join(\"/\")}`;\n\tif (visibleWidth(compact) <= maxWidth) return compact;\n\n\tconst tailOnly = `${root}…/${parts[parts.length - 1]}`;\n\tif (visibleWidth(tailOnly) <= maxWidth) return tailOnly;\n\n\treturn truncateToWidth(tailOnly, maxWidth, \"...\");\n}\n\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate gitCache: GitCache | null = null;\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.gitCache = null;\n\t}\n\n\tdispose(): void {\n\t\tthis.gitCache = null;\n\t}\n\n\tprivate getGitInfo(cwd: string): GitInfo {\n\t\tconst now = Date.now();\n\t\tif (this.gitCache?.cwd === cwd && now - this.gitCache.fetchedAt < GIT_CACHE_TTL_MS) {\n\t\t\treturn this.gitCache.info;\n\t\t}\n\n\t\tconst providerBranch = this.footerData.getGitBranch();\n\n\t\ttry {\n\t\t\tconst repoRoot = execFileSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n\t\t\t\tcwd,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\ttimeout: 500,\n\t\t\t}).trim();\n\n\t\t\tif (!repoRoot) {\n\t\t\t\tconst fallbackInfo = providerBranch ? { inGitRepo: true, branch: providerBranch } : { inGitRepo: false };\n\t\t\t\tthis.gitCache = { cwd, info: fallbackInfo, fetchedAt: now };\n\t\t\t\treturn fallbackInfo;\n\t\t\t}\n\n\t\t\tconst branch =\n\t\t\t\tproviderBranch ||\n\t\t\t\texecFileSync(\"git\", [\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], {\n\t\t\t\t\tcwd,\n\t\t\t\t\tencoding: \"utf8\",\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\t\ttimeout: 500,\n\t\t\t\t}).trim() ||\n\t\t\t\tundefined;\n\n\t\t\tconst porcelain = execFileSync(\"git\", [\"status\", \"--porcelain\", \"-uno\"], {\n\t\t\t\tcwd,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\ttimeout: 500,\n\t\t\t}).trim();\n\n\t\t\tconst info: GitInfo = {\n\t\t\t\tinGitRepo: true,\n\t\t\t\trepoName: path.basename(repoRoot),\n\t\t\t\tbranch,\n\t\t\t\tdirty: porcelain.length > 0,\n\t\t\t};\n\n\t\t\tthis.gitCache = { cwd, info, fetchedAt: now };\n\t\t\treturn info;\n\t\t} catch {\n\t\t\tconst fallbackInfo = providerBranch ? { inGitRepo: true, branch: providerBranch } : { inGitRepo: false };\n\t\t\tthis.gitCache = { cwd, info: fallbackInfo, fetchedAt: now };\n\t\t\treturn fallbackInfo;\n\t\t}\n\t}\n\n\tprivate getContextTokens(): string {\n\t\tconst usage = this.session.getContextUsage();\n\t\tif (!usage || usage.tokens == null) return \"--\";\n\n\t\tconst contextWindow =\n\t\t\ttypeof usage.contextWindow === \"number\"\n\t\t\t\t? usage.contextWindow\n\t\t\t\t: (this.session.state.model?.contextWindow ?? null);\n\n\t\tif (contextWindow == null) {\n\t\t\treturn formatTokenCount(usage.tokens);\n\t\t}\n\n\t\treturn `${formatTokenCount(usage.tokens)}/${formatTokenCount(contextWindow)}`;\n\t}\n\n\tprivate getContextPercentValue(): number | null {\n\t\tconst usage = this.session.getContextUsage();\n\t\tif (!usage || usage.percent == null) return null;\n\t\treturn usage.percent;\n\t}\n\n\tprivate getContextPercentDisplay(): string {\n\t\tconst percent = this.getContextPercentValue();\n\t\tif (percent == null) return \"--\";\n\t\treturn `${percent.toFixed(1)}%${this.autoCompactEnabled ? \" (auto)\" : \"\"}`;\n\t}\n\n\tprivate getContextPercentColor(): \"success\" | \"warning\" | \"error\" {\n\t\tconst percent = this.getContextPercentValue();\n\t\tif (percent == null) return \"success\";\n\t\tif (percent > 90) return \"error\";\n\t\tif (percent > 70) return \"warning\";\n\t\treturn \"success\";\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [\"\"];\n\n\t\tconst cwd = process.cwd();\n\t\tconst git = this.getGitInfo(cwd);\n\t\tconst separator = theme.fg(\"dim\", \" · \");\n\n\t\tlet cwdLabel = shortenPath(cwd);\n\n\t\tconst leftMetaParts: string[] = [\n\t\t\ttheme.fg(\"dim\", \"host \") + theme.fg(\"muted\", `${os.userInfo().username}@${os.hostname()}`),\n\t\t];\n\n\t\tif (git.inGitRepo) {\n\t\t\tif (git.repoName) {\n\t\t\t\tleftMetaParts.push(theme.fg(\"dim\", \"repo \") + theme.fg(\"toolTitle\", git.repoName));\n\t\t\t}\n\t\t\tif (git.branch) {\n\t\t\t\tconst branchDisplay = git.dirty ? `${git.branch}*` : git.branch;\n\t\t\t\tleftMetaParts.push(\n\t\t\t\t\ttheme.fg(\"dim\", \"branch \") + theme.fg(git.dirty ? \"warning\" : \"borderAccent\", branchDisplay),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst rightParts = [\n\t\t\ttheme.fg(\"dim\", \"tok \") + theme.fg(\"success\", this.getContextTokens()),\n\t\t\ttheme.fg(\"dim\", \"ctx \") + theme.fg(this.getContextPercentColor(), this.getContextPercentDisplay()),\n\t\t];\n\n\t\tconst ellipsis = theme.fg(\"dim\", \"...\");\n\t\tconst minGap = 1;\n\n\t\tlet right = `${rightParts.join(separator)} `;\n\t\tlet left = ` ${theme.fg(\"accent\", cwdLabel)}${\n\t\t\tleftMetaParts.length > 0 ? separator + leftMetaParts.join(separator) : \"\"\n\t\t}`;\n\n\t\tconst leftWidth = visibleWidth(left);\n\t\tconst rightWidth = visibleWidth(right);\n\t\tlet footerLine: string;\n\n\t\tif (leftWidth + minGap + rightWidth <= width) {\n\t\t\tconst gap = Math.max(minGap, width - leftWidth - rightWidth);\n\t\t\tfooterLine = left + \" \".repeat(gap) + right;\n\t\t} else {\n\t\t\tconst maxRight = Math.max(12, Math.floor(width * 0.55));\n\t\t\tright = truncateToWidth(right, Math.min(rightWidth, maxRight), ellipsis);\n\n\t\t\tconst rightFitWidth = visibleWidth(right);\n\t\t\tconst availableLeft = Math.max(0, width - minGap - rightFitWidth);\n\n\t\t\tif (availableLeft > 0) {\n\t\t\t\tconst meta = leftMetaParts.length > 0 ? separator + leftMetaParts.join(separator) : \"\";\n\t\t\t\tconst fixedLeftWidth = visibleWidth(` ${meta}`);\n\t\t\t\tconst cwdBudget = Math.max(1, availableLeft - fixedLeftWidth);\n\n\t\t\t\tcwdLabel = shortenPathForWidth(cwd, cwdBudget);\n\t\t\t\tleft = ` ${theme.fg(\"accent\", cwdLabel)}${meta}`;\n\t\t\t\tleft = truncateToWidth(left, availableLeft, ellipsis);\n\t\t\t} else {\n\t\t\t\tleft = \"\";\n\t\t\t}\n\n\t\t\tconst leftFitWidth = visibleWidth(left);\n\n\t\t\tif (leftFitWidth === 0) {\n\t\t\t\tfooterLine = truncateToWidth(right, width, ellipsis);\n\t\t\t} else {\n\t\t\t\tconst gap = Math.max(minGap, width - leftFitWidth - rightFitWidth);\n\t\t\t\tfooterLine = left + \" \".repeat(gap) + right;\n\t\t\t}\n\t\t}\n\n\t\tfooterLine = truncateToWidth(footerLine, width, ellipsis);\n\t\tconst lines = [footerLine];\n\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { truncateToWidth, visibleWidth } from "@
|
|
4
|
+
import { truncateToWidth, visibleWidth } from "@apholdings/jensen-tui";
|
|
5
5
|
import { theme } from "../theme/theme.js";
|
|
6
6
|
const GIT_CACHE_TTL_MS = 5000;
|
|
7
7
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { type Component, truncateToWidth, visibleWidth } from \"@mariozechner/pi-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { theme } from \"../theme/theme.js\";\n\ntype GitInfo = {\n\tinGitRepo: boolean;\n\trepoName?: string;\n\tbranch?: string;\n\tdirty?: boolean;\n};\n\ntype GitCache = {\n\tcwd: string;\n\tinfo: GitInfo;\n\tfetchedAt: number;\n};\n\nconst GIT_CACHE_TTL_MS = 5000;\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\nfunction formatTokenCount(value: number): string {\n\tif (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n\tif (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`;\n\treturn String(value);\n}\n\nfunction shortenPath(input: string): string {\n\tconst home = os.homedir();\n\tlet p = input;\n\n\tif (home && p.startsWith(home)) {\n\t\tp = `~${p.slice(home.length)}`;\n\t}\n\n\tif (p === \"/\") return \"/\";\n\n\tconst parts = p.split(\"/\").filter(Boolean);\n\tif (parts.length <= 4) return p;\n\n\tconst tail = parts.slice(-3).join(\"/\");\n\treturn p.startsWith(\"~\") ? `~/…/${tail}` : `/…/${tail}`;\n}\n\nfunction shortenPathForWidth(input: string, maxWidth: number): string {\n\tif (maxWidth <= 0) return \"\";\n\n\tconst base = shortenPath(input);\n\tif (visibleWidth(base) <= maxWidth) return base;\n\n\tconst root = base.startsWith(\"~\") ? \"~/\" : \"/\";\n\tconst parts = base.replace(/^~?\\//, \"\").split(\"/\").filter(Boolean);\n\tif (parts.length === 0) return truncateToWidth(base, maxWidth, \"...\");\n\n\tconst compactParts = parts.map((part, i) => (i === parts.length - 1 ? part : (part[0] ?? part)));\n\tconst compact = `${root}${compactParts.join(\"/\")}`;\n\tif (visibleWidth(compact) <= maxWidth) return compact;\n\n\tconst tailOnly = `${root}…/${parts[parts.length - 1]}`;\n\tif (visibleWidth(tailOnly) <= maxWidth) return tailOnly;\n\n\treturn truncateToWidth(tailOnly, maxWidth, \"...\");\n}\n\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate gitCache: GitCache | null = null;\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.gitCache = null;\n\t}\n\n\tdispose(): void {\n\t\tthis.gitCache = null;\n\t}\n\n\tprivate getGitInfo(cwd: string): GitInfo {\n\t\tconst now = Date.now();\n\t\tif (this.gitCache?.cwd === cwd && now - this.gitCache.fetchedAt < GIT_CACHE_TTL_MS) {\n\t\t\treturn this.gitCache.info;\n\t\t}\n\n\t\tconst providerBranch = this.footerData.getGitBranch();\n\n\t\ttry {\n\t\t\tconst repoRoot = execFileSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n\t\t\t\tcwd,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\ttimeout: 500,\n\t\t\t}).trim();\n\n\t\t\tif (!repoRoot) {\n\t\t\t\tconst fallbackInfo = providerBranch ? { inGitRepo: true, branch: providerBranch } : { inGitRepo: false };\n\t\t\t\tthis.gitCache = { cwd, info: fallbackInfo, fetchedAt: now };\n\t\t\t\treturn fallbackInfo;\n\t\t\t}\n\n\t\t\tconst branch =\n\t\t\t\tproviderBranch ||\n\t\t\t\texecFileSync(\"git\", [\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], {\n\t\t\t\t\tcwd,\n\t\t\t\t\tencoding: \"utf8\",\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\t\ttimeout: 500,\n\t\t\t\t}).trim() ||\n\t\t\t\tundefined;\n\n\t\t\tconst porcelain = execFileSync(\"git\", [\"status\", \"--porcelain\", \"-uno\"], {\n\t\t\t\tcwd,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\ttimeout: 500,\n\t\t\t}).trim();\n\n\t\t\tconst info: GitInfo = {\n\t\t\t\tinGitRepo: true,\n\t\t\t\trepoName: path.basename(repoRoot),\n\t\t\t\tbranch,\n\t\t\t\tdirty: porcelain.length > 0,\n\t\t\t};\n\n\t\t\tthis.gitCache = { cwd, info, fetchedAt: now };\n\t\t\treturn info;\n\t\t} catch {\n\t\t\tconst fallbackInfo = providerBranch ? { inGitRepo: true, branch: providerBranch } : { inGitRepo: false };\n\t\t\tthis.gitCache = { cwd, info: fallbackInfo, fetchedAt: now };\n\t\t\treturn fallbackInfo;\n\t\t}\n\t}\n\n\tprivate getContextTokens(): string {\n\t\tconst usage = this.session.getContextUsage();\n\t\tif (!usage || usage.tokens == null) return \"--\";\n\n\t\tconst contextWindow =\n\t\t\ttypeof usage.contextWindow === \"number\"\n\t\t\t\t? usage.contextWindow\n\t\t\t\t: (this.session.state.model?.contextWindow ?? null);\n\n\t\tif (contextWindow == null) {\n\t\t\treturn formatTokenCount(usage.tokens);\n\t\t}\n\n\t\treturn `${formatTokenCount(usage.tokens)}/${formatTokenCount(contextWindow)}`;\n\t}\n\n\tprivate getContextPercentValue(): number | null {\n\t\tconst usage = this.session.getContextUsage();\n\t\tif (!usage || usage.percent == null) return null;\n\t\treturn usage.percent;\n\t}\n\n\tprivate getContextPercentDisplay(): string {\n\t\tconst percent = this.getContextPercentValue();\n\t\tif (percent == null) return \"--\";\n\t\treturn `${percent.toFixed(1)}%${this.autoCompactEnabled ? \" (auto)\" : \"\"}`;\n\t}\n\n\tprivate getContextPercentColor(): \"success\" | \"warning\" | \"error\" {\n\t\tconst percent = this.getContextPercentValue();\n\t\tif (percent == null) return \"success\";\n\t\tif (percent > 90) return \"error\";\n\t\tif (percent > 70) return \"warning\";\n\t\treturn \"success\";\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [\"\"];\n\n\t\tconst cwd = process.cwd();\n\t\tconst git = this.getGitInfo(cwd);\n\t\tconst separator = theme.fg(\"dim\", \" · \");\n\n\t\tlet cwdLabel = shortenPath(cwd);\n\n\t\tconst leftMetaParts: string[] = [\n\t\t\ttheme.fg(\"dim\", \"host \") + theme.fg(\"muted\", `${os.userInfo().username}@${os.hostname()}`),\n\t\t];\n\n\t\tif (git.inGitRepo) {\n\t\t\tif (git.repoName) {\n\t\t\t\tleftMetaParts.push(theme.fg(\"dim\", \"repo \") + theme.fg(\"toolTitle\", git.repoName));\n\t\t\t}\n\t\t\tif (git.branch) {\n\t\t\t\tconst branchDisplay = git.dirty ? `${git.branch}*` : git.branch;\n\t\t\t\tleftMetaParts.push(\n\t\t\t\t\ttheme.fg(\"dim\", \"branch \") + theme.fg(git.dirty ? \"warning\" : \"borderAccent\", branchDisplay),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst rightParts = [\n\t\t\ttheme.fg(\"dim\", \"tok \") + theme.fg(\"success\", this.getContextTokens()),\n\t\t\ttheme.fg(\"dim\", \"ctx \") + theme.fg(this.getContextPercentColor(), this.getContextPercentDisplay()),\n\t\t];\n\n\t\tconst ellipsis = theme.fg(\"dim\", \"...\");\n\t\tconst minGap = 1;\n\n\t\tlet right = `${rightParts.join(separator)} `;\n\t\tlet left = ` ${theme.fg(\"accent\", cwdLabel)}${\n\t\t\tleftMetaParts.length > 0 ? separator + leftMetaParts.join(separator) : \"\"\n\t\t}`;\n\n\t\tconst leftWidth = visibleWidth(left);\n\t\tconst rightWidth = visibleWidth(right);\n\t\tlet footerLine: string;\n\n\t\tif (leftWidth + minGap + rightWidth <= width) {\n\t\t\tconst gap = Math.max(minGap, width - leftWidth - rightWidth);\n\t\t\tfooterLine = left + \" \".repeat(gap) + right;\n\t\t} else {\n\t\t\tconst maxRight = Math.max(12, Math.floor(width * 0.55));\n\t\t\tright = truncateToWidth(right, Math.min(rightWidth, maxRight), ellipsis);\n\n\t\t\tconst rightFitWidth = visibleWidth(right);\n\t\t\tconst availableLeft = Math.max(0, width - minGap - rightFitWidth);\n\n\t\t\tif (availableLeft > 0) {\n\t\t\t\tconst meta = leftMetaParts.length > 0 ? separator + leftMetaParts.join(separator) : \"\";\n\t\t\t\tconst fixedLeftWidth = visibleWidth(` ${meta}`);\n\t\t\t\tconst cwdBudget = Math.max(1, availableLeft - fixedLeftWidth);\n\n\t\t\t\tcwdLabel = shortenPathForWidth(cwd, cwdBudget);\n\t\t\t\tleft = ` ${theme.fg(\"accent\", cwdLabel)}${meta}`;\n\t\t\t\tleft = truncateToWidth(left, availableLeft, ellipsis);\n\t\t\t} else {\n\t\t\t\tleft = \"\";\n\t\t\t}\n\n\t\t\tconst leftFitWidth = visibleWidth(left);\n\n\t\t\tif (leftFitWidth === 0) {\n\t\t\t\tfooterLine = truncateToWidth(right, width, ellipsis);\n\t\t\t} else {\n\t\t\t\tconst gap = Math.max(minGap, width - leftFitWidth - rightFitWidth);\n\t\t\t\tfooterLine = left + \" \".repeat(gap) + right;\n\t\t\t}\n\t\t}\n\n\t\tfooterLine = truncateToWidth(footerLine, width, ellipsis);\n\t\tconst lines = [footerLine];\n\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"footer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { type Component, truncateToWidth, visibleWidth } from \"@apholdings/jensen-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { theme } from \"../theme/theme.js\";\n\ntype GitInfo = {\n\tinGitRepo: boolean;\n\trepoName?: string;\n\tbranch?: string;\n\tdirty?: boolean;\n};\n\ntype GitCache = {\n\tcwd: string;\n\tinfo: GitInfo;\n\tfetchedAt: number;\n};\n\nconst GIT_CACHE_TTL_MS = 5000;\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\nfunction formatTokenCount(value: number): string {\n\tif (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n\tif (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`;\n\treturn String(value);\n}\n\nfunction shortenPath(input: string): string {\n\tconst home = os.homedir();\n\tlet p = input;\n\n\tif (home && p.startsWith(home)) {\n\t\tp = `~${p.slice(home.length)}`;\n\t}\n\n\tif (p === \"/\") return \"/\";\n\n\tconst parts = p.split(\"/\").filter(Boolean);\n\tif (parts.length <= 4) return p;\n\n\tconst tail = parts.slice(-3).join(\"/\");\n\treturn p.startsWith(\"~\") ? `~/…/${tail}` : `/…/${tail}`;\n}\n\nfunction shortenPathForWidth(input: string, maxWidth: number): string {\n\tif (maxWidth <= 0) return \"\";\n\n\tconst base = shortenPath(input);\n\tif (visibleWidth(base) <= maxWidth) return base;\n\n\tconst root = base.startsWith(\"~\") ? \"~/\" : \"/\";\n\tconst parts = base.replace(/^~?\\//, \"\").split(\"/\").filter(Boolean);\n\tif (parts.length === 0) return truncateToWidth(base, maxWidth, \"...\");\n\n\tconst compactParts = parts.map((part, i) => (i === parts.length - 1 ? part : (part[0] ?? part)));\n\tconst compact = `${root}${compactParts.join(\"/\")}`;\n\tif (visibleWidth(compact) <= maxWidth) return compact;\n\n\tconst tailOnly = `${root}…/${parts[parts.length - 1]}`;\n\tif (visibleWidth(tailOnly) <= maxWidth) return tailOnly;\n\n\treturn truncateToWidth(tailOnly, maxWidth, \"...\");\n}\n\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate gitCache: GitCache | null = null;\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.gitCache = null;\n\t}\n\n\tdispose(): void {\n\t\tthis.gitCache = null;\n\t}\n\n\tprivate getGitInfo(cwd: string): GitInfo {\n\t\tconst now = Date.now();\n\t\tif (this.gitCache?.cwd === cwd && now - this.gitCache.fetchedAt < GIT_CACHE_TTL_MS) {\n\t\t\treturn this.gitCache.info;\n\t\t}\n\n\t\tconst providerBranch = this.footerData.getGitBranch();\n\n\t\ttry {\n\t\t\tconst repoRoot = execFileSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n\t\t\t\tcwd,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\ttimeout: 500,\n\t\t\t}).trim();\n\n\t\t\tif (!repoRoot) {\n\t\t\t\tconst fallbackInfo = providerBranch ? { inGitRepo: true, branch: providerBranch } : { inGitRepo: false };\n\t\t\t\tthis.gitCache = { cwd, info: fallbackInfo, fetchedAt: now };\n\t\t\t\treturn fallbackInfo;\n\t\t\t}\n\n\t\t\tconst branch =\n\t\t\t\tproviderBranch ||\n\t\t\t\texecFileSync(\"git\", [\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], {\n\t\t\t\t\tcwd,\n\t\t\t\t\tencoding: \"utf8\",\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\t\ttimeout: 500,\n\t\t\t\t}).trim() ||\n\t\t\t\tundefined;\n\n\t\t\tconst porcelain = execFileSync(\"git\", [\"status\", \"--porcelain\", \"-uno\"], {\n\t\t\t\tcwd,\n\t\t\t\tencoding: \"utf8\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t\ttimeout: 500,\n\t\t\t}).trim();\n\n\t\t\tconst info: GitInfo = {\n\t\t\t\tinGitRepo: true,\n\t\t\t\trepoName: path.basename(repoRoot),\n\t\t\t\tbranch,\n\t\t\t\tdirty: porcelain.length > 0,\n\t\t\t};\n\n\t\t\tthis.gitCache = { cwd, info, fetchedAt: now };\n\t\t\treturn info;\n\t\t} catch {\n\t\t\tconst fallbackInfo = providerBranch ? { inGitRepo: true, branch: providerBranch } : { inGitRepo: false };\n\t\t\tthis.gitCache = { cwd, info: fallbackInfo, fetchedAt: now };\n\t\t\treturn fallbackInfo;\n\t\t}\n\t}\n\n\tprivate getContextTokens(): string {\n\t\tconst usage = this.session.getContextUsage();\n\t\tif (!usage || usage.tokens == null) return \"--\";\n\n\t\tconst contextWindow =\n\t\t\ttypeof usage.contextWindow === \"number\"\n\t\t\t\t? usage.contextWindow\n\t\t\t\t: (this.session.state.model?.contextWindow ?? null);\n\n\t\tif (contextWindow == null) {\n\t\t\treturn formatTokenCount(usage.tokens);\n\t\t}\n\n\t\treturn `${formatTokenCount(usage.tokens)}/${formatTokenCount(contextWindow)}`;\n\t}\n\n\tprivate getContextPercentValue(): number | null {\n\t\tconst usage = this.session.getContextUsage();\n\t\tif (!usage || usage.percent == null) return null;\n\t\treturn usage.percent;\n\t}\n\n\tprivate getContextPercentDisplay(): string {\n\t\tconst percent = this.getContextPercentValue();\n\t\tif (percent == null) return \"--\";\n\t\treturn `${percent.toFixed(1)}%${this.autoCompactEnabled ? \" (auto)\" : \"\"}`;\n\t}\n\n\tprivate getContextPercentColor(): \"success\" | \"warning\" | \"error\" {\n\t\tconst percent = this.getContextPercentValue();\n\t\tif (percent == null) return \"success\";\n\t\tif (percent > 90) return \"error\";\n\t\tif (percent > 70) return \"warning\";\n\t\treturn \"success\";\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [\"\"];\n\n\t\tconst cwd = process.cwd();\n\t\tconst git = this.getGitInfo(cwd);\n\t\tconst separator = theme.fg(\"dim\", \" · \");\n\n\t\tlet cwdLabel = shortenPath(cwd);\n\n\t\tconst leftMetaParts: string[] = [\n\t\t\ttheme.fg(\"dim\", \"host \") + theme.fg(\"muted\", `${os.userInfo().username}@${os.hostname()}`),\n\t\t];\n\n\t\tif (git.inGitRepo) {\n\t\t\tif (git.repoName) {\n\t\t\t\tleftMetaParts.push(theme.fg(\"dim\", \"repo \") + theme.fg(\"toolTitle\", git.repoName));\n\t\t\t}\n\t\t\tif (git.branch) {\n\t\t\t\tconst branchDisplay = git.dirty ? `${git.branch}*` : git.branch;\n\t\t\t\tleftMetaParts.push(\n\t\t\t\t\ttheme.fg(\"dim\", \"branch \") + theme.fg(git.dirty ? \"warning\" : \"borderAccent\", branchDisplay),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst rightParts = [\n\t\t\ttheme.fg(\"dim\", \"tok \") + theme.fg(\"success\", this.getContextTokens()),\n\t\t\ttheme.fg(\"dim\", \"ctx \") + theme.fg(this.getContextPercentColor(), this.getContextPercentDisplay()),\n\t\t];\n\n\t\tconst ellipsis = theme.fg(\"dim\", \"...\");\n\t\tconst minGap = 1;\n\n\t\tlet right = `${rightParts.join(separator)} `;\n\t\tlet left = ` ${theme.fg(\"accent\", cwdLabel)}${\n\t\t\tleftMetaParts.length > 0 ? separator + leftMetaParts.join(separator) : \"\"\n\t\t}`;\n\n\t\tconst leftWidth = visibleWidth(left);\n\t\tconst rightWidth = visibleWidth(right);\n\t\tlet footerLine: string;\n\n\t\tif (leftWidth + minGap + rightWidth <= width) {\n\t\t\tconst gap = Math.max(minGap, width - leftWidth - rightWidth);\n\t\t\tfooterLine = left + \" \".repeat(gap) + right;\n\t\t} else {\n\t\t\tconst maxRight = Math.max(12, Math.floor(width * 0.55));\n\t\t\tright = truncateToWidth(right, Math.min(rightWidth, maxRight), ellipsis);\n\n\t\t\tconst rightFitWidth = visibleWidth(right);\n\t\t\tconst availableLeft = Math.max(0, width - minGap - rightFitWidth);\n\n\t\t\tif (availableLeft > 0) {\n\t\t\t\tconst meta = leftMetaParts.length > 0 ? separator + leftMetaParts.join(separator) : \"\";\n\t\t\t\tconst fixedLeftWidth = visibleWidth(` ${meta}`);\n\t\t\t\tconst cwdBudget = Math.max(1, availableLeft - fixedLeftWidth);\n\n\t\t\t\tcwdLabel = shortenPathForWidth(cwd, cwdBudget);\n\t\t\t\tleft = ` ${theme.fg(\"accent\", cwdLabel)}${meta}`;\n\t\t\t\tleft = truncateToWidth(left, availableLeft, ellipsis);\n\t\t\t} else {\n\t\t\t\tleft = \"\";\n\t\t\t}\n\n\t\t\tconst leftFitWidth = visibleWidth(left);\n\n\t\t\tif (leftFitWidth === 0) {\n\t\t\t\tfooterLine = truncateToWidth(right, width, ellipsis);\n\t\t\t} else {\n\t\t\t\tconst gap = Math.max(minGap, width - leftFitWidth - rightFitWidth);\n\t\t\t\tfooterLine = left + \" \".repeat(gap) + right;\n\t\t\t}\n\t\t}\n\n\t\tfooterLine = truncateToWidth(footerLine, width, ellipsis);\n\t\tconst lines = [footerLine];\n\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Component } from "@
|
|
1
|
+
import type { Component } from "@apholdings/jensen-tui";
|
|
2
2
|
import type { ExtensionAPI } from "../../../core/extensions/index.js";
|
|
3
3
|
export declare class Header implements Component {
|
|
4
4
|
render(width: number): string[];
|