gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.f55d16d13
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/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/github-sync/templates.js +39 -8
- package/dist/resources/extensions/gsd/auto/loop.js +16 -9
- package/dist/resources/extensions/gsd/auto/phases.js +37 -30
- package/dist/resources/extensions/gsd/auto/run-unit.js +19 -15
- package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
- package/dist/resources/extensions/gsd/auto-dispatch.js +10 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +10 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +111 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +154 -8
- package/dist/resources/extensions/gsd/auto-start.js +2 -3
- package/dist/resources/extensions/gsd/auto.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +15 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +42 -4
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
- package/dist/resources/extensions/gsd/db-base-schema.js +14 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +16 -0
- package/dist/resources/extensions/gsd/detection.js +106 -0
- package/dist/resources/extensions/gsd/graph.js +9 -3
- package/dist/resources/extensions/gsd/gsd-db.js +102 -2
- package/dist/resources/extensions/gsd/guided-flow.js +2 -2
- package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
- package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
- package/package.json +10 -6
- package/packages/contracts/package.json +1 -1
- package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
- package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/fake-model.js +27 -0
- package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/index.js +8 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
- package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/fake.js +319 -0
- package/packages/pi-ai/dist/providers/fake.js.map +1 -0
- package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
- package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
- package/packages/pi-ai/src/models/fake-model.ts +30 -0
- package/packages/pi-ai/src/models/index.ts +9 -0
- package/packages/pi-ai/src/providers/fake.ts +376 -0
- package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +74 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +14 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +97 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +106 -17
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +60 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +40 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +23 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +87 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +108 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +16 -1
- package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +12 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +118 -17
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +43 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +25 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
- package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/index.d.ts +1 -0
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +2 -0
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/style.d.ts +41 -0
- package/packages/pi-tui/dist/style.d.ts.map +1 -0
- package/packages/pi-tui/dist/style.js +158 -0
- package/packages/pi-tui/dist/style.js.map +1 -0
- package/packages/pi-tui/dist/tui.d.ts +0 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +3 -8
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
- package/packages/pi-tui/src/index.ts +9 -0
- package/packages/pi-tui/src/style.ts +225 -0
- package/packages/pi-tui/src/tui.ts +3 -8
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +18 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +36 -27
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/github-sync/templates.ts +38 -8
- package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +17 -10
- package/src/resources/extensions/gsd/auto/phases.ts +42 -28
- package/src/resources/extensions/gsd/auto/run-unit.ts +24 -14
- package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
- package/src/resources/extensions/gsd/auto-dispatch.ts +17 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +10 -10
- package/src/resources/extensions/gsd/auto-prompts.ts +116 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +153 -7
- package/src/resources/extensions/gsd/auto-start.ts +7 -6
- package/src/resources/extensions/gsd/auto.ts +12 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
- package/src/resources/extensions/gsd/clean-root-preflight.ts +41 -3
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
- package/src/resources/extensions/gsd/db-base-schema.ts +15 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +17 -0
- package/src/resources/extensions/gsd/detection.ts +128 -0
- package/src/resources/extensions/gsd/graph.ts +12 -5
- package/src/resources/extensions/gsd/gsd-db.ts +119 -1
- package/src/resources/extensions/gsd/guided-flow.ts +2 -2
- package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +84 -5
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +170 -1
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +88 -2
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +112 -6
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
- package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
- package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +46 -2
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
- package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
- package/packages/contracts/tsconfig.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → mPZbi5BH9dwokaPZlrYuQ}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → mPZbi5BH9dwokaPZlrYuQ}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/style.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// GSD2 - Tests for terminal style primitives
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { describe, test } from "node:test";
|
|
4
|
+
import stripAnsi from "strip-ansi";
|
|
5
|
+
import { style, visibleWidth } from "../index.js";
|
|
6
|
+
describe("style", () => {
|
|
7
|
+
test("renders rule frames with title, right title, and body gutter", () => {
|
|
8
|
+
const lines = style()
|
|
9
|
+
.border("rule")
|
|
10
|
+
.title("• Tool Bash")
|
|
11
|
+
.titleRight("Running")
|
|
12
|
+
.render(["$ npm test"], 40);
|
|
13
|
+
const plain = lines.map((line) => stripAnsi(line));
|
|
14
|
+
assert.match(plain[0], /^─+$/);
|
|
15
|
+
assert.equal(visibleWidth(plain[0]), 40);
|
|
16
|
+
assert.ok(plain[1].includes("• Tool Bash"));
|
|
17
|
+
assert.ok(plain[1].includes("Running"));
|
|
18
|
+
assert.equal(visibleWidth(plain[1]), 40);
|
|
19
|
+
assert.ok(plain[2].startsWith("│ "));
|
|
20
|
+
assert.ok(plain[2].includes("$ npm test"));
|
|
21
|
+
});
|
|
22
|
+
test("renders boxed rounded borders with padded content", () => {
|
|
23
|
+
const lines = style()
|
|
24
|
+
.border("rounded")
|
|
25
|
+
.paddingX(1)
|
|
26
|
+
.render(["Done"], 12)
|
|
27
|
+
.map((line) => stripAnsi(line));
|
|
28
|
+
assert.equal(lines[0], "╭──────────╮");
|
|
29
|
+
assert.equal(lines[1], "│ Done │");
|
|
30
|
+
assert.equal(lines[2], "╰──────────╯");
|
|
31
|
+
});
|
|
32
|
+
test("truncates content to the available visible width", () => {
|
|
33
|
+
const plain = style().border("rule").render(["abcdefghij"], 7).map((line) => stripAnsi(line));
|
|
34
|
+
assert.equal(plain[1], "│ abcde");
|
|
35
|
+
assert.equal(visibleWidth(plain[1]), 7);
|
|
36
|
+
});
|
|
37
|
+
test("renders minimal left-rule surfaces", () => {
|
|
38
|
+
const plain = style().border("minimal").title("note").render(["No full card"], 20).map((line) => stripAnsi(line));
|
|
39
|
+
assert.equal(plain[0], "│ note ");
|
|
40
|
+
assert.equal(plain[1], "│ No full card ");
|
|
41
|
+
});
|
|
42
|
+
test("applies dashboard density and body gutters", () => {
|
|
43
|
+
const plain = style()
|
|
44
|
+
.border("single")
|
|
45
|
+
.density("dashboard")
|
|
46
|
+
.bodyGutter("· ")
|
|
47
|
+
.render(["body"], 14)
|
|
48
|
+
.map((line) => stripAnsi(line));
|
|
49
|
+
assert.equal(plain[0], "┌────────────┐");
|
|
50
|
+
assert.equal(plain[1], "│ │");
|
|
51
|
+
assert.equal(plain[2], "│· body │");
|
|
52
|
+
assert.equal(plain[3], "│ │");
|
|
53
|
+
assert.equal(plain[4], "└────────────┘");
|
|
54
|
+
});
|
|
55
|
+
test("passes tone to toneColor when no explicit border color is set", () => {
|
|
56
|
+
const lines = style()
|
|
57
|
+
.border("minimal")
|
|
58
|
+
.tone("success", (tone, text) => `[${tone}]${text}`)
|
|
59
|
+
.render(["ok"], 8);
|
|
60
|
+
assert.equal(lines[0], "[success]│ ok ");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=style.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.test.js","sourceRoot":"","sources":["../../src/__tests__/style.test.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD2 - Tests for terminal style primitives\n\nimport assert from \"node:assert/strict\";\nimport { describe, test } from \"node:test\";\nimport stripAnsi from \"strip-ansi\";\n\nimport { style, visibleWidth } from \"../index.js\";\n\ndescribe(\"style\", () => {\n\ttest(\"renders rule frames with title, right title, and body gutter\", () => {\n\t\tconst lines = style()\n\t\t\t.border(\"rule\")\n\t\t\t.title(\"• Tool Bash\")\n\t\t\t.titleRight(\"Running\")\n\t\t\t.render([\"$ npm test\"], 40);\n\n\t\tconst plain = lines.map((line) => stripAnsi(line));\n\t\tassert.match(plain[0], /^─+$/);\n\t\tassert.equal(visibleWidth(plain[0]), 40);\n\t\tassert.ok(plain[1].includes(\"• Tool Bash\"));\n\t\tassert.ok(plain[1].includes(\"Running\"));\n\t\tassert.equal(visibleWidth(plain[1]), 40);\n\t\tassert.ok(plain[2].startsWith(\"│ \"));\n\t\tassert.ok(plain[2].includes(\"$ npm test\"));\n\t});\n\n\ttest(\"renders boxed rounded borders with padded content\", () => {\n\t\tconst lines = style()\n\t\t\t.border(\"rounded\")\n\t\t\t.paddingX(1)\n\t\t\t.render([\"Done\"], 12)\n\t\t\t.map((line) => stripAnsi(line));\n\n\t\tassert.equal(lines[0], \"╭──────────╮\");\n\t\tassert.equal(lines[1], \"│ Done │\");\n\t\tassert.equal(lines[2], \"╰──────────╯\");\n\t});\n\n\ttest(\"truncates content to the available visible width\", () => {\n\t\tconst plain = style().border(\"rule\").render([\"abcdefghij\"], 7).map((line) => stripAnsi(line));\n\n\t\tassert.equal(plain[1], \"│ abcde\");\n\t\tassert.equal(visibleWidth(plain[1]), 7);\n\t});\n\n\ttest(\"renders minimal left-rule surfaces\", () => {\n\t\tconst plain = style().border(\"minimal\").title(\"note\").render([\"No full card\"], 20).map((line) => stripAnsi(line));\n\n\t\tassert.equal(plain[0], \"│ note \");\n\t\tassert.equal(plain[1], \"│ No full card \");\n\t});\n\n\ttest(\"applies dashboard density and body gutters\", () => {\n\t\tconst plain = style()\n\t\t\t.border(\"single\")\n\t\t\t.density(\"dashboard\")\n\t\t\t.bodyGutter(\"· \")\n\t\t\t.render([\"body\"], 14)\n\t\t\t.map((line) => stripAnsi(line));\n\n\t\tassert.equal(plain[0], \"┌────────────┐\");\n\t\tassert.equal(plain[1], \"│ │\");\n\t\tassert.equal(plain[2], \"│· body │\");\n\t\tassert.equal(plain[3], \"│ │\");\n\t\tassert.equal(plain[4], \"└────────────┘\");\n\t});\n\n\ttest(\"passes tone to toneColor when no explicit border color is set\", () => {\n\t\tconst lines = style()\n\t\t\t.border(\"minimal\")\n\t\t\t.tone(\"success\", (tone, text) => `[${tone}]${text}`)\n\t\t\t.render([\"ok\"], 8);\n\n\t\tassert.equal(lines[0], \"[success]│ ok \");\n\t});\n});\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
// GSD-2 + packages/pi-tui/src/__tests__/tui.test.ts - Regression coverage for the TUI renderer and container lifecycle.
|
|
1
2
|
import assert from "node:assert/strict";
|
|
2
3
|
import { describe, it } from "node:test";
|
|
3
|
-
import { Container, TUI } from "../tui.js";
|
|
4
|
-
function makeTerminal() {
|
|
4
|
+
import { Container, CURSOR_MARKER, TUI } from "../tui.js";
|
|
5
|
+
function makeTerminal(writes) {
|
|
5
6
|
return {
|
|
6
7
|
isTTY: true,
|
|
7
8
|
columns: 80,
|
|
@@ -10,7 +11,9 @@ function makeTerminal() {
|
|
|
10
11
|
start() { },
|
|
11
12
|
stop() { },
|
|
12
13
|
drainInput: async () => { },
|
|
13
|
-
write() {
|
|
14
|
+
write(data) {
|
|
15
|
+
writes?.push(data);
|
|
16
|
+
},
|
|
14
17
|
moveBy() { },
|
|
15
18
|
hideCursor() { },
|
|
16
19
|
showCursor() { },
|
|
@@ -39,6 +42,24 @@ function makeTerminal() {
|
|
|
39
42
|
// extracting the debounce decision into a pure helper) — deferred to a
|
|
40
43
|
// separate refactor PR rather than shipping a tautology. See #4794.
|
|
41
44
|
describe("TUI", () => {
|
|
45
|
+
it("updates an editor line from the real hardware cursor row", () => {
|
|
46
|
+
const writes = [];
|
|
47
|
+
const terminal = makeTerminal(writes);
|
|
48
|
+
let value = "input";
|
|
49
|
+
const tui = new TUI(terminal);
|
|
50
|
+
tui.addChild({
|
|
51
|
+
render: () => ["top", `${value}${CURSOR_MARKER}`, " GSD No project loaded - run /gsd to start"],
|
|
52
|
+
invalidate() { },
|
|
53
|
+
});
|
|
54
|
+
const anyTui = tui;
|
|
55
|
+
anyTui.doRender();
|
|
56
|
+
const writeCountAfterFirstRender = writes.length;
|
|
57
|
+
value = "input x";
|
|
58
|
+
anyTui.doRender();
|
|
59
|
+
const renderWrite = writes[writeCountAfterFirstRender];
|
|
60
|
+
assert.ok(renderWrite.startsWith("\x1b[?2026h\r"), "editor diff should start at the current cursor row");
|
|
61
|
+
assert.ok(!renderWrite.startsWith("\x1b[?2026h\x1b[1A\r"), "editor diff must not move above the cursor row");
|
|
62
|
+
});
|
|
42
63
|
it("does not swallow a bare Escape keypress while waiting for the cell-size response", () => {
|
|
43
64
|
const tui = new TUI(makeTerminal());
|
|
44
65
|
const received = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.test.js","sourceRoot":"","sources":["../../src/__tests__/tui.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"tui.test.js","sourceRoot":"","sources":["../../src/__tests__/tui.test.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD-2 + packages/pi-tui/src/__tests__/tui.test.ts - Regression coverage for the TUI renderer and container lifecycle.\n\nimport assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\n\nimport { Container, CURSOR_MARKER, TUI } from \"../tui.js\";\nimport type { Component } from \"../tui.js\";\nimport type { Terminal } from \"../terminal.js\";\n\nfunction makeTerminal(writes?: string[]): Terminal {\n\treturn {\n\t\tisTTY: true,\n\t\tcolumns: 80,\n\t\trows: 24,\n\t\tkittyProtocolActive: false,\n\t\tstart() {},\n\t\tstop() {},\n\t\tdrainInput: async () => {},\n\t\twrite(data: string) {\n\t\t\twrites?.push(data);\n\t\t},\n\t\tmoveBy() {},\n\t\thideCursor() {},\n\t\tshowCursor() {},\n\t\tclearLine() {},\n\t\tclearFromCursor() {},\n\t\tclearScreen() {},\n\t\tsetTitle() {},\n\t};\n}\n\n// TUI clearOnShrink debounce — tests removed in #4794 (ref #4784).\n//\n// The previous tests mutated private fields (`_shrinkDebounceActive`,\n// `maxLinesRendered`) and then asserted the values they just wrote —\n// pure tautologies that never exercised the real debounce path in\n// `renderNow()` (tui.ts:734-754). A regression that narrowed the\n// condition, reversed the flag flip, or dropped the \"keep\n// maxLinesRendered\" rule would have passed all of them.\n//\n// A proper test would (a) render a component that produces N lines to\n// establish `maxLinesRendered`, (b) swap in a component that produces\n// N-k lines to trigger the shrink branch, and (c) observe terminal\n// writes to confirm the debounce defers/commits the full redraw on the\n// expected render call.\n//\n// That test setup requires exposing enough of the render path (or\n// extracting the debounce decision into a pure helper) — deferred to a\n// separate refactor PR rather than shipping a tautology. See #4794.\n\ndescribe(\"TUI\", () => {\n\tit(\"updates an editor line from the real hardware cursor row\", () => {\n\t\tconst writes: string[] = [];\n\t\tconst terminal = makeTerminal(writes);\n\t\tlet value = \"input\";\n\t\tconst tui = new TUI(terminal);\n\t\ttui.addChild({\n\t\t\trender: () => [\"top\", `${value}${CURSOR_MARKER}`, \" GSD No project loaded - run /gsd to start\"],\n\t\t\tinvalidate() {},\n\t\t});\n\t\tconst anyTui = tui as any;\n\n\t\tanyTui.doRender();\n\t\tconst writeCountAfterFirstRender = writes.length;\n\n\t\tvalue = \"input x\";\n\t\tanyTui.doRender();\n\n\t\tconst renderWrite = writes[writeCountAfterFirstRender];\n\t\tassert.ok(renderWrite.startsWith(\"\\x1b[?2026h\\r\"), \"editor diff should start at the current cursor row\");\n\t\tassert.ok(!renderWrite.startsWith(\"\\x1b[?2026h\\x1b[1A\\r\"), \"editor diff must not move above the cursor row\");\n\t});\n\n\tit(\"does not swallow a bare Escape keypress while waiting for the cell-size response\", () => {\n\t\tconst tui = new TUI(makeTerminal());\n\t\tconst received: string[] = [];\n\n\t\ttui.setFocus({\n\t\t\trender: () => [],\n\t\t\thandleInput: (data: string) => {\n\t\t\t\treceived.push(data);\n\t\t\t},\n\t\t\tinvalidate() {},\n\t\t});\n\n\t\tconst anyTui = tui as any;\n\t\tanyTui.cellSizeQueryPending = true;\n\t\tanyTui.inputBuffer = \"\";\n\n\t\tanyTui.handleInput(\"\\x1b\");\n\n\t\tassert.deepEqual(received, [\"\\x1b\"]);\n\t\tassert.equal(anyTui.cellSizeQueryPending, false);\n\t\tassert.equal(anyTui.inputBuffer, \"\");\n\t});\n});\n\ndescribe(\"Container\", () => {\n\tfunction makeDisposableChild(counter: { disposed: number }): Component & { dispose(): void } {\n\t\treturn {\n\t\t\trender: () => [],\n\t\t\tinvalidate() {},\n\t\t\tdispose() {\n\t\t\t\tcounter.disposed++;\n\t\t\t},\n\t\t};\n\t}\n\n\tit(\"detachChildren() removes children without disposing them\", () => {\n\t\tconst c = new Container();\n\t\tconst counter = { disposed: 0 };\n\t\tc.addChild(makeDisposableChild(counter));\n\t\tc.addChild(makeDisposableChild(counter));\n\n\t\tc.detachChildren();\n\n\t\tassert.equal(c.children.length, 0);\n\t\tassert.equal(counter.disposed, 0);\n\t});\n\n\tit(\"clear() still disposes children (regression guard for detach/dispose split)\", () => {\n\t\tconst c = new Container();\n\t\tconst counter = { disposed: 0 };\n\t\tc.addChild(makeDisposableChild(counter));\n\t\tc.addChild(makeDisposableChild(counter));\n\n\t\tc.clear();\n\n\t\tassert.equal(c.children.length, 0);\n\t\tassert.equal(counter.disposed, 2);\n\t});\n});\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { style, TerminalStyle, type TerminalBorderStyle, type TerminalDensity, type TerminalStyleSpec, type TerminalTone, } from "./style.js";
|
|
1
2
|
export { type AutocompleteItem, type AutocompleteProvider, CombinedAutocompleteProvider, type SlashCommand, } from "./autocomplete.js";
|
|
2
3
|
export { Box } from "./components/box.js";
|
|
3
4
|
export { CancellableLoader } from "./components/cancellable-loader.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,4BAA4B,EAC5B,KAAK,YAAY,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,gBAAgB,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAE,KAAK,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EACN,0BAA0B,EAC1B,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EACH,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEnG,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,EACN,eAAe,EACf,KAAK,cAAc,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,oBAAoB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,aAAa,EACb,KAAK,SAAS,EACd,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,GAAG,GACH,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,KAAK,EACL,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,4BAA4B,EAC5B,KAAK,YAAY,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,gBAAgB,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAE,KAAK,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EACN,0BAA0B,EAC1B,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EACH,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEnG,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,EACN,eAAe,EACf,KAAK,cAAc,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,oBAAoB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,KAAK,SAAS,EACd,SAAS,EACT,aAAa,EACb,KAAK,SAAS,EACd,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,GAAG,GACH,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,uBAAuB;AACvB,OAAO,EAGN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAyB,QAAQ,EAAsB,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAmB,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,0BAA0B,EAG1B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAC;AAC/D,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAIlB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAMX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.js\";\n// Components\nexport { Box } from \"./components/box.js\";\nexport { CancellableLoader } from \"./components/cancellable-loader.js\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.js\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.js\";\nexport { Input } from \"./components/input.js\";\nexport { Loader } from \"./components/loader.js\";\nexport { type DefaultTextStyle, Markdown, type MarkdownTheme } from \"./components/markdown.js\";\nexport { type SelectItem, SelectList, type SelectListTheme } from \"./components/select-list.js\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.js\";\nexport { Spacer } from \"./components/spacer.js\";\nexport { Text } from \"./components/text.js\";\nexport { TruncatedText } from \"./components/truncated-text.js\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.js\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.js\";\n// Keybindings\nexport {\n\tDEFAULT_EDITOR_KEYBINDINGS,\n\ttype EditorAction,\n\ttype EditorKeybindingsConfig,\n\tEditorKeybindingsManager,\n\tgetEditorKeybindings,\n\tsetEditorKeybindings,\n} from \"./keybindings.js\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.js\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.js\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.js\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetImageDimensions,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.js\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.js\";\n// Utilities\nexport { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"./utils.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,mBAAmB;AACnB,OAAO,EACN,KAAK,EACL,aAAa,GAKb,MAAM,YAAY,CAAC;AACpB,uBAAuB;AACvB,OAAO,EAGN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAyB,QAAQ,EAAsB,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAmB,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,0BAA0B,EAG1B,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAC;AAC/D,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAIlB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAMX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Style primitives\nexport {\n\tstyle,\n\tTerminalStyle,\n\ttype TerminalBorderStyle,\n\ttype TerminalDensity,\n\ttype TerminalStyleSpec,\n\ttype TerminalTone,\n} from \"./style.js\";\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.js\";\n// Components\nexport { Box } from \"./components/box.js\";\nexport { CancellableLoader } from \"./components/cancellable-loader.js\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.js\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.js\";\nexport { Input } from \"./components/input.js\";\nexport { Loader } from \"./components/loader.js\";\nexport { type DefaultTextStyle, Markdown, type MarkdownTheme } from \"./components/markdown.js\";\nexport { type SelectItem, SelectList, type SelectListTheme } from \"./components/select-list.js\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.js\";\nexport { Spacer } from \"./components/spacer.js\";\nexport { Text } from \"./components/text.js\";\nexport { TruncatedText } from \"./components/truncated-text.js\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.js\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.js\";\n// Keybindings\nexport {\n\tDEFAULT_EDITOR_KEYBINDINGS,\n\ttype EditorAction,\n\ttype EditorKeybindingsConfig,\n\tEditorKeybindingsManager,\n\tgetEditorKeybindings,\n\tsetEditorKeybindings,\n} from \"./keybindings.js\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.js\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.js\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.js\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetImageDimensions,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.js\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.js\";\n// Utilities\nexport { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"./utils.js\";\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type TerminalBorderStyle = "none" | "rule" | "single" | "rounded" | "heavy" | "minimal";
|
|
2
|
+
export type TerminalDensity = "compact" | "comfortable" | "dashboard";
|
|
3
|
+
export type TerminalTone = "default" | "muted" | "running" | "success" | "error" | "current";
|
|
4
|
+
export interface TerminalStyleSpec {
|
|
5
|
+
width?: number;
|
|
6
|
+
paddingX?: number;
|
|
7
|
+
paddingY?: number;
|
|
8
|
+
border?: TerminalBorderStyle;
|
|
9
|
+
density?: TerminalDensity;
|
|
10
|
+
tone?: TerminalTone;
|
|
11
|
+
borderColor?: (text: string) => string;
|
|
12
|
+
foreground?: (text: string) => string;
|
|
13
|
+
toneColor?: (tone: TerminalTone, text: string) => string;
|
|
14
|
+
title?: string;
|
|
15
|
+
titleRight?: string;
|
|
16
|
+
titleColor?: (text: string) => string;
|
|
17
|
+
titleRightColor?: (text: string) => string;
|
|
18
|
+
bodyGutter?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class TerminalStyle {
|
|
21
|
+
private readonly spec;
|
|
22
|
+
constructor(spec?: TerminalStyleSpec);
|
|
23
|
+
width(width: number): TerminalStyle;
|
|
24
|
+
padding(x: number, y?: number): TerminalStyle;
|
|
25
|
+
paddingX(paddingX: number): TerminalStyle;
|
|
26
|
+
paddingY(paddingY: number): TerminalStyle;
|
|
27
|
+
border(border: TerminalBorderStyle): TerminalStyle;
|
|
28
|
+
density(density: TerminalDensity): TerminalStyle;
|
|
29
|
+
tone(tone: TerminalTone, toneColor?: (tone: TerminalTone, text: string) => string): TerminalStyle;
|
|
30
|
+
borderColor(borderColor: (text: string) => string): TerminalStyle;
|
|
31
|
+
foreground(foreground: (text: string) => string): TerminalStyle;
|
|
32
|
+
toneColor(toneColor: (tone: TerminalTone, text: string) => string): TerminalStyle;
|
|
33
|
+
title(title: string, titleColor?: (text: string) => string): TerminalStyle;
|
|
34
|
+
titleRight(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle;
|
|
35
|
+
rightTitle(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle;
|
|
36
|
+
bodyGutter(bodyGutter: string): TerminalStyle;
|
|
37
|
+
render(contentLines: string[], width?: number): string[];
|
|
38
|
+
private renderTitleRows;
|
|
39
|
+
}
|
|
40
|
+
export declare function style(spec?: TerminalStyleSpec): TerminalStyle;
|
|
41
|
+
//# sourceMappingURL=style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAC/F,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7F,MAAM,WAAW,iBAAiB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAwDD,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;gBAE7B,IAAI,GAAE,iBAAsB;IAIxC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa;IAInC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,SAAI,GAAG,aAAa;IAIxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAIzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAIzC,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa;IAIlD,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,aAAa;IAIhD,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIjG,WAAW,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIjE,UAAU,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAI/D,SAAS,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIjF,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAI1E,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIzF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,aAAa;IAIzF,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAI7C,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAiExD,OAAO,CAAC,eAAe;CAavB;AAED,wBAAgB,KAAK,CAAC,IAAI,GAAE,iBAAsB,GAAG,aAAa,CAEjE"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// GSD2 - Terminal style primitives for framed TUI surfaces
|
|
2
|
+
import { truncateToWidth, visibleWidth } from "./utils.js";
|
|
3
|
+
const BORDER_CHARS = {
|
|
4
|
+
single: {
|
|
5
|
+
topLeft: "┌",
|
|
6
|
+
topRight: "┐",
|
|
7
|
+
bottomLeft: "└",
|
|
8
|
+
bottomRight: "┘",
|
|
9
|
+
horizontal: "─",
|
|
10
|
+
vertical: "│",
|
|
11
|
+
},
|
|
12
|
+
rounded: {
|
|
13
|
+
topLeft: "╭",
|
|
14
|
+
topRight: "╮",
|
|
15
|
+
bottomLeft: "╰",
|
|
16
|
+
bottomRight: "╯",
|
|
17
|
+
horizontal: "─",
|
|
18
|
+
vertical: "│",
|
|
19
|
+
},
|
|
20
|
+
heavy: {
|
|
21
|
+
topLeft: "┏",
|
|
22
|
+
topRight: "┓",
|
|
23
|
+
bottomLeft: "┗",
|
|
24
|
+
bottomRight: "┛",
|
|
25
|
+
horizontal: "━",
|
|
26
|
+
vertical: "┃",
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const DENSITY_PADDING = {
|
|
30
|
+
compact: { x: 0, y: 0 },
|
|
31
|
+
comfortable: { x: 1, y: 0 },
|
|
32
|
+
dashboard: { x: 1, y: 1 },
|
|
33
|
+
};
|
|
34
|
+
function padVisible(line, width) {
|
|
35
|
+
return line + " ".repeat(Math.max(0, width - visibleWidth(line)));
|
|
36
|
+
}
|
|
37
|
+
function color(fn, text) {
|
|
38
|
+
return fn ? fn(text) : text;
|
|
39
|
+
}
|
|
40
|
+
function normalizeWidth(spec, width) {
|
|
41
|
+
return Math.max(1, Math.floor(width ?? spec.width ?? 80));
|
|
42
|
+
}
|
|
43
|
+
export class TerminalStyle {
|
|
44
|
+
constructor(spec = {}) {
|
|
45
|
+
this.spec = { ...spec };
|
|
46
|
+
}
|
|
47
|
+
width(width) {
|
|
48
|
+
return new TerminalStyle({ ...this.spec, width });
|
|
49
|
+
}
|
|
50
|
+
padding(x, y = x) {
|
|
51
|
+
return new TerminalStyle({ ...this.spec, paddingX: x, paddingY: y });
|
|
52
|
+
}
|
|
53
|
+
paddingX(paddingX) {
|
|
54
|
+
return new TerminalStyle({ ...this.spec, paddingX });
|
|
55
|
+
}
|
|
56
|
+
paddingY(paddingY) {
|
|
57
|
+
return new TerminalStyle({ ...this.spec, paddingY });
|
|
58
|
+
}
|
|
59
|
+
border(border) {
|
|
60
|
+
return new TerminalStyle({ ...this.spec, border });
|
|
61
|
+
}
|
|
62
|
+
density(density) {
|
|
63
|
+
return new TerminalStyle({ ...this.spec, density });
|
|
64
|
+
}
|
|
65
|
+
tone(tone, toneColor) {
|
|
66
|
+
return new TerminalStyle({ ...this.spec, tone, toneColor });
|
|
67
|
+
}
|
|
68
|
+
borderColor(borderColor) {
|
|
69
|
+
return new TerminalStyle({ ...this.spec, borderColor });
|
|
70
|
+
}
|
|
71
|
+
foreground(foreground) {
|
|
72
|
+
return new TerminalStyle({ ...this.spec, foreground });
|
|
73
|
+
}
|
|
74
|
+
toneColor(toneColor) {
|
|
75
|
+
return new TerminalStyle({ ...this.spec, toneColor });
|
|
76
|
+
}
|
|
77
|
+
title(title, titleColor) {
|
|
78
|
+
return new TerminalStyle({ ...this.spec, title, titleColor });
|
|
79
|
+
}
|
|
80
|
+
titleRight(titleRight, titleRightColor) {
|
|
81
|
+
return new TerminalStyle({ ...this.spec, titleRight, titleRightColor });
|
|
82
|
+
}
|
|
83
|
+
rightTitle(titleRight, titleRightColor) {
|
|
84
|
+
return this.titleRight(titleRight, titleRightColor);
|
|
85
|
+
}
|
|
86
|
+
bodyGutter(bodyGutter) {
|
|
87
|
+
return new TerminalStyle({ ...this.spec, bodyGutter });
|
|
88
|
+
}
|
|
89
|
+
render(contentLines, width) {
|
|
90
|
+
const outerWidth = normalizeWidth(this.spec, width);
|
|
91
|
+
const border = this.spec.border ?? "none";
|
|
92
|
+
const densityPadding = DENSITY_PADDING[this.spec.density ?? "compact"];
|
|
93
|
+
const paddingX = Math.max(0, Math.floor(this.spec.paddingX ?? densityPadding.x));
|
|
94
|
+
const paddingY = Math.max(0, Math.floor(this.spec.paddingY ?? densityPadding.y));
|
|
95
|
+
const gutter = this.spec.bodyGutter ?? "";
|
|
96
|
+
const gutterWidth = visibleWidth(gutter);
|
|
97
|
+
const borderColumns = border === "none" ? 0 : 2;
|
|
98
|
+
const innerWidth = Math.max(1, outerWidth - borderColumns - paddingX * 2 - gutterWidth);
|
|
99
|
+
const emptyPaddedLine = " ".repeat(paddingX * 2 + innerWidth);
|
|
100
|
+
const sourceLines = contentLines.length > 0 ? contentLines : [""];
|
|
101
|
+
const paddedBody = [
|
|
102
|
+
...Array.from({ length: paddingY }, () => emptyPaddedLine),
|
|
103
|
+
...sourceLines.map((line) => {
|
|
104
|
+
const clipped = truncateToWidth(line, innerWidth, "");
|
|
105
|
+
const styled = color(this.spec.foreground, clipped);
|
|
106
|
+
return `${gutter}${" ".repeat(paddingX)}${padVisible(styled, innerWidth)}${" ".repeat(paddingX)}`;
|
|
107
|
+
}),
|
|
108
|
+
...Array.from({ length: paddingY }, () => emptyPaddedLine),
|
|
109
|
+
];
|
|
110
|
+
const borderColorFn = this.spec.borderColor ?? (this.spec.toneColor ? (value) => this.spec.toneColor?.(this.spec.tone ?? "default", value) ?? value : undefined);
|
|
111
|
+
const borderColor = (text) => color(borderColorFn, text);
|
|
112
|
+
if (border === "none") {
|
|
113
|
+
return paddedBody.map((line) => padVisible(line, outerWidth));
|
|
114
|
+
}
|
|
115
|
+
if (border === "rule") {
|
|
116
|
+
return [
|
|
117
|
+
borderColor("─".repeat(outerWidth)),
|
|
118
|
+
...this.renderTitleRows(outerWidth),
|
|
119
|
+
...paddedBody.map((line) => `${borderColor("│ ")}${truncateToWidth(line, Math.max(1, outerWidth - 2), "")}`),
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
if (border === "minimal") {
|
|
123
|
+
const contentWidth = Math.max(1, outerWidth - 2);
|
|
124
|
+
return [
|
|
125
|
+
...this.renderTitleRows(contentWidth).map((line) => `${borderColor("│ ")}${padVisible(line, contentWidth)}`),
|
|
126
|
+
...paddedBody.map((line) => `${borderColor("│ ")}${padVisible(line, contentWidth)}`),
|
|
127
|
+
];
|
|
128
|
+
}
|
|
129
|
+
const chars = BORDER_CHARS[border];
|
|
130
|
+
const horizontalWidth = Math.max(0, outerWidth - 2);
|
|
131
|
+
const top = borderColor(`${chars.topLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.topRight}`);
|
|
132
|
+
const bottom = borderColor(`${chars.bottomLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.bottomRight}`);
|
|
133
|
+
const contentWidth = Math.max(1, outerWidth - 2);
|
|
134
|
+
return [
|
|
135
|
+
top,
|
|
136
|
+
...this.renderTitleRows(contentWidth).map((line) => `${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`),
|
|
137
|
+
...paddedBody.map((line) => `${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`),
|
|
138
|
+
bottom,
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
renderTitleRows(width) {
|
|
142
|
+
const leftRaw = this.spec.title ?? "";
|
|
143
|
+
const rightRaw = this.spec.titleRight ?? "";
|
|
144
|
+
if (!leftRaw && !rightRaw)
|
|
145
|
+
return [];
|
|
146
|
+
const leftBudget = rightRaw ? Math.max(1, width - visibleWidth(rightRaw) - 1) : width;
|
|
147
|
+
const left = color(this.spec.titleColor, truncateToWidth(leftRaw, leftBudget, ""));
|
|
148
|
+
const right = color(this.spec.titleRightColor, rightRaw);
|
|
149
|
+
const gap = rightRaw
|
|
150
|
+
? Math.max(1, width - visibleWidth(left) - visibleWidth(right))
|
|
151
|
+
: Math.max(0, width - visibleWidth(left));
|
|
152
|
+
return [`${left}${" ".repeat(gap)}${right}`];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export function style(spec = {}) {
|
|
156
|
+
return new TerminalStyle(spec);
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../src/style.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD2 - Terminal style primitives for framed TUI surfaces\n\nimport { truncateToWidth, visibleWidth } from \"./utils.js\";\n\nexport type TerminalBorderStyle = \"none\" | \"rule\" | \"single\" | \"rounded\" | \"heavy\" | \"minimal\";\nexport type TerminalDensity = \"compact\" | \"comfortable\" | \"dashboard\";\nexport type TerminalTone = \"default\" | \"muted\" | \"running\" | \"success\" | \"error\" | \"current\";\n\nexport interface TerminalStyleSpec {\n\twidth?: number;\n\tpaddingX?: number;\n\tpaddingY?: number;\n\tborder?: TerminalBorderStyle;\n\tdensity?: TerminalDensity;\n\ttone?: TerminalTone;\n\tborderColor?: (text: string) => string;\n\tforeground?: (text: string) => string;\n\ttoneColor?: (tone: TerminalTone, text: string) => string;\n\ttitle?: string;\n\ttitleRight?: string;\n\ttitleColor?: (text: string) => string;\n\ttitleRightColor?: (text: string) => string;\n\tbodyGutter?: string;\n}\n\ntype BorderChars = {\n\ttopLeft: string;\n\ttopRight: string;\n\tbottomLeft: string;\n\tbottomRight: string;\n\thorizontal: string;\n\tvertical: string;\n};\n\nconst BORDER_CHARS: Record<Exclude<TerminalBorderStyle, \"none\" | \"rule\" | \"minimal\">, BorderChars> = {\n\tsingle: {\n\t\ttopLeft: \"┌\",\n\t\ttopRight: \"┐\",\n\t\tbottomLeft: \"└\",\n\t\tbottomRight: \"┘\",\n\t\thorizontal: \"─\",\n\t\tvertical: \"│\",\n\t},\n\trounded: {\n\t\ttopLeft: \"╭\",\n\t\ttopRight: \"╮\",\n\t\tbottomLeft: \"╰\",\n\t\tbottomRight: \"╯\",\n\t\thorizontal: \"─\",\n\t\tvertical: \"│\",\n\t},\n\theavy: {\n\t\ttopLeft: \"┏\",\n\t\ttopRight: \"┓\",\n\t\tbottomLeft: \"┗\",\n\t\tbottomRight: \"┛\",\n\t\thorizontal: \"━\",\n\t\tvertical: \"┃\",\n\t},\n};\n\nconst DENSITY_PADDING: Record<TerminalDensity, { x: number; y: number }> = {\n\tcompact: { x: 0, y: 0 },\n\tcomfortable: { x: 1, y: 0 },\n\tdashboard: { x: 1, y: 1 },\n};\n\nfunction padVisible(line: string, width: number): string {\n\treturn line + \" \".repeat(Math.max(0, width - visibleWidth(line)));\n}\n\nfunction color(fn: ((text: string) => string) | undefined, text: string): string {\n\treturn fn ? fn(text) : text;\n}\n\nfunction normalizeWidth(spec: TerminalStyleSpec, width?: number): number {\n\treturn Math.max(1, Math.floor(width ?? spec.width ?? 80));\n}\n\nexport class TerminalStyle {\n\tprivate readonly spec: TerminalStyleSpec;\n\n\tconstructor(spec: TerminalStyleSpec = {}) {\n\t\tthis.spec = { ...spec };\n\t}\n\n\twidth(width: number): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, width });\n\t}\n\n\tpadding(x: number, y = x): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, paddingX: x, paddingY: y });\n\t}\n\n\tpaddingX(paddingX: number): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, paddingX });\n\t}\n\n\tpaddingY(paddingY: number): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, paddingY });\n\t}\n\n\tborder(border: TerminalBorderStyle): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, border });\n\t}\n\n\tdensity(density: TerminalDensity): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, density });\n\t}\n\n\ttone(tone: TerminalTone, toneColor?: (tone: TerminalTone, text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, tone, toneColor });\n\t}\n\n\tborderColor(borderColor: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, borderColor });\n\t}\n\n\tforeground(foreground: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, foreground });\n\t}\n\n\ttoneColor(toneColor: (tone: TerminalTone, text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, toneColor });\n\t}\n\n\ttitle(title: string, titleColor?: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, title, titleColor });\n\t}\n\n\ttitleRight(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, titleRight, titleRightColor });\n\t}\n\n\trightTitle(titleRight: string, titleRightColor?: (text: string) => string): TerminalStyle {\n\t\treturn this.titleRight(titleRight, titleRightColor);\n\t}\n\n\tbodyGutter(bodyGutter: string): TerminalStyle {\n\t\treturn new TerminalStyle({ ...this.spec, bodyGutter });\n\t}\n\n\trender(contentLines: string[], width?: number): string[] {\n\t\tconst outerWidth = normalizeWidth(this.spec, width);\n\t\tconst border = this.spec.border ?? \"none\";\n\t\tconst densityPadding = DENSITY_PADDING[this.spec.density ?? \"compact\"];\n\t\tconst paddingX = Math.max(0, Math.floor(this.spec.paddingX ?? densityPadding.x));\n\t\tconst paddingY = Math.max(0, Math.floor(this.spec.paddingY ?? densityPadding.y));\n\t\tconst gutter = this.spec.bodyGutter ?? \"\";\n\t\tconst gutterWidth = visibleWidth(gutter);\n\t\tconst borderColumns = border === \"none\" ? 0 : 2;\n\t\tconst innerWidth = Math.max(1, outerWidth - borderColumns - paddingX * 2 - gutterWidth);\n\t\tconst emptyPaddedLine = \" \".repeat(paddingX * 2 + innerWidth);\n\t\tconst sourceLines = contentLines.length > 0 ? contentLines : [\"\"];\n\t\tconst paddedBody = [\n\t\t\t...Array.from({ length: paddingY }, () => emptyPaddedLine),\n\t\t\t...sourceLines.map((line) => {\n\t\t\t\tconst clipped = truncateToWidth(line, innerWidth, \"\");\n\t\t\t\tconst styled = color(this.spec.foreground, clipped);\n\t\t\t\treturn `${gutter}${\" \".repeat(paddingX)}${padVisible(styled, innerWidth)}${\" \".repeat(paddingX)}`;\n\t\t\t}),\n\t\t\t...Array.from({ length: paddingY }, () => emptyPaddedLine),\n\t\t];\n\t\tconst borderColorFn = this.spec.borderColor ?? (this.spec.toneColor ? (value: string) => this.spec.toneColor?.(this.spec.tone ?? \"default\", value) ?? value : undefined);\n\t\tconst borderColor = (text: string) => color(borderColorFn, text);\n\n\t\tif (border === \"none\") {\n\t\t\treturn paddedBody.map((line) => padVisible(line, outerWidth));\n\t\t}\n\n\t\tif (border === \"rule\") {\n\t\t\treturn [\n\t\t\t\tborderColor(\"─\".repeat(outerWidth)),\n\t\t\t\t...this.renderTitleRows(outerWidth),\n\t\t\t\t...paddedBody.map((line) => `${borderColor(\"│ \")}${truncateToWidth(line, Math.max(1, outerWidth - 2), \"\")}`),\n\t\t\t];\n\t\t}\n\n\t\tif (border === \"minimal\") {\n\t\t\tconst contentWidth = Math.max(1, outerWidth - 2);\n\t\t\treturn [\n\t\t\t\t...this.renderTitleRows(contentWidth).map((line) => `${borderColor(\"│ \")}${padVisible(line, contentWidth)}`),\n\t\t\t\t...paddedBody.map((line) => `${borderColor(\"│ \")}${padVisible(line, contentWidth)}`),\n\t\t\t];\n\t\t}\n\n\t\tconst chars = BORDER_CHARS[border];\n\t\tconst horizontalWidth = Math.max(0, outerWidth - 2);\n\t\tconst top = borderColor(\n\t\t\t`${chars.topLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.topRight}`,\n\t\t);\n\t\tconst bottom = borderColor(\n\t\t\t`${chars.bottomLeft}${chars.horizontal.repeat(horizontalWidth)}${chars.bottomRight}`,\n\t\t);\n\t\tconst contentWidth = Math.max(1, outerWidth - 2);\n\t\treturn [\n\t\t\ttop,\n\t\t\t...this.renderTitleRows(contentWidth).map((line) =>\n\t\t\t\t`${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`,\n\t\t\t),\n\t\t\t...paddedBody.map((line) =>\n\t\t\t\t`${borderColor(chars.vertical)}${padVisible(line, contentWidth)}${borderColor(chars.vertical)}`,\n\t\t\t),\n\t\t\tbottom,\n\t\t];\n\t}\n\n\tprivate renderTitleRows(width: number): string[] {\n\t\tconst leftRaw = this.spec.title ?? \"\";\n\t\tconst rightRaw = this.spec.titleRight ?? \"\";\n\t\tif (!leftRaw && !rightRaw) return [];\n\n\t\tconst leftBudget = rightRaw ? Math.max(1, width - visibleWidth(rightRaw) - 1) : width;\n\t\tconst left = color(this.spec.titleColor, truncateToWidth(leftRaw, leftBudget, \"\"));\n\t\tconst right = color(this.spec.titleRightColor, rightRaw);\n\t\tconst gap = rightRaw\n\t\t\t? Math.max(1, width - visibleWidth(left) - visibleWidth(right))\n\t\t\t: Math.max(0, width - visibleWidth(left));\n\t\treturn [`${left}${\" \".repeat(gap)}${right}`];\n\t}\n}\n\nexport function style(spec: TerminalStyleSpec = {}): TerminalStyle {\n\treturn new TerminalStyle(spec);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GSD-2 + packages/pi-tui/src/tui.ts - Terminal UI renderer with differential rendering.
|
|
1
2
|
/**
|
|
2
3
|
* Minimal TUI implementation with differential rendering
|
|
3
4
|
*/
|
|
@@ -106,7 +107,6 @@ export class TUI extends Container {
|
|
|
106
107
|
this.renderRequested = false;
|
|
107
108
|
this.cursorRow = 0; // Logical cursor row (end of rendered content)
|
|
108
109
|
this.hardwareCursorRow = 0; // Actual terminal cursor row (may differ due to IME positioning)
|
|
109
|
-
this.contentCursorRow = 0; // Stable baseline row at end of rendered content (before IME cursor reposition)
|
|
110
110
|
this.inputBuffer = ""; // Buffer for parsing terminal responses
|
|
111
111
|
this.cellSizeQueryPending = false;
|
|
112
112
|
this.showHardwareCursor = process.env.PI_HARDWARE_CURSOR === "1" || process.env.TERM_PROGRAM === "WarpTerminal";
|
|
@@ -342,7 +342,6 @@ export class TUI extends Container {
|
|
|
342
342
|
this.previousHeight = -1; // -1 triggers heightChanged, forcing a full clear
|
|
343
343
|
this.cursorRow = 0;
|
|
344
344
|
this.hardwareCursorRow = 0;
|
|
345
|
-
this.contentCursorRow = 0;
|
|
346
345
|
this.maxLinesRendered = 0;
|
|
347
346
|
this.previousViewportTop = 0;
|
|
348
347
|
}
|
|
@@ -460,7 +459,7 @@ export class TUI extends Container {
|
|
|
460
459
|
const height = this.terminal.rows;
|
|
461
460
|
let viewportTop = Math.max(0, this.maxLinesRendered - height);
|
|
462
461
|
let prevViewportTop = this.previousViewportTop;
|
|
463
|
-
let hardwareCursorRow = this.
|
|
462
|
+
let hardwareCursorRow = this.hardwareCursorRow;
|
|
464
463
|
const computeLineDiff = (targetRow) => {
|
|
465
464
|
const currentScreenRow = hardwareCursorRow - prevViewportTop;
|
|
466
465
|
const targetScreenRow = targetRow - viewportTop;
|
|
@@ -510,7 +509,6 @@ export class TUI extends Container {
|
|
|
510
509
|
this.terminal.write(buffer);
|
|
511
510
|
this.cursorRow = Math.max(0, newLines.length - 1);
|
|
512
511
|
this.hardwareCursorRow = this.cursorRow;
|
|
513
|
-
this.contentCursorRow = this.cursorRow;
|
|
514
512
|
// Reset max lines when clearing, otherwise track growth
|
|
515
513
|
if (clear) {
|
|
516
514
|
this.maxLinesRendered = newLines.length;
|
|
@@ -633,7 +631,6 @@ export class TUI extends Container {
|
|
|
633
631
|
this.terminal.write(buffer);
|
|
634
632
|
this.cursorRow = targetRow;
|
|
635
633
|
this.hardwareCursorRow = targetRow;
|
|
636
|
-
this.contentCursorRow = targetRow;
|
|
637
634
|
}
|
|
638
635
|
this.positionHardwareCursor(cursorPos, newLines.length);
|
|
639
636
|
this.previousLines = newLines;
|
|
@@ -742,10 +739,8 @@ export class TUI extends Container {
|
|
|
742
739
|
// Track cursor position for next render
|
|
743
740
|
// cursorRow tracks end of content (for viewport calculation)
|
|
744
741
|
// hardwareCursorRow tracks actual terminal cursor position (for movement)
|
|
745
|
-
|
|
746
|
-
this.cursorRow = contentBottomRow;
|
|
742
|
+
this.cursorRow = Math.max(0, newLines.length - 1);
|
|
747
743
|
this.hardwareCursorRow = finalCursorRow;
|
|
748
|
-
this.contentCursorRow = contentBottomRow;
|
|
749
744
|
// Track terminal's working area (grows but doesn't shrink unless cleared)
|
|
750
745
|
this.maxLinesRendered = Math.max(this.maxLinesRendered, newLines.length);
|
|
751
746
|
this.previousViewportTop = Math.max(0, this.maxLinesRendered - height);
|