pi-harness-runtime 1.1.440 → 1.1.441
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/harness/e2e/auto-test-loop.ts +2 -0
- package/harness/e2e/browser-scrapers/base-browser-scraper.ts +2 -0
- package/harness/e2e/browser-scrapers/chrome-profile-manager.ts +2 -0
- package/harness/e2e/browser-scrapers/codex-browser-scraper.ts +2 -0
- package/harness/e2e/tools-detector.ts +2 -0
- package/harness/key-loader.ts +2 -0
- package/harness/langchain/checkpointer.ts +2 -0
- package/harness/langchain/cron-cli.ts +2 -0
- package/harness/langchain/graph.ts +2 -0
- package/harness/notification-center.ts +2 -0
- package/harness/secret-provider.ts +2 -0
- package/index.ts +2 -0
- package/package.json +7 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/dist/extension.d.ts.map +1 -1
- package/packages/agent-policy/dist/extension.js +2 -0
- package/packages/agent-policy/dist/extension.js.map +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/agent-policy/src/extension.ts +2 -0
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/dist/minimax-browser-auth.d.ts.map +1 -1
- package/packages/auth/dist/minimax-browser-auth.js +23 -1
- package/packages/auth/dist/minimax-browser-auth.js.map +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/auth/src/minimax-browser-auth.ts +30 -5
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/dist/inbox.d.ts.map +1 -1
- package/packages/autonomous-runtime/dist/inbox.js +2 -0
- package/packages/autonomous-runtime/dist/inbox.js.map +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/autonomous-runtime/src/inbox.ts +2 -0
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/dist/src/clipboard.d.ts.map +1 -1
- package/packages/clipboard/dist/src/clipboard.js +2 -0
- package/packages/clipboard/dist/src/clipboard.js.map +1 -1
- package/packages/clipboard/dist/src/copy-sync.d.ts.map +1 -1
- package/packages/clipboard/dist/src/copy-sync.js +2 -0
- package/packages/clipboard/dist/src/copy-sync.js.map +1 -1
- package/packages/clipboard/dist/src/gist-relay.d.ts.map +1 -1
- package/packages/clipboard/dist/src/gist-relay.js +2 -0
- package/packages/clipboard/dist/src/gist-relay.js.map +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard/src/clipboard.ts +2 -0
- package/packages/clipboard/src/copy-sync.ts +2 -0
- package/packages/clipboard/src/gist-relay.ts +2 -0
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/connection-runtime/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/contracts/dist/delegation-store.js +1 -4
- package/packages/contracts/dist/workspace-env.js +28 -1
- package/packages/contracts/package.json +1 -1
- package/packages/contracts/src/delegation-store.ts +9 -4
- package/packages/contracts/src/workspace-env.ts +29 -4
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/durable-review/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-sink/package.json +1 -1
- package/packages/event-store/dist/src/store.d.ts.map +1 -1
- package/packages/event-store/dist/src/store.js +2 -0
- package/packages/event-store/dist/src/store.js.map +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/event-store/src/store.ts +3 -0
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/dist/analyzer.d.ts.map +1 -1
- package/packages/generic-web-plugin/dist/analyzer.js +2 -0
- package/packages/generic-web-plugin/dist/analyzer.js.map +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/generic-web-plugin/src/analyzer.ts +3 -0
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/dist/mcp-client.d.ts.map +1 -1
- package/packages/knowledge-retrieval/dist/mcp-client.js +0 -1
- package/packages/knowledge-retrieval/dist/mcp-client.js.map +1 -1
- package/packages/knowledge-retrieval/package.json +1 -4
- package/packages/knowledge-retrieval/src/mcp-client.ts +0 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/logging/package.json +1 -1
- package/packages/mcp-adapter/dist/server.d.ts.map +1 -1
- package/packages/mcp-adapter/dist/server.js +2 -0
- package/packages/mcp-adapter/dist/server.js.map +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/mcp-adapter/src/server.ts +3 -0
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/dist/index.d.ts.map +1 -1
- package/packages/paperclip-integration/dist/index.js +2 -0
- package/packages/paperclip-integration/dist/index.js.map +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/paperclip-integration/src/index.ts +2 -0
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/permission-mode/package.json +1 -1
- package/packages/privilege-broker/dist/audit.d.ts.map +1 -1
- package/packages/privilege-broker/dist/audit.js +2 -0
- package/packages/privilege-broker/dist/audit.js.map +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/privilege-broker/src/audit.ts +2 -0
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/dist/compiler.d.ts.map +1 -1
- package/packages/prompt-compiler/dist/compiler.js +2 -0
- package/packages/prompt-compiler/dist/compiler.js.map +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-compiler/src/compiler.ts +2 -0
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/dist/client.d.ts.map +1 -1
- package/packages/skill-mcp-client/dist/client.js +0 -1
- package/packages/skill-mcp-client/dist/client.js.map +1 -1
- package/packages/skill-mcp-client/package.json +1 -4
- package/packages/skill-mcp-client/src/client.ts +0 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/dist/parser.d.ts.map +1 -1
- package/packages/skills/dist/parser.js +2 -0
- package/packages/skills/dist/parser.js.map +1 -1
- package/packages/skills/dist/skill-versioning.d.ts.map +1 -1
- package/packages/skills/dist/skill-versioning.js +2 -0
- package/packages/skills/dist/skill-versioning.js.map +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/skills/src/parser.ts +3 -0
- package/packages/skills/src/skill-versioning.ts +2 -0
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/tooling-preference/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/two-phase-review/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/voice-api/package.json +1 -1
- package/packages/webmcp-tester/dist/index.js +0 -2
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/webmcp-tester/src/index.ts +0 -3
- package/packages/wiki/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/dist/trigger.d.ts.map +1 -1
- package/packages/write-review/dist/trigger.js +1 -2
- package/packages/write-review/dist/trigger.js.map +1 -1
- package/packages/write-review/package.json +1 -1
- package/packages/write-review/src/trigger.ts +1 -2
- package/scripts/lib/runtime-imports.ts +189 -3
- package/scripts/telegram-webhook-server.ts +2 -0
- package/scripts/verify-package-contents.ts +148 -1
- package/harness/e2e/tools-detector.test.ts +0 -155
- package/harness/glm-quota-countdown.test.ts +0 -323
- package/harness/langchain/agents.test.ts +0 -39
- package/harness/langchain/checkpointer.test.ts +0 -243
- package/harness/langchain/daemon.test.ts +0 -459
- package/harness/langchain/model-router.test.ts +0 -191
- package/harness/langchain/ping-pong-middleware.test.ts +0 -69
- package/harness/langchain/scoreboard.test.ts +0 -267
- package/harness/langchain/status-line.test.ts +0 -106
- package/harness/langchain/surge.test.ts +0 -467
- package/harness/langchain/widget.test.ts +0 -251
- package/harness/skill-sync.test.ts +0 -57
- package/harness/ssh-detach-interceptor.test.ts +0 -263
- package/harness/ssh-hang-recovery.test.ts +0 -86
- package/packages/a2a-adapter/test/a2a.test.ts +0 -151
- package/packages/agent-policy/test/interlock.test.ts +0 -101
- package/packages/agent-policy/test/policy-retention.test.ts +0 -380
- package/packages/agent-policy/test/policy.test.ts +0 -387
- package/packages/auth/test/auth.test.ts +0 -238
- package/packages/autonomous-refactor/test/refactor.test.ts +0 -202
- package/packages/autonomous-runtime/test/types.test.ts +0 -95
- package/packages/cache-strategy/test/cache.test.ts +0 -137
- package/packages/capability-registry/test/registry.test.ts +0 -204
- package/packages/checkpoint/test/engine.test.ts +0 -265
- package/packages/cli-plugin-sdk/test/cli.test.ts +0 -45
- package/packages/code-generation/test/generator.test.ts +0 -238
- package/packages/code-review/test/engine.test.ts +0 -302
- package/packages/codex-adapter/test/provider.test.ts +0 -142
- package/packages/codex-watcher/test/watch.test.ts +0 -453
- package/packages/context-compiler/test/context-compiler.test.ts +0 -746
- package/packages/context-manager/test/context.test.ts +0 -198
- package/packages/contracts/test/delegation.test.ts +0 -350
- package/packages/contracts/test/workspace-env.test.ts +0 -802
- package/packages/cookie-sanitizer/test/infer.test.ts +0 -110
- package/packages/cookie-sanitizer/test/normalize.test.ts +0 -113
- package/packages/cookie-sanitizer/test/parse.test.ts +0 -204
- package/packages/cookie-sanitizer/test/sync.test.ts +0 -237
- package/packages/cookie-sanitizer/test/watcher.test.ts +0 -27
- package/packages/cost-optimizer/test/cost-optimizer.test.ts +0 -438
- package/packages/dependency-analyzer/test/analyzer.test.ts +0 -49
- package/packages/django-plugin/test/analyzer.test.ts +0 -195
- package/packages/doc-generator/test/docs.test.ts +0 -168
- package/packages/durable-review/test/acceptance.test.ts +0 -357
- package/packages/durable-review/test/smoke.test.ts +0 -107
- package/packages/evaluation-engine/test/engine.test.ts +0 -277
- package/packages/evaluation-runner/test/runner.test.ts +0 -168
- package/packages/event-bus/test/bus.test.ts +0 -100
- package/packages/event-store/test/store.test.ts +0 -115
- package/packages/experience-replay/test/replay.test.ts +0 -267
- package/packages/feedback-collector/test/collector.test.ts +0 -142
- package/packages/framework-detector/test/detector.test.ts +0 -75
- package/packages/framework-plugin-sdk/test/manager.test.ts +0 -320
- package/packages/frappe-plugin/test/analyzer.test.ts +0 -250
- package/packages/generic-web-plugin/test/analyzer.test.ts +0 -134
- package/packages/health-monitor/test/health.test.ts +0 -231
- package/packages/intent-analyzer/test/analyzer.test.ts +0 -72
- package/packages/intent-analyzer/test/ping-pong.test.ts +0 -96
- package/packages/jev-judge/tests/auto-continue-context.test.ts +0 -280
- package/packages/jev-judge/tests/continuation-controller.test.ts +0 -1396
- package/packages/jev-judge/tests/jev-provider-chain.test.ts +0 -536
- package/packages/jev-judge/tests/outcome-application.test.ts +0 -132
- package/packages/jev-judge/tests/question-risk.test.ts +0 -129
- package/packages/jev-judge/tests/typesafe-provider.test.ts +0 -640
- package/packages/jev-judge/tests/validation-ledger.test.ts +0 -181
- package/packages/jev-judge/tests/validation-plan.test.ts +0 -170
- package/packages/jev-judge/tests/validation-tie-breaker.test.ts +0 -88
- package/packages/laravel-plugin/test/analyzer.test.ts +0 -220
- package/packages/learning-engine/test/engine.test.ts +0 -331
- package/packages/logging/test/buffer.test.ts +0 -44
- package/packages/logging/test/classification.test.ts +0 -137
- package/packages/logging/test/config.test.ts +0 -97
- package/packages/logging/test/fanout.test.ts +0 -186
- package/packages/logging/test/identity-transport.test.ts +0 -197
- package/packages/logging/test/incidents.test.ts +0 -404
- package/packages/logging/test/ingest-schema.test.ts +0 -184
- package/packages/logging/test/integration.test.ts +0 -140
- package/packages/logging/test/log-http.test.ts +0 -246
- package/packages/logging/test/redact.test.ts +0 -109
- package/packages/logging/test/sampler.test.ts +0 -57
- package/packages/logging/test/server.test.ts +0 -444
- package/packages/logging/test/shipper.test.ts +0 -152
- package/packages/logging/test/spool.test.ts +0 -96
- package/packages/mcp-adapter/test/server.test.ts +0 -91
- package/packages/memory-engine/test/engine.test.ts +0 -456
- package/packages/model-registry/test/registry.test.ts +0 -342
- package/packages/nextjs-plugin/test/analyzer.test.ts +0 -149
- package/packages/notification/test/approval-payload.test.ts +0 -269
- package/packages/notification/test/detail-format.test.ts +0 -106
- package/packages/notification/test/notification.test.ts +0 -375
- package/packages/notification/test/pending-question-lifecycle.test.ts +0 -195
- package/packages/notification/test/pending-question.test.ts +0 -331
- package/packages/notification/test/tooling-proposal-payload.test.ts +0 -212
- package/packages/observability/test/observability.test.ts +0 -1350
- package/packages/performance-optimizer/test/optimizer.test.ts +0 -267
- package/packages/project-analyzer/test/index.test.ts +0 -1719
- package/packages/prompt-compiler/test/prompt-compiler.test.ts +0 -813
- package/packages/prompt-versioning/test/versioning.test.ts +0 -112
- package/packages/provider-adapter-sdk/test/sdk.test.ts +0 -220
- package/packages/provider-router/test/provider-router.test.ts +0 -405
- package/packages/provider-selector/test/selector.test.ts +0 -192
- package/packages/providers/test/providers.test.ts +0 -225
- package/packages/qdrant-skills/test/collection-info.test.ts +0 -165
- package/packages/qdrant-skills/test/embedder-batch.test.ts +0 -184
- package/packages/qdrant-skills/test/embedder.test.ts +0 -97
- package/packages/quota-manager/test/quota.test.ts +0 -432
- package/packages/rate-limiter/test/limiter.test.ts +0 -128
- package/packages/react-vite-plugin/test/analyzer.test.ts +0 -139
- package/packages/relay/test/client.test.ts +0 -446
- package/packages/relay/test/relay-e2e.test.ts +0 -299
- package/packages/relay/test/relay-endpoint.test.ts +0 -278
- package/packages/release-manager/test/release.test.ts +0 -215
- package/packages/requirement-compiler/test/requirement-compiler.test.ts +0 -743
- package/packages/runtime/test/runtime-api.test.ts +0 -169
- package/packages/runtime/test/runtime.test.ts +0 -297
- package/packages/scheduler/test/scheduler.test.ts +0 -125
- package/packages/session/test/manager.test.ts +0 -233
- package/packages/shared-context/test/shared-context.test.ts +0 -114
- package/packages/skill-registry/test/registry.test.ts +0 -508
- package/packages/skills/test/init-skills.test.ts +0 -114
- package/packages/skills/test/remote-skills.test.ts +0 -360
- package/packages/skills/test/remote-source.test.ts +0 -248
- package/packages/skills/test/sanitize.test.ts +0 -250
- package/packages/skills/test/vector-indexing.test.ts +0 -205
- package/packages/skills/test/vector-schema.test.ts +0 -180
- package/packages/skills/test/vector-threshold.test.ts +0 -108
- package/packages/sprint-planner/test/planner.test.ts +0 -187
- package/packages/task-compiler/test/task-compiler.test.ts +0 -628
- package/packages/test-data-generator/test/generator.test.ts +0 -265
- package/packages/test-generator/test/generator.test.ts +0 -156
- package/packages/token-estimation/test/token-estimation.test.ts +0 -207
- package/packages/token-optimizer/test/optimizer.test.ts +0 -141
- package/packages/tooling-preference/tests/changed-files.test.ts +0 -124
- package/packages/tooling-preference/tests/detect.test.ts +0 -188
- package/packages/tooling-preference/tests/proposal.test.ts +0 -107
- package/packages/tooling-preference/tests/quality-check.test.ts +0 -272
- package/packages/tooling-preference/tests/registry.test.ts +0 -51
- package/packages/tooling-preference/tests/store.test.ts +0 -99
- package/packages/trajectory/test/store.test.ts +0 -250
- package/packages/tui/test/harness-footer.test.ts +0 -559
- package/packages/tui/test/harness-header.test.ts +0 -590
- package/packages/two-phase-review/test/classify.test.ts +0 -102
- package/packages/two-phase-review/test/helpers.ts +0 -72
- package/packages/two-phase-review/test/rules.test.ts +0 -150
- package/packages/two-phase-review/test/runtime.test.ts +0 -362
- package/packages/two-phase-review/test/scope.test.ts +0 -186
- package/packages/two-phase-review/test/signals.test.ts +0 -183
- package/packages/two-phase-review/test/state.test.ts +0 -201
- package/packages/wiki/test/basic.test.ts +0 -242
- package/packages/workspace-scanner/test/scanner.test.ts +0 -43
- package/packages/worktree/test/worktree.test.ts +0 -163
|
@@ -1,559 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for harness-footer.ts
|
|
3
|
-
*
|
|
4
|
-
* Tests cover the acceptance criteria of the harness footer:
|
|
5
|
-
* - the MiniMax quota keeps its own row and the workspace summary gets a
|
|
6
|
-
* distinct row (never appended to the quota text)
|
|
7
|
-
* - the workspace row survives narrow terminals (the quota row is truncated
|
|
8
|
-
* instead)
|
|
9
|
-
* - Pi's footer information (cwd/branch, token stats, cost, context usage,
|
|
10
|
-
* model/thinking state) is still rendered
|
|
11
|
-
* - other extensions' status values remain visible
|
|
12
|
-
* - a stale extension context degrades gracefully instead of breaking the TUI
|
|
13
|
-
*
|
|
14
|
-
* Run with: bun test packages/tui/test/harness-footer.test.ts
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
// The test file lives outside the package tsconfig (`include: src/**/*`), so
|
|
18
|
-
// the `bun:test` module declaration is pulled in explicitly.
|
|
19
|
-
/// <reference types="bun-types" />
|
|
20
|
-
|
|
21
|
-
import { describe, expect, it } from "bun:test";
|
|
22
|
-
import type {
|
|
23
|
-
ExtensionContext,
|
|
24
|
-
ReadonlyFooterDataProvider,
|
|
25
|
-
Theme,
|
|
26
|
-
} from "@earendil-works/pi-coding-agent";
|
|
27
|
-
import { visibleWidth } from "@earendil-works/pi-tui";
|
|
28
|
-
import {
|
|
29
|
-
createHarnessFooter,
|
|
30
|
-
formatCwdForFooter,
|
|
31
|
-
renderFooterRows,
|
|
32
|
-
wrapStatusText,
|
|
33
|
-
type FooterSessionInfo,
|
|
34
|
-
} from "../src/harness-footer.js";
|
|
35
|
-
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
// Test doubles
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
|
|
40
|
-
/** Theme stub without ANSI escapes so assertions stay readable. */
|
|
41
|
-
const plainTheme = {
|
|
42
|
-
fg: (_token: string, text: string) => text,
|
|
43
|
-
} as unknown as Theme;
|
|
44
|
-
|
|
45
|
-
function makeFooterData(statuses: Record<string, string>): ReadonlyFooterDataProvider {
|
|
46
|
-
const map = new Map(Object.entries(statuses));
|
|
47
|
-
return {
|
|
48
|
-
getGitBranch: () => "main",
|
|
49
|
-
getExtensionStatuses: () => map,
|
|
50
|
-
getAvailableProviderCount: () => 1,
|
|
51
|
-
onBranchChange: () => () => {},
|
|
52
|
-
} as unknown as ReadonlyFooterDataProvider;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function makeSessionInfo(overrides: Partial<FooterSessionInfo> = {}): FooterSessionInfo {
|
|
56
|
-
return {
|
|
57
|
-
cwd: "/home/tester/pi-harness-runtime",
|
|
58
|
-
branch: "main",
|
|
59
|
-
sessionName: null,
|
|
60
|
-
modelId: "MiniMax-M2",
|
|
61
|
-
modelProvider: "minimax",
|
|
62
|
-
modelSupportsReasoning: false,
|
|
63
|
-
thinkingLevel: null,
|
|
64
|
-
usage: {
|
|
65
|
-
input: 1200,
|
|
66
|
-
output: 340,
|
|
67
|
-
cacheRead: 0,
|
|
68
|
-
cacheWrite: 0,
|
|
69
|
-
cost: 0.12,
|
|
70
|
-
},
|
|
71
|
-
cacheHitRate: null,
|
|
72
|
-
contextPercent: 34.2,
|
|
73
|
-
contextWindow: 200000,
|
|
74
|
-
providerCount: 1,
|
|
75
|
-
...overrides,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const QUOTA = "MiniMax: 5h: 98% left (resets 3 hr 15 min) - week: 85% left";
|
|
80
|
-
const WORKSPACE =
|
|
81
|
-
"Workspace: ~/pi-harness-runtime | OS: Linux | mode: UNKNOWN (no explicit NODE_ENV)" +
|
|
82
|
-
" | dev server: not detected | dev script: unavailable | build script: available | RAM: 6.4/15";
|
|
83
|
-
|
|
84
|
-
// ---------------------------------------------------------------------------
|
|
85
|
-
// Tests
|
|
86
|
-
// ---------------------------------------------------------------------------
|
|
87
|
-
|
|
88
|
-
/** A live-looking extension context (cwd, model, usage, context window). */
|
|
89
|
-
function makeLiveCtx(overrides: Record<string, unknown> = {}): ExtensionContext {
|
|
90
|
-
return {
|
|
91
|
-
mode: "tui",
|
|
92
|
-
cwd: "/home/tester/pi-harness-runtime",
|
|
93
|
-
model: { id: "MiniMax-M2", provider: "minimax", contextWindow: 200000 },
|
|
94
|
-
thinkingLevel: "high",
|
|
95
|
-
sessionManager: {
|
|
96
|
-
getCwd: () => "/home/tester/pi-harness-runtime",
|
|
97
|
-
getSessionName: () => "session-1",
|
|
98
|
-
getEntries: () => [
|
|
99
|
-
{
|
|
100
|
-
type: "message",
|
|
101
|
-
message: {
|
|
102
|
-
role: "assistant",
|
|
103
|
-
usage: {
|
|
104
|
-
input: 100,
|
|
105
|
-
output: 20,
|
|
106
|
-
cacheRead: 0,
|
|
107
|
-
cacheWrite: 0,
|
|
108
|
-
cost: { total: 0.01 },
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
getContextUsage: () => ({ percent: 12.5, contextWindow: 200000 }),
|
|
115
|
-
...overrides,
|
|
116
|
-
} as unknown as ExtensionContext;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
describe("harness footer rows", () => {
|
|
120
|
-
it("puts the quota and the workspace summary on separate rows", () => {
|
|
121
|
-
const footer = createHarnessFooter(
|
|
122
|
-
{} as never,
|
|
123
|
-
plainTheme,
|
|
124
|
-
makeFooterData({
|
|
125
|
-
"harness-runtime": QUOTA,
|
|
126
|
-
"harness-workspace": WORKSPACE,
|
|
127
|
-
}),
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
const lines = footer.render(120);
|
|
131
|
-
const quotaLine = lines.find((line) => line.includes("MiniMax: 5h:"));
|
|
132
|
-
const workspaceIndex = lines.findIndex((line) => line.includes("Workspace:"));
|
|
133
|
-
// The workspace value can wrap over several lines - the fields must
|
|
134
|
-
// all be there.
|
|
135
|
-
const workspaceText = lines.slice(workspaceIndex).join(" ");
|
|
136
|
-
|
|
137
|
-
expect(quotaLine).toBeDefined();
|
|
138
|
-
expect(workspaceIndex).toBeGreaterThanOrEqual(0);
|
|
139
|
-
expect(quotaLine).not.toContain("Workspace:");
|
|
140
|
-
expect(workspaceText).not.toContain("MiniMax:");
|
|
141
|
-
expect(workspaceText).toContain("Workspace:");
|
|
142
|
-
expect(workspaceText).toContain("OS: Linux");
|
|
143
|
-
expect(workspaceText).toContain("dev server:");
|
|
144
|
-
expect(workspaceText).toContain("build script:");
|
|
145
|
-
expect(workspaceText).toContain("RAM:");
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("keeps Pi's footer information (cwd, branch, stats, model)", () => {
|
|
149
|
-
const footer = createHarnessFooter(
|
|
150
|
-
{} as never,
|
|
151
|
-
plainTheme,
|
|
152
|
-
makeFooterData({ "harness-runtime": QUOTA }),
|
|
153
|
-
{ getContext: () => makeLiveCtx() },
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
const lines = footer.render(160);
|
|
157
|
-
// Row 0: working directory + branch (+ session name).
|
|
158
|
-
expect(lines[0]).toContain("pi-harness-runtime");
|
|
159
|
-
expect(lines[0]).toContain("main");
|
|
160
|
-
expect(lines[0]).toContain("session-1");
|
|
161
|
-
// Row 1: token/cost/context stats + model.
|
|
162
|
-
expect(lines[1]).toContain("↑100");
|
|
163
|
-
expect(lines[1]).toContain("↓20");
|
|
164
|
-
expect(lines[1]).toContain("$0.010");
|
|
165
|
-
expect(lines[1]).toContain("12.5%");
|
|
166
|
-
expect(lines[1]).toContain("MiniMax-M2");
|
|
167
|
-
// The quota still gets its own row.
|
|
168
|
-
expect(lines[2]).toContain("MiniMax:");
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it("keeps the harness status keys out of the shared extensions row", () => {
|
|
172
|
-
const footer = createHarnessFooter(
|
|
173
|
-
{} as never,
|
|
174
|
-
plainTheme,
|
|
175
|
-
makeFooterData({
|
|
176
|
-
"harness-runtime": QUOTA,
|
|
177
|
-
"harness-workspace": WORKSPACE,
|
|
178
|
-
"harness-auto-continue": "auto-continue: CONTINUING",
|
|
179
|
-
"other-extension": "other-extension-status",
|
|
180
|
-
}),
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
const lines = footer.render(200);
|
|
184
|
-
const sharedRow = lines.find((line) =>
|
|
185
|
-
line.includes("other-extension-status"),
|
|
186
|
-
);
|
|
187
|
-
expect(sharedRow).toBeDefined();
|
|
188
|
-
// The shared row carries only the OTHER extensions' values.
|
|
189
|
-
expect(sharedRow).not.toContain("MiniMax:");
|
|
190
|
-
expect(sharedRow).not.toContain("Workspace:");
|
|
191
|
-
expect(sharedRow).not.toContain("CONTINUING");
|
|
192
|
-
// Each harness value has its own row.
|
|
193
|
-
expect(lines.some((line) => line.includes("MiniMax:"))).toBe(true);
|
|
194
|
-
expect(lines.some((line) => line.includes("Workspace:"))).toBe(true);
|
|
195
|
-
const autoRow = lines.find((line) => line.includes("CONTINUING"));
|
|
196
|
-
expect(autoRow).toBeDefined();
|
|
197
|
-
expect(autoRow).not.toContain("other-extension-status");
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it("computes the cache-hit rate from input + cached tokens", () => {
|
|
201
|
-
// Regression: `input ?? 0 + cacheRead + cacheWrite` parses as
|
|
202
|
-
// `input ?? (0 + cacheRead + cacheWrite)` and reported CH9000.0%.
|
|
203
|
-
const ctx = makeLiveCtx({
|
|
204
|
-
sessionManager: {
|
|
205
|
-
getCwd: () => "/home/tester/pi-harness-runtime",
|
|
206
|
-
getSessionName: () => "session-1",
|
|
207
|
-
getEntries: () => [
|
|
208
|
-
{
|
|
209
|
-
type: "message",
|
|
210
|
-
message: {
|
|
211
|
-
role: "assistant",
|
|
212
|
-
usage: {
|
|
213
|
-
input: 100,
|
|
214
|
-
output: 20,
|
|
215
|
-
cacheRead: 9000,
|
|
216
|
-
cacheWrite: 0,
|
|
217
|
-
cost: { total: 0.01 },
|
|
218
|
-
},
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
],
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
const footer = createHarnessFooter(
|
|
226
|
-
{} as never,
|
|
227
|
-
plainTheme,
|
|
228
|
-
makeFooterData({}),
|
|
229
|
-
{ getContext: () => ctx },
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
const lines = footer.render(200);
|
|
233
|
-
expect(lines[1]).toContain("CH98.9%");
|
|
234
|
-
expect(lines[1]).not.toContain("CH9000");
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it("keeps the last known session rows when the context goes stale", () => {
|
|
238
|
-
let stale = false;
|
|
239
|
-
const footer = createHarnessFooter(
|
|
240
|
-
{} as never,
|
|
241
|
-
plainTheme,
|
|
242
|
-
makeFooterData({ "harness-runtime": QUOTA }),
|
|
243
|
-
{
|
|
244
|
-
getContext: () => {
|
|
245
|
-
if (stale) throw new Error("This extension ctx is stale");
|
|
246
|
-
return makeLiveCtx();
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
const before = footer.render(160);
|
|
252
|
-
expect(before[0]).toContain("pi-harness-runtime");
|
|
253
|
-
|
|
254
|
-
stale = true;
|
|
255
|
-
const after = footer.render(160);
|
|
256
|
-
// The cwd/model rows survive the stale context.
|
|
257
|
-
expect(after[0]).toContain("pi-harness-runtime");
|
|
258
|
-
expect(after[1]).toContain("MiniMax-M2");
|
|
259
|
-
expect(after.some((line) => line.includes("MiniMax:"))).toBe(true);
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it("keeps the last known rows when the context throws on property access", () => {
|
|
263
|
-
// The real stale-ctx case: the ctx object still exists but every
|
|
264
|
-
// property access throws ("This extension ctx is stale after session
|
|
265
|
-
// replacement or reload"). The footer must not blank the rows.
|
|
266
|
-
const staleCtx = makeLiveCtx();
|
|
267
|
-
let broken = false;
|
|
268
|
-
const ctxProxy = new Proxy(staleCtx, {
|
|
269
|
-
get(target, prop, receiver) {
|
|
270
|
-
if (broken && prop !== "then") {
|
|
271
|
-
throw new Error("This extension ctx is stale after session replacement or reload...");
|
|
272
|
-
}
|
|
273
|
-
return Reflect.get(target, prop, receiver);
|
|
274
|
-
},
|
|
275
|
-
}) as ExtensionContext;
|
|
276
|
-
|
|
277
|
-
const footer = createHarnessFooter(
|
|
278
|
-
{} as never,
|
|
279
|
-
plainTheme,
|
|
280
|
-
makeFooterData({ "harness-runtime": QUOTA }),
|
|
281
|
-
{ getContext: () => ctxProxy },
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
const before = footer.render(160);
|
|
285
|
-
expect(before[0]).toContain("pi-harness-runtime");
|
|
286
|
-
expect(before[1]).toContain("MiniMax-M2");
|
|
287
|
-
|
|
288
|
-
broken = true;
|
|
289
|
-
const after = footer.render(160);
|
|
290
|
-
expect(after[0]).toContain("pi-harness-runtime");
|
|
291
|
-
expect(after[1]).toContain("MiniMax-M2");
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
it("keeps the workspace row visible when the terminal is narrow", () => {
|
|
295
|
-
const footer = createHarnessFooter(
|
|
296
|
-
{} as never,
|
|
297
|
-
plainTheme,
|
|
298
|
-
makeFooterData({
|
|
299
|
-
"harness-runtime": QUOTA,
|
|
300
|
-
"harness-workspace": WORKSPACE,
|
|
301
|
-
}),
|
|
302
|
-
);
|
|
303
|
-
|
|
304
|
-
const lines = footer.render(40);
|
|
305
|
-
const workspaceLine = lines.find((line) => line.includes("Workspace:"));
|
|
306
|
-
expect(workspaceLine).toBeDefined();
|
|
307
|
-
// The quota row is still there.
|
|
308
|
-
const quotaLine = lines.find((line) => line.includes("MiniMax:"));
|
|
309
|
-
expect(quotaLine).toBeDefined();
|
|
310
|
-
expect(quotaLine?.length ?? 0).toBeGreaterThan(0);
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
it("wraps the workspace row instead of hiding the fields that do not fit", () => {
|
|
314
|
-
const footer = createHarnessFooter(
|
|
315
|
-
{} as never,
|
|
316
|
-
plainTheme,
|
|
317
|
-
makeFooterData({
|
|
318
|
-
"harness-runtime": QUOTA,
|
|
319
|
-
"harness-workspace": WORKSPACE,
|
|
320
|
-
}),
|
|
321
|
-
);
|
|
322
|
-
|
|
323
|
-
const lines = footer.render(40);
|
|
324
|
-
const start = lines.findIndex((line) => line.includes("Workspace:"));
|
|
325
|
-
expect(start).toBeGreaterThanOrEqual(0);
|
|
326
|
-
// The workspace value continues on the following lines until the
|
|
327
|
-
// quota row starts - no field may be cut away.
|
|
328
|
-
const workspaceLines: string[] = [];
|
|
329
|
-
for (let i = start; i < lines.length; i++) {
|
|
330
|
-
if (lines[i].includes("MiniMax:")) break;
|
|
331
|
-
workspaceLines.push(lines[i]);
|
|
332
|
-
}
|
|
333
|
-
const joined = workspaceLines.join(" ");
|
|
334
|
-
expect(joined).toContain("OS: Linux");
|
|
335
|
-
expect(joined).toContain("dev server: not detected");
|
|
336
|
-
expect(joined).toContain("RAM: 6.4/15");
|
|
337
|
-
// Every line stays inside the terminal width.
|
|
338
|
-
for (const line of workspaceLines) {
|
|
339
|
-
expect(visibleWidth(line)).toBeLessThanOrEqual(40);
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
it("still shows other extensions' status values", () => {
|
|
344
|
-
const footer = createHarnessFooter(
|
|
345
|
-
{} as never,
|
|
346
|
-
plainTheme,
|
|
347
|
-
makeFooterData({
|
|
348
|
-
"harness-runtime": QUOTA,
|
|
349
|
-
"harness-workspace": WORKSPACE,
|
|
350
|
-
"other-extension": "other-extension-status",
|
|
351
|
-
}),
|
|
352
|
-
);
|
|
353
|
-
|
|
354
|
-
const lines = footer.render(200);
|
|
355
|
-
expect(lines.some((line) => line.includes("other-extension-status"))).toBe(
|
|
356
|
-
true,
|
|
357
|
-
);
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
it("degrades gracefully when the extension context is stale", () => {
|
|
361
|
-
const footer = createHarnessFooter(
|
|
362
|
-
{} as never,
|
|
363
|
-
plainTheme,
|
|
364
|
-
makeFooterData({
|
|
365
|
-
"harness-runtime": QUOTA,
|
|
366
|
-
"harness-workspace": WORKSPACE,
|
|
367
|
-
}),
|
|
368
|
-
{
|
|
369
|
-
getContext: () => {
|
|
370
|
-
throw new Error("This extension ctx is stale");
|
|
371
|
-
},
|
|
372
|
-
},
|
|
373
|
-
);
|
|
374
|
-
|
|
375
|
-
const lines = footer.render(120);
|
|
376
|
-
expect(lines.some((line) => line.includes("MiniMax:"))).toBe(true);
|
|
377
|
-
expect(lines.some((line) => line.includes("Workspace:"))).toBe(true);
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
it("survives a custom theme that does not define every color", () => {
|
|
381
|
-
const strictTheme = {
|
|
382
|
-
fg: (token: string, text: string) => {
|
|
383
|
-
if (token !== "accent") throw new Error(`Unknown theme color: ${token}`);
|
|
384
|
-
return text;
|
|
385
|
-
},
|
|
386
|
-
} as unknown as Theme;
|
|
387
|
-
|
|
388
|
-
const footer = createHarnessFooter(
|
|
389
|
-
{} as never,
|
|
390
|
-
strictTheme,
|
|
391
|
-
makeFooterData({
|
|
392
|
-
"harness-runtime": QUOTA,
|
|
393
|
-
"harness-workspace": WORKSPACE,
|
|
394
|
-
}),
|
|
395
|
-
{ getContext: () => ({}) as ExtensionContext },
|
|
396
|
-
);
|
|
397
|
-
|
|
398
|
-
const lines = footer.render(120);
|
|
399
|
-
expect(lines.some((line) => line.includes("MiniMax:"))).toBe(true);
|
|
400
|
-
expect(lines.some((line) => line.includes("Workspace:"))).toBe(true);
|
|
401
|
-
});
|
|
402
|
-
|
|
403
|
-
it("renders the session rows from the live context", () => {
|
|
404
|
-
const ctx = makeLiveCtx();
|
|
405
|
-
|
|
406
|
-
const footer = createHarnessFooter(
|
|
407
|
-
{} as never,
|
|
408
|
-
plainTheme,
|
|
409
|
-
makeFooterData({ "harness-runtime": QUOTA }),
|
|
410
|
-
{ getContext: () => ctx },
|
|
411
|
-
);
|
|
412
|
-
|
|
413
|
-
const lines = footer.render(160);
|
|
414
|
-
expect(lines[0]).toContain("pi-harness-runtime");
|
|
415
|
-
expect(lines[0]).toContain("main");
|
|
416
|
-
expect(lines[1]).toContain("↑100");
|
|
417
|
-
expect(lines[1]).toContain("$0.010");
|
|
418
|
-
expect(lines[1]).toContain("12.5%");
|
|
419
|
-
expect(lines[1]).toContain("MiniMax-M2");
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
describe("harness footer helpers", () => {
|
|
424
|
-
it("keeps a short status on one line", () => {
|
|
425
|
-
expect(wrapStatusText("Workspace: ~/app | OS: Linux", 120)).toEqual([
|
|
426
|
-
"Workspace: ~/app | OS: Linux",
|
|
427
|
-
]);
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
it("breaks a long status at the field borders and keeps every line inside the width", () => {
|
|
431
|
-
const lines = wrapStatusText("Workspace: ~/app | OS: Linux | RAM: 4/15", 24);
|
|
432
|
-
|
|
433
|
-
expect(lines.length).toBeGreaterThan(1);
|
|
434
|
-
expect(lines[0]).toContain("Workspace:");
|
|
435
|
-
expect(lines.slice(1).join(" ")).toContain("RAM: 4/15");
|
|
436
|
-
for (const line of lines) {
|
|
437
|
-
expect(visibleWidth(line)).toBeLessThanOrEqual(24);
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
it("breaks a word that is longer than the width", () => {
|
|
442
|
-
const lines = wrapStatusText(
|
|
443
|
-
"Workspace: /home/tester/a-very-long-directory-name/pi-harness-runtime",
|
|
444
|
-
20,
|
|
445
|
-
0,
|
|
446
|
-
);
|
|
447
|
-
|
|
448
|
-
expect(lines.length).toBeGreaterThan(1);
|
|
449
|
-
for (const line of lines) {
|
|
450
|
-
expect(visibleWidth(line)).toBeLessThanOrEqual(20);
|
|
451
|
-
}
|
|
452
|
-
expect(lines.join("")).toContain("pi-harness-runtime");
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
it("caps the number of lines and truncates the last one", () => {
|
|
456
|
-
const lines = wrapStatusText(
|
|
457
|
-
"Workspace: ~/app | OS: Linux | mode: UNKNOWN (no explicit NODE_ENV) | RAM: 4/15",
|
|
458
|
-
24,
|
|
459
|
-
2,
|
|
460
|
-
);
|
|
461
|
-
|
|
462
|
-
expect(lines.length).toBe(2);
|
|
463
|
-
expect(visibleWidth(lines[1]!)).toBeLessThanOrEqual(24);
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
it("says that the summary is incomplete when lines are dropped", () => {
|
|
467
|
-
const lines = wrapStatusText(
|
|
468
|
-
"Workspace: ~/app | OS: Linux | mode: UNKNOWN (no explicit NODE_ENV) | dev server: not detected | RAM: 4/15",
|
|
469
|
-
24,
|
|
470
|
-
2,
|
|
471
|
-
);
|
|
472
|
-
|
|
473
|
-
expect(lines.length).toBe(2);
|
|
474
|
-
// The marker survives the truncation - the user must be able to see
|
|
475
|
-
// that the summary is incomplete.
|
|
476
|
-
expect(lines[1]).toContain("more)");
|
|
477
|
-
expect(visibleWidth(lines[1]!)).toBeLessThanOrEqual(24);
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
it("wraps a single field that is longer than the width", () => {
|
|
481
|
-
const lines = wrapStatusText("mode: UNKNOWN (no explicit NODE_ENV)", 20);
|
|
482
|
-
|
|
483
|
-
expect(lines.length).toBeGreaterThan(1);
|
|
484
|
-
expect(lines.join(" ")).toContain("NODE_ENV");
|
|
485
|
-
});
|
|
486
|
-
|
|
487
|
-
it("renders one row per harness status", () => {
|
|
488
|
-
const lines = renderFooterRows(
|
|
489
|
-
makeSessionInfo(),
|
|
490
|
-
[
|
|
491
|
-
{ label: "quota", text: QUOTA },
|
|
492
|
-
{ label: "workspace", text: WORKSPACE, maxLines: 8 },
|
|
493
|
-
],
|
|
494
|
-
120,
|
|
495
|
-
plainTheme,
|
|
496
|
-
);
|
|
497
|
-
|
|
498
|
-
// pwd + stats + quota + workspace (the workspace value wraps when it
|
|
499
|
-
// does not fit into the width).
|
|
500
|
-
expect(lines.length).toBeGreaterThanOrEqual(4);
|
|
501
|
-
expect(lines[2]).toBe(QUOTA);
|
|
502
|
-
expect(lines[3]).toContain("Workspace:");
|
|
503
|
-
expect(lines.slice(3).join(" ")).toContain("RAM: 6.4/15");
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
it("keeps a short row on one line", () => {
|
|
507
|
-
const lines = renderFooterRows(
|
|
508
|
-
makeSessionInfo(),
|
|
509
|
-
[
|
|
510
|
-
{
|
|
511
|
-
label: "quota",
|
|
512
|
-
text: `${QUOTA} ${"x".repeat(200)}`,
|
|
513
|
-
},
|
|
514
|
-
],
|
|
515
|
-
40,
|
|
516
|
-
plainTheme,
|
|
517
|
-
);
|
|
518
|
-
|
|
519
|
-
// pwd + stats + ONE quota row (truncated, not wrapped).
|
|
520
|
-
expect(lines.length).toBe(3);
|
|
521
|
-
expect(visibleWidth(lines[2]!)).toBeLessThanOrEqual(40);
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
it("collapses the home directory to ~", () => {
|
|
525
|
-
expect(formatCwdForFooter("/home/tester/project", "/home/tester")).toBe(
|
|
526
|
-
"~/project",
|
|
527
|
-
);
|
|
528
|
-
expect(formatCwdForFooter("/home/tester", "/home/tester")).toBe("~");
|
|
529
|
-
expect(formatCwdForFooter("/opt/work", "/home/tester")).toBe("/opt/work");
|
|
530
|
-
// A sibling directory that merely shares the home prefix is NOT in home.
|
|
531
|
-
expect(formatCwdForFooter("/home/testerX", "/home/tester")).toBe(
|
|
532
|
-
"/home/testerX",
|
|
533
|
-
);
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
it("renders the context percent with one decimal", () => {
|
|
537
|
-
const lines = renderFooterRows(
|
|
538
|
-
makeSessionInfo({ contextPercent: 34.267 }),
|
|
539
|
-
[],
|
|
540
|
-
160,
|
|
541
|
-
plainTheme,
|
|
542
|
-
);
|
|
543
|
-
expect(lines[1]).toContain("34.3%");
|
|
544
|
-
expect(lines[1]).not.toContain("34.267%");
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
it("appends the (auto) indicator only when auto-compact is enabled", () => {
|
|
548
|
-
const withAuto = renderFooterRows(makeSessionInfo(), [], 160, plainTheme, true);
|
|
549
|
-
const withoutAuto = renderFooterRows(
|
|
550
|
-
makeSessionInfo(),
|
|
551
|
-
[],
|
|
552
|
-
160,
|
|
553
|
-
plainTheme,
|
|
554
|
-
false,
|
|
555
|
-
);
|
|
556
|
-
expect(withAuto[1]).toContain("(auto)");
|
|
557
|
-
expect(withoutAuto[1]).not.toContain("(auto)");
|
|
558
|
-
});
|
|
559
|
-
});
|