diff --git a/src/components/AbTestPicker.tsx b/src/components/AbTestPicker.tsx index 6e06e716e..712df2367 100644 --- a/src/components/AbTestPicker.tsx +++ b/src/components/AbTestPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface AbTestRow extends Record { abTestId: string; @@ -16,9 +16,9 @@ interface AbTestRow extends Record { export const abTestColumns = [ { key: "name", header: "name", flex: true }, - { key: "status", header: "status", width: 14 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "executionStatus", header: "execution", width: 12 }, - { key: "updatedAt", header: "updated UTC", width: 16, render: formatTimestamp }, + { key: "updatedAt", header: "updated UTC", width: TIMESTAMP_WIDTH, render: formatTimestamp }, ] satisfies DataTableColumn[]; function toRow(summary: ABTestSummary): AbTestRow { diff --git a/src/components/BatchEvaluationPicker.tsx b/src/components/BatchEvaluationPicker.tsx index ad6e45fa4..6967ea178 100644 --- a/src/components/BatchEvaluationPicker.tsx +++ b/src/components/BatchEvaluationPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; // BatchEvaluationRow is the flat, display-ready shape the table renders. It also // satisfies DataTable's `T extends Record` constraint, which the @@ -19,11 +19,11 @@ interface BatchEvaluationRow extends Record { export const batchEvaluationColumns = [ { key: "name", header: "name", flex: true }, - { key: "status", header: "status", width: 22 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/BatchInsightsPicker.tsx b/src/components/BatchInsightsPicker.tsx index 99e32a67c..324dae0d4 100644 --- a/src/components/BatchInsightsPicker.tsx +++ b/src/components/BatchInsightsPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface BatchInsightsRow extends Record { batchEvaluationId: string; @@ -15,11 +15,11 @@ interface BatchInsightsRow extends Record { const batchInsightsColumns = [ { key: "name", header: "name", flex: true }, - { key: "status", header: "status", width: 22 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/ConfigBundlePicker.tsx b/src/components/ConfigBundlePicker.tsx index 767542744..1d4e1e7eb 100644 --- a/src/components/ConfigBundlePicker.tsx +++ b/src/components/ConfigBundlePicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface ConfigBundleRow extends Record { bundleId: string; @@ -19,7 +19,7 @@ export const configBundleColumns = [ { key: "createdAt", header: "created UTC", - width: 16, + width: TIMESTAMP_WIDTH, minWidth: 11, render: formatTimestamp, }, diff --git a/src/components/ConfigBundleVersionPicker.tsx b/src/components/ConfigBundleVersionPicker.tsx index e03a195e6..135875fb4 100644 --- a/src/components/ConfigBundleVersionPicker.tsx +++ b/src/components/ConfigBundleVersionPicker.tsx @@ -3,7 +3,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface ConfigBundleVersionRow extends Record { versionId: string; @@ -19,7 +19,7 @@ export const configBundleVersionColumns = [ { key: "versionCreatedAt", header: "created UTC", - width: 16, + width: TIMESTAMP_WIDTH, minWidth: 11, render: formatTimestamp, }, diff --git a/src/components/DatasetPicker.tsx b/src/components/DatasetPicker.tsx index 9daa0f71a..353518058 100644 --- a/src/components/DatasetPicker.tsx +++ b/src/components/DatasetPicker.tsx @@ -4,7 +4,13 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { + COUNT_WIDTH, + NUMERIC_ALIGN, + STATUS_WIDTH, + TIMESTAMP_WIDTH, + type DataTableColumn, +} from "./ui/data-table"; interface DatasetRow extends Record { datasetId: string; @@ -17,13 +23,13 @@ interface DatasetRow extends Record { export const datasetColumns = [ { key: "datasetName", header: "name", flex: true }, - { key: "status", header: "status", width: 14 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "schemaType", header: "schema", width: 12 }, - { key: "exampleCount", header: "examples", width: 8 }, + { key: "exampleCount", header: "examples", width: COUNT_WIDTH, align: NUMERIC_ALIGN }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/EvaluatorPicker.tsx b/src/components/EvaluatorPicker.tsx index 1ff12dae8..00b6a0f00 100644 --- a/src/components/EvaluatorPicker.tsx +++ b/src/components/EvaluatorPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; // EvaluatorRow is the flat, display-ready shape the table renders. It also // satisfies DataTable's `T extends Record` constraint, which the @@ -24,7 +24,7 @@ export const evaluatorColumns = [ { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/GatewayConnectorPicker.tsx b/src/components/GatewayConnectorPicker.tsx index 4cfe16d0d..fd236e1d9 100644 --- a/src/components/GatewayConnectorPicker.tsx +++ b/src/components/GatewayConnectorPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface GatewayConnectorRow extends Record { targetId: string; @@ -15,11 +15,11 @@ interface GatewayConnectorRow extends Record { export const gatewayConnectorColumns = [ { key: "name", header: "name", flex: true }, - { key: "status", header: "status", width: 18 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/GatewayPicker.tsx b/src/components/GatewayPicker.tsx index 9da7ff6a1..5949abe1e 100644 --- a/src/components/GatewayPicker.tsx +++ b/src/components/GatewayPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface GatewayRow extends Record { gatewayId: string; @@ -17,13 +17,13 @@ interface GatewayRow extends Record { export const gatewayColumns = [ { key: "name", header: "name", flex: true }, - { key: "status", header: "status", width: 16 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "protocol", header: "protocol", width: 12 }, { key: "authorizer", header: "authorizer", width: 18 }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/GatewayRulePicker.tsx b/src/components/GatewayRulePicker.tsx index aeefa3594..a1400bebf 100644 --- a/src/components/GatewayRulePicker.tsx +++ b/src/components/GatewayRulePicker.tsx @@ -3,7 +3,7 @@ import { useNavigate } from "react-router"; import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { COUNT_WIDTH, NUMERIC_ALIGN, STATUS_WIDTH, type DataTableColumn } from "./ui/data-table"; interface GatewayRuleRow extends Record { ruleId: string; @@ -13,8 +13,8 @@ interface GatewayRuleRow extends Record { } export const gatewayRuleColumns = [ - { key: "priority", header: "priority", width: 10 }, - { key: "status", header: "status", width: 13 }, + { key: "priority", header: "priority", width: COUNT_WIDTH, align: NUMERIC_ALIGN }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "description", header: "description", flex: true }, { key: "ruleId", diff --git a/src/components/GatewayTargetPicker.tsx b/src/components/GatewayTargetPicker.tsx index 3508bb4b6..4095fcb7e 100644 --- a/src/components/GatewayTargetPicker.tsx +++ b/src/components/GatewayTargetPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface GatewayTargetRow extends Record { targetId: string; @@ -17,11 +17,11 @@ interface GatewayTargetRow extends Record { export const gatewayTargetColumns = [ { key: "name", header: "name", flex: true }, { key: "type", header: "type", width: 18 }, - { key: "status", header: "status", width: 18 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/HarnessEndpointPicker.tsx b/src/components/HarnessEndpointPicker.tsx index b479d5615..997190e45 100644 --- a/src/components/HarnessEndpointPicker.tsx +++ b/src/components/HarnessEndpointPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { FLAG_ALIGN, STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; // EndpointRow is the flat, display-ready shape the table renders. interface EndpointRow extends Record { @@ -17,13 +17,13 @@ interface EndpointRow extends Record { export const harnessEndpointColumns = [ { key: "endpointName", header: "name", flex: true }, - { key: "liveVersion", header: "live", width: 6, minWidth: 5 }, - { key: "targetVersion", header: "target", width: 6 }, - { key: "status", header: "status", width: 13 }, + { key: "liveVersion", header: "live", width: 6, minWidth: 5, align: FLAG_ALIGN }, + { key: "targetVersion", header: "target", width: 6, align: FLAG_ALIGN }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/HarnessPicker.tsx b/src/components/HarnessPicker.tsx index 85b7a5bb6..a6e9da370 100644 --- a/src/components/HarnessPicker.tsx +++ b/src/components/HarnessPicker.tsx @@ -4,7 +4,13 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { + NUMERIC_ALIGN, + STATUS_WIDTH, + TIMESTAMP_WIDTH, + VERSION_WIDTH, + type DataTableColumn, +} from "./ui/data-table"; // HarnessRow is the flat, display-ready shape the table renders. It also satisfies // DataTable's `T extends Record` constraint, which the SDK's @@ -19,12 +25,12 @@ interface HarnessRow extends Record { export const harnessColumns = [ { key: "harnessName", header: "name", flex: true }, - { key: "harnessVersion", header: "version", width: 7 }, - { key: "status", header: "status", width: 13 }, + { key: "harnessVersion", header: "version", width: VERSION_WIDTH, align: NUMERIC_ALIGN }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/HarnessVersionPicker.tsx b/src/components/HarnessVersionPicker.tsx index 72af713ce..2ee02d237 100644 --- a/src/components/HarnessVersionPicker.tsx +++ b/src/components/HarnessVersionPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; // VersionRow is the flat, display-ready shape the table renders. interface VersionRow extends Record { @@ -16,11 +16,11 @@ interface VersionRow extends Record { export const harnessVersionColumns = [ { key: "harnessVersion", header: "version", flex: true }, - { key: "status", header: "status", width: 13, minWidth: 6 }, + { key: "status", header: "status", width: STATUS_WIDTH, minWidth: 6 }, { key: "createdAt", header: "created UTC", - width: 16, + width: TIMESTAMP_WIDTH, minWidth: 11, render: formatTimestamp, }, diff --git a/src/components/MemoryPicker.tsx b/src/components/MemoryPicker.tsx index c398df451..e4c33bac4 100644 --- a/src/components/MemoryPicker.tsx +++ b/src/components/MemoryPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface MemoryRow extends Record { memoryId: string; @@ -14,11 +14,11 @@ interface MemoryRow extends Record { export const memoryColumns = [ { key: "memoryId", header: "id", flex: true }, - { key: "status", header: "status", width: 13 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/OnlineEvalPicker.tsx b/src/components/OnlineEvalPicker.tsx index d83711ac7..5d3a2f163 100644 --- a/src/components/OnlineEvalPicker.tsx +++ b/src/components/OnlineEvalPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; // OnlineEvalRow is the flat, display-ready shape the table renders. It also // satisfies DataTable's `T extends Record` constraint, which the @@ -21,12 +21,12 @@ interface OnlineEvalRow extends Record { export const onlineEvalColumns = [ { key: "configName", header: "name", flex: true }, - { key: "status", header: "status", width: 12 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "executionStatus", header: "execution", width: 11 }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/OnlineInsightPicker.tsx b/src/components/OnlineInsightPicker.tsx index e14fe9208..c7a7f1f23 100644 --- a/src/components/OnlineInsightPicker.tsx +++ b/src/components/OnlineInsightPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; // OnlineInsightRow is the flat, display-ready shape the table renders. It also // satisfies DataTable's `T extends Record` constraint, which the @@ -21,12 +21,12 @@ interface OnlineInsightRow extends Record { const onlineInsightColumns = [ { key: "configName", header: "name", flex: true }, - { key: "status", header: "status", width: 12 }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "executionStatus", header: "execution", width: 11 }, { key: "updatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/PaginatedTablePicker.test.tsx b/src/components/PaginatedTablePicker.test.tsx index 497fbdfc4..c52179b7a 100644 --- a/src/components/PaginatedTablePicker.test.tsx +++ b/src/components/PaginatedTablePicker.test.tsx @@ -356,8 +356,8 @@ describe("paginated table picker contract", () => { core.runtime.setListResponse({ agentRuntimes: [ runtime({ - agentRuntimeId: "page-one", - agentRuntimeName: "matching-page-one", + agentRuntimeId: "matching-page-one", + agentRuntimeName: "page-one", }), ], nextToken: "t2", @@ -366,8 +366,8 @@ describe("paginated table picker contract", () => { { agentRuntimes: [ runtime({ - agentRuntimeId: "page-two", - agentRuntimeName: "matching-page-two", + agentRuntimeId: "matching-page-two", + agentRuntimeName: "page-two", }), ], }, @@ -465,11 +465,13 @@ describe("paginated table picker contract", () => { for (const width of [100, 80, 60]) { if (width !== 100) await r.resize(width); const lines = (r.lastFrame() ?? "").split("\n"); - const headerIndex = lines.findIndex((line) => line.includes("id suffix")); + const headerIndex = lines.findIndex((line) => line.includes("version")); const rowLines = suffixes.map((suffix) => lines.find((line) => line.includes(suffix))); expect(headerIndex).toBeGreaterThanOrEqual(0); - expect(stringWidth(lines[headerIndex + 1]!)).toBe(width); + // The rule under the header spans the table, which stops short of a wide + // terminal once the identifier column has reached its ceiling. + expect(stringWidth(lines[headerIndex + 1]!)).toBeLessThanOrEqual(width); expect(rowLines.every((line) => line !== undefined)).toBe(true); expect(new Set(rowLines.map((line) => lines.indexOf(line!))).size).toBe(suffixes.length); expect(rowLines.every((line) => stringWidth(line!) <= width)).toBe(true); diff --git a/src/components/RuntimeEndpointPicker.tsx b/src/components/RuntimeEndpointPicker.tsx index fc46edcc3..e6efbda5d 100644 --- a/src/components/RuntimeEndpointPicker.tsx +++ b/src/components/RuntimeEndpointPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { FLAG_ALIGN, STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface RuntimeEndpointRow extends Record { qualifier: string; @@ -16,13 +16,13 @@ interface RuntimeEndpointRow extends Record { export const runtimeEndpointColumns = [ { key: "qualifier", header: "qualifier", flex: true }, - { key: "liveVersion", header: "live", width: 6, minWidth: 5 }, - { key: "targetVersion", header: "target", width: 6 }, - { key: "status", header: "status", width: 13 }, + { key: "liveVersion", header: "live", width: 6, minWidth: 5, align: FLAG_ALIGN }, + { key: "targetVersion", header: "target", width: 6, align: FLAG_ALIGN }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "lastUpdatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; diff --git a/src/components/RuntimePicker.tsx b/src/components/RuntimePicker.tsx index cc46466b7..ef9b4d801 100644 --- a/src/components/RuntimePicker.tsx +++ b/src/components/RuntimePicker.tsx @@ -4,44 +4,40 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { + NUMERIC_ALIGN, + STATUS_WIDTH, + TIMESTAMP_WIDTH, + VERSION_WIDTH, + type DataTableColumn, +} from "./ui/data-table"; interface RuntimeRow extends Record { runtimeId: string; - runtimeName: string; runtimeVersion: string; status: string; lastUpdatedAt: string; } -function runtimeIdSuffix(value: unknown): string { - const id = String(value ?? ""); - return id.slice(id.lastIndexOf("-") + 1); -} - +// The control plane derives a Runtime's ID from its name (`orders-Ab12Cd34Ef`), +// so the ID column carries the name already; splitting the suffix out would +// only show the same value twice. export const runtimeColumns = [ - { key: "runtimeName", header: "name", flex: true }, - { - key: "runtimeId", - header: "id suffix", - width: 10, - render: runtimeIdSuffix, - }, - { key: "runtimeVersion", header: "version", width: 7 }, - { key: "status", header: "status", width: 13 }, + { key: "runtimeId", header: "id", flex: true }, + { key: "runtimeVersion", header: "version", width: VERSION_WIDTH, align: NUMERIC_ALIGN }, + { key: "status", header: "status", width: STATUS_WIDTH }, { key: "lastUpdatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, render: formatTimestamp, }, ] satisfies DataTableColumn[]; function toRow(runtime: AgentRuntime): RuntimeRow { - const runtimeId = runtime.agentRuntimeId ?? ""; + const runtimeId = runtime.agentRuntimeId ?? runtime.agentRuntimeName ?? ""; return { runtimeId, - runtimeName: runtime.agentRuntimeName ?? runtimeId, runtimeVersion: runtime.agentRuntimeVersion ?? "-", status: runtime.status ?? "-", lastUpdatedAt: runtime.lastUpdatedAt?.toISOString() ?? "-", diff --git a/src/components/RuntimeVersionPicker.tsx b/src/components/RuntimeVersionPicker.tsx index f589d5a0c..69f076341 100644 --- a/src/components/RuntimeVersionPicker.tsx +++ b/src/components/RuntimeVersionPicker.tsx @@ -4,7 +4,7 @@ import type { ScreenProps } from "../handlers/types"; import { coreOptsFromCtx } from "../handlers/utils"; import { formatTimestamp } from "./formatTimestamp"; import { PaginatedTablePicker } from "./PaginatedTablePicker"; -import type { DataTableColumn } from "./ui/data-table"; +import { STATUS_WIDTH, TIMESTAMP_WIDTH, type DataTableColumn } from "./ui/data-table"; interface RuntimeVersionRow extends Record { version: string; @@ -14,11 +14,11 @@ interface RuntimeVersionRow extends Record { export const runtimeVersionColumns = [ { key: "version", header: "version", flex: true }, - { key: "status", header: "status", width: 13, minWidth: 6 }, + { key: "status", header: "status", width: STATUS_WIDTH, minWidth: 6 }, { key: "lastUpdatedAt", header: "updated UTC", - width: 16, + width: TIMESTAMP_WIDTH, minWidth: 11, render: formatTimestamp, }, diff --git a/src/components/ui/data-table/columnPresets.ts b/src/components/ui/data-table/columnPresets.ts new file mode 100644 index 000000000..4616e86f5 --- /dev/null +++ b/src/components/ui/data-table/columnPresets.ts @@ -0,0 +1,33 @@ +/** + * Shared column geometry, so the same kind of value is the same width and the + * same alignment in every table. Before these existed each picker picked its + * own numbers and `status` ended up anywhere between 12 and 22 cells wide. + */ + +/** Fits `2026-08-14 09:41` exactly, the format every timestamp column renders. */ +export const TIMESTAMP_WIDTH = 16; + +/** + * Fits the longest status the control plane returns, `UPDATE_UNSUCCESSFUL` + * (19), plus a cell of breathing room before the next column. + */ +export const STATUS_WIDTH = 20; + +/** Version and revision numbers, right-aligned so the digits stack. */ +export const VERSION_WIDTH = 7; + +/** Small counts and priorities, right-aligned for the same reason. */ +export const COUNT_WIDTH = 8; + +/** + * Numeric columns are right-aligned so values of different magnitude share + * their ones place; text columns keep the default left edge. + */ +export const NUMERIC_ALIGN = "right" as const; + +/** + * Narrow, fixed-vocabulary flag columns (`live`, `target`) hold one or two + * characters, so centering keeps the value under its own header instead of + * stranding it at the far left edge of a header twice its width. + */ +export const FLAG_ALIGN = "center" as const; diff --git a/src/components/ui/data-table/columnWidths.test.ts b/src/components/ui/data-table/columnWidths.test.ts index 0d5064c9e..93fb95f86 100644 --- a/src/components/ui/data-table/columnWidths.test.ts +++ b/src/components/ui/data-table/columnWidths.test.ts @@ -12,6 +12,7 @@ import { runtimeColumns } from "../../RuntimePicker"; import { runtimeVersionColumns } from "../../RuntimeVersionPicker"; import { computeColumnWidths, + FLEX_MAX_WIDTH, FLEX_MIN_WIDTH, resolveBorderWidth, SELECTION_MARKER_WIDTH, @@ -41,28 +42,50 @@ describe("computeColumnWidths", () => { selectable: true, borderWidth: 0, }); - - expect(result.totalWidth).toBe(terminalWidth); - expect(result.widths[config.flexIndex]!).toBeGreaterThanOrEqual(FLEX_MIN_WIDTH); + const flexWidth = result.widths[config.flexIndex]!; + + expect(result.totalWidth).toBeLessThanOrEqual(terminalWidth); + expect(flexWidth).toBeGreaterThanOrEqual(FLEX_MIN_WIDTH); + expect(flexWidth).toBeLessThanOrEqual(FLEX_MAX_WIDTH); + // The table only stops short of the terminal edge once the flexible + // column has hit its ceiling; the remainder is deliberate right margin. + if (result.totalWidth !== terminalWidth) expect(flexWidth).toBe(FLEX_MAX_WIDTH); } }); } test("drops fixed columns from right to left without truncating headers", () => { expect(computeColumnWidths(runtimeColumns, 40, { selectable: true, borderWidth: 0 })).toEqual({ - widths: [19, 10, 7, undefined, undefined], + widths: [30, 7, undefined, undefined], totalWidth: 40, }); expect(computeColumnWidths(runtimeColumns, 60, { selectable: true, borderWidth: 0 })).toEqual({ - widths: [25, 10, 7, 13, undefined], + widths: [29, 7, 20, undefined], totalWidth: 60, }); expect(computeColumnWidths(runtimeColumns, 80, { selectable: true, borderWidth: 0 })).toEqual({ - widths: [28, 10, 7, 13, 16], + widths: [32, 7, 20, 16], totalWidth: 80, }); }); + test("caps the flexible column and leaves the leftover as right margin", () => { + for (const terminalWidth of [100, 160, 200]) { + expect( + computeColumnWidths(runtimeColumns, terminalWidth, { selectable: true, borderWidth: 0 }), + ).toEqual({ widths: [FLEX_MAX_WIDTH, 7, 20, 16], totalWidth: 88 }); + } + }); + + test("honors a per-column flex ceiling below the shared default", () => { + const columns = [{ flex: true as const, maxWidth: 24 }, { width: 6 }]; + + expect(computeColumnWidths(columns, 200, { selectable: false, borderWidth: 0 })).toEqual({ + widths: [24, 6], + totalWidth: 31, + }); + }); + test("defaults minWidth to width and honors explicit shrink floors", () => { const columns = [{ width: 6 }, { width: 6, minWidth: 4 }]; @@ -106,7 +129,7 @@ describe("computeColumnWidths", () => { borderWidth: 0, }); - expect(runtime.widths[2]).toBe(7); + expect(runtime.widths[1]).toBe(7); expect(harness.widths[1]).toBe(7); expect(endpoint.widths[1]).toBe(6); expect(endpoint.widths[2]).toBe(6); diff --git a/src/components/ui/data-table/columnWidths.ts b/src/components/ui/data-table/columnWidths.ts index 8e57b7a99..f3f1f297c 100644 --- a/src/components/ui/data-table/columnWidths.ts +++ b/src/components/ui/data-table/columnWidths.ts @@ -1,9 +1,16 @@ export const COLUMN_GAP = 1; export const FLEX_MIN_WIDTH = 16; export const SELECTION_MARKER_WIDTH = 1; +/** + * How wide a flexible column may grow before the leftover terminal width is + * left as right margin instead. Without a ceiling the flexible column absorbs + * every spare cell, so on a wide terminal the identifier ends up separated + * from its own metadata by a canyon of blank space. + */ +export const FLEX_MAX_WIDTH = 40; export type ColumnSizing = - | { flex: true; width?: never; minWidth?: never } + | { flex: true; maxWidth?: number; width?: never; minWidth?: never } | { flex?: false; width: number; minWidth?: number }; export type ComputedColumnWidths = { @@ -81,9 +88,12 @@ export function computeColumnWidths( for (const column of fixedColumns) widths[column.index] = column.width; if (flexIndex !== -1) { + const flexColumn = columns[flexIndex]!; + const ceiling = flexColumn.flex === true ? (flexColumn.maxWidth ?? FLEX_MAX_WIDTH) : undefined; + const available = frameWidth - markerWidth - visibleFixedWidth() - gapWidth(); widths[flexIndex] = Math.max( FLEX_MIN_WIDTH, - frameWidth - markerWidth - visibleFixedWidth() - gapWidth(), + ceiling === undefined ? available : Math.min(available, ceiling), ); } diff --git a/src/components/ui/data-table/index.ts b/src/components/ui/data-table/index.ts index 592e2f416..518b00837 100644 --- a/src/components/ui/data-table/index.ts +++ b/src/components/ui/data-table/index.ts @@ -1,2 +1,10 @@ export { DataTable } from "./DataTable.js"; export type { DataTableProps, DataTableColumn } from "./DataTable.js"; +export { + COUNT_WIDTH, + FLAG_ALIGN, + NUMERIC_ALIGN, + STATUS_WIDTH, + TIMESTAMP_WIDTH, + VERSION_WIDTH, +} from "./columnPresets.js"; diff --git a/src/handlers/identity/api-key-credential-provider/list/screen.tsx b/src/handlers/identity/api-key-credential-provider/list/screen.tsx index d3db7ba41..ad998cc1c 100644 --- a/src/handlers/identity/api-key-credential-provider/list/screen.tsx +++ b/src/handlers/identity/api-key-credential-provider/list/screen.tsx @@ -2,7 +2,7 @@ import type { ApiKeyCredentialProviderItem } from "@aws-sdk/client-bedrock-agent import { useNavigate } from "react-router"; import { formatTimestamp } from "../../../../components/formatTimestamp"; import { PaginatedTablePicker } from "../../../../components/PaginatedTablePicker"; -import type { DataTableColumn } from "../../../../components/ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "../../../../components/ui/data-table"; import type { ScreenProps } from "../../../types"; import { coreOptsFromCtx } from "../../../utils"; @@ -17,8 +17,8 @@ interface ApiKeyProviderRow extends Record { export const apiKeyProviderColumns = [ { key: "name", header: "name", flex: true }, - { key: "createdAt", header: "created UTC", width: 16, render: formatTimestamp }, - { key: "updatedAt", header: "updated UTC", width: 16, render: formatTimestamp }, + { key: "createdAt", header: "created UTC", width: TIMESTAMP_WIDTH, render: formatTimestamp }, + { key: "updatedAt", header: "updated UTC", width: TIMESTAMP_WIDTH, render: formatTimestamp }, ] satisfies DataTableColumn[]; function toRow(provider: ApiKeyCredentialProviderItem): ApiKeyProviderRow { diff --git a/src/handlers/identity/oauth2-credential-provider/list/screen.tsx b/src/handlers/identity/oauth2-credential-provider/list/screen.tsx index b99dd53f7..de254f724 100644 --- a/src/handlers/identity/oauth2-credential-provider/list/screen.tsx +++ b/src/handlers/identity/oauth2-credential-provider/list/screen.tsx @@ -2,7 +2,7 @@ import type { Oauth2CredentialProviderItem } from "@aws-sdk/client-bedrock-agent import { useNavigate } from "react-router"; import { formatTimestamp } from "../../../../components/formatTimestamp"; import { PaginatedTablePicker } from "../../../../components/PaginatedTablePicker"; -import type { DataTableColumn } from "../../../../components/ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "../../../../components/ui/data-table"; import type { ScreenProps } from "../../../types"; import { coreOptsFromCtx } from "../../../utils"; @@ -19,8 +19,8 @@ interface Oauth2ProviderRow extends Record { export const oauth2ProviderColumns = [ { key: "name", header: "name", flex: true }, { key: "vendor", header: "vendor", width: 18 }, - { key: "createdAt", header: "created UTC", width: 16, render: formatTimestamp }, - { key: "updatedAt", header: "updated UTC", width: 16, render: formatTimestamp }, + { key: "createdAt", header: "created UTC", width: TIMESTAMP_WIDTH, render: formatTimestamp }, + { key: "updatedAt", header: "updated UTC", width: TIMESTAMP_WIDTH, render: formatTimestamp }, ] satisfies DataTableColumn[]; function toRow(provider: Oauth2CredentialProviderItem): Oauth2ProviderRow { diff --git a/src/handlers/memory/event/list/screen.tsx b/src/handlers/memory/event/list/screen.tsx index f203ee0b9..c3d9bd8be 100644 --- a/src/handlers/memory/event/list/screen.tsx +++ b/src/handlers/memory/event/list/screen.tsx @@ -3,7 +3,7 @@ import { useNavigate, useParams } from "react-router"; import { MemoryPicker } from "../../../../components/MemoryPicker"; import { PaginatedTablePicker } from "../../../../components/PaginatedTablePicker"; import { formatTimestamp } from "../../../../components/formatTimestamp"; -import type { DataTableColumn } from "../../../../components/ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "../../../../components/ui/data-table"; import type { ScreenProps } from "../../../types"; import { coreOptsFromCtx } from "../../../utils"; import { MemoryActorPicker, MemorySessionPicker } from "../../listPickers"; @@ -20,7 +20,7 @@ const eventColumns = [ { key: "occurredAt", header: "occurred UTC", - width: 16, + width: TIMESTAMP_WIDTH, minWidth: 11, render: formatTimestamp, }, diff --git a/src/handlers/memory/listPickers.tsx b/src/handlers/memory/listPickers.tsx index 02cedb49f..c00a100cf 100644 --- a/src/handlers/memory/listPickers.tsx +++ b/src/handlers/memory/listPickers.tsx @@ -1,7 +1,7 @@ import type { ActorSummary, SessionSummary } from "@aws-sdk/client-bedrock-agentcore"; import { PaginatedTablePicker } from "../../components/PaginatedTablePicker"; import { formatTimestamp } from "../../components/formatTimestamp"; -import type { DataTableColumn } from "../../components/ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "../../components/ui/data-table"; import type { ScreenProps } from "../types"; import { coreOptsFromCtx } from "../utils"; @@ -74,7 +74,7 @@ const sessionColumns = [ { key: "createdAt", header: "created UTC", - width: 16, + width: TIMESTAMP_WIDTH, minWidth: 11, render: formatTimestamp, }, diff --git a/src/handlers/memory/record/list/screen.tsx b/src/handlers/memory/record/list/screen.tsx index c720ea36c..66e6ab730 100644 --- a/src/handlers/memory/record/list/screen.tsx +++ b/src/handlers/memory/record/list/screen.tsx @@ -9,7 +9,7 @@ import { MemoryPicker } from "../../../../components/MemoryPicker"; import { PaginatedTablePicker } from "../../../../components/PaginatedTablePicker"; import { formatTimestamp } from "../../../../components/formatTimestamp"; import { darkTheme } from "../../../../components/ui/_core"; -import type { DataTableColumn } from "../../../../components/ui/data-table"; +import { TIMESTAMP_WIDTH, type DataTableColumn } from "../../../../components/ui/data-table"; import type { ScreenProps } from "../../../types"; import { coreOptsFromCtx } from "../../../utils"; @@ -40,7 +40,7 @@ const recordColumns = [ { key: "createdAt", header: "created UTC", - width: 16, + width: TIMESTAMP_WIDTH, minWidth: 16, render: formatTimestamp, }, diff --git a/src/handlers/runtime/endpoint/endpoint.screen.test.tsx b/src/handlers/runtime/endpoint/endpoint.screen.test.tsx index 5c821472f..05ee4c9c1 100644 --- a/src/handlers/runtime/endpoint/endpoint.screen.test.tsx +++ b/src/handlers/runtime/endpoint/endpoint.screen.test.tsx @@ -91,7 +91,7 @@ async function waitForRuntimePicker(lastFrame: () => string | undefined): Promis return ( frame.includes("agentcore → runtime → endpoint → list") && !frame.includes("agentcore → runtime → endpoint → list → runtime-123") && - frame.includes("checkout") + frame.includes("runtime-123") ); }); } @@ -108,7 +108,7 @@ describe("Runtime endpoint flow", () => { }); const r = renderScreen("/agentcore/runtime/endpoint/list", { core }); - await waitForText(r.lastFrame, "pick-runtime"); + await waitForText(r.lastFrame, runtimeId); await r.press("return"); await waitForText(r.lastFrame, "agentcore → runtime → endpoint → list → runtime/blue one"); await waitForText(r.lastFrame, "prod"); @@ -324,7 +324,7 @@ describe("Runtime endpoint flow", () => { const parent = renderScreen("/agentcore/runtime/endpoint/list", { core: parentCore, }); - await waitForText(parent.lastFrame, "checkout"); + await waitForText(parent.lastFrame, "runtime-123"); await parent.press("escape"); await waitForText( parent.lastFrame, @@ -341,7 +341,7 @@ describe("Runtime endpoint flow", () => { }); listCore.runtime.setGetEndpointResponse(getEndpointResponse()); const list = renderScreen("/agentcore/runtime/endpoint/list", { core: listCore }); - await waitForText(list.lastFrame, "checkout"); + await waitForText(list.lastFrame, "runtime-123"); await list.press("return"); await waitForText(list.lastFrame, "prod"); await list.press("escape"); @@ -358,7 +358,7 @@ describe("Runtime endpoint flow", () => { test("bare endpoint get redirects to parent selection", async () => { const core = new TestCoreClient(); core.runtime.setListResponse({ - agentRuntimes: [runtime({ agentRuntimeName: "redirect-parent" })], + agentRuntimes: [runtime({ agentRuntimeId: "redirect-parent" })], }); const r = renderScreen("/agentcore/runtime/endpoint/get", { core }); diff --git a/src/handlers/runtime/invoke/invoke.screen.test.tsx b/src/handlers/runtime/invoke/invoke.screen.test.tsx index a642a84e8..e03f288a2 100644 --- a/src/handlers/runtime/invoke/invoke.screen.test.tsx +++ b/src/handlers/runtime/invoke/invoke.screen.test.tsx @@ -92,7 +92,7 @@ describe("Runtime invoke routing", () => { } as GetAgentRuntimeResponse); const screen = renderScreen("/agentcore/runtime/invoke", { core }); - await waitForText(screen.lastFrame, "pick-runtime"); + await waitForText(screen.lastFrame, runtimeId); await screen.press("return"); await waitForText(screen.lastFrame, qualifier); await screen.press("return"); @@ -107,7 +107,7 @@ describe("Runtime invoke routing", () => { test("esc from an initial endpoint picker returns to the Runtime picker", async () => { const core = new TestCoreClient(); core.runtime.setListEndpointsResponse({ runtimeEndpoints: [endpoint()] }).setListResponse({ - agentRuntimes: [runtime({ agentRuntimeName: "back-to-runtime-picker" })], + agentRuntimes: [runtime({ agentRuntimeId: "back-to-runtime-picker" })], }); const screen = renderScreen(`/agentcore/runtime/invoke/${RUNTIME_ID}`, { core }); @@ -794,7 +794,7 @@ describe("Runtime invoke JSON console", () => { await waitForText(screen.lastFrame, "Context user/JWT/1h"); core.runtime.setGetResponse({ agentRuntimeArn: nextArn } as GetAgentRuntimeResponse); await screen.write("\x14"); - await waitForText(screen.lastFrame, "next-runtime"); + await waitForText(screen.lastFrame, nextRuntimeId); await screen.press("down"); await screen.press("return"); await waitForText(screen.lastFrame, nextQualifier); diff --git a/src/handlers/runtime/runtime.screen.test.tsx b/src/handlers/runtime/runtime.screen.test.tsx index dff9eb0f5..e37feaf21 100644 --- a/src/handlers/runtime/runtime.screen.test.tsx +++ b/src/handlers/runtime/runtime.screen.test.tsx @@ -20,7 +20,7 @@ const runtimeEndpointUrl = "https://runtime.test"; function runtime(overrides: Partial = {}): AgentRuntime { return { agentRuntimeArn: "arn:aws:bedrock-agentcore:us-east-1:123456789012:runtime/runtime-1", - agentRuntimeId: "runtime-1", + agentRuntimeId: "checkout-Ab12Cd34Ef", agentRuntimeVersion: "7", agentRuntimeName: "checkout", description: "Checkout Runtime", @@ -84,14 +84,15 @@ describe("runtime picker", () => { await waitForText(r.lastFrame, "orders"); const frame = r.lastFrame()!; - expect(frame).toContain("name"); expect(frame).toContain("id"); - expect(frame).toContain("id suffix"); expect(frame).toContain("version"); expect(frame).toContain("status"); expect(frame).toContain("updated UTC"); - expect(frame).toContain("AbCdEf1234"); - expect(frame).not.toContain("orders-AbCdEf1234"); + // One identifier column, carrying the whole ID: the control plane derives it + // from the name, so a separate name or suffix column would only repeat it. + expect(frame).toContain("orders-AbCdEf1234"); + expect(frame).not.toContain("name"); + expect(frame).not.toContain("id suffix"); expect(frame).toContain("99999"); expect(frame).toContain("CREATE_FAILED"); expect(frame).toContain("2026-07-19 01:02"); @@ -149,7 +150,9 @@ describe("runtime picker", () => { }); test("bare Runtime get redirects to the picker", async () => { - const core = coreWithRuntimes([runtime({ agentRuntimeName: "redirected" })]); + const core = coreWithRuntimes([ + runtime({ agentRuntimeId: "redirected-Ab12Cd34Ef", agentRuntimeName: "redirected" }), + ]); const r = renderScreen("/agentcore/runtime/get", { core }); await waitForText(r.lastFrame, "redirected"); @@ -236,7 +239,7 @@ describe("runtime hub", () => { ); const r = renderScreen("/agentcore/runtime/list", { core }); - await waitForText(r.lastFrame, "encoded-runtime"); + await waitForText(r.lastFrame, runtimeId); await r.press("return"); await waitForText(r.lastFrame, `agentcore → runtime → get → ${runtimeId}`); await waitFor(() => @@ -386,7 +389,7 @@ describe("runtime hub", () => { core.runtime.setGetResponse(getRuntimeResponse()); const r = renderScreen("/agentcore/runtime/list", { core }); - await waitForText(r.lastFrame, "checkout"); + await waitForText(r.lastFrame, "runtime-123"); await r.press("return"); await waitForText(r.lastFrame, "show the full JSON definition"); await r.press("escape"); @@ -398,7 +401,7 @@ describe("runtime hub", () => { core.runtime.setGetResponse(getRuntimeResponse()); const r = renderScreen("/agentcore/runtime/list", { core }); - await waitForText(r.lastFrame, "checkout"); + await waitForText(r.lastFrame, "runtime-123"); await r.press("return"); await waitForText(r.lastFrame, "show the full JSON definition"); for (let index = 0; index < 3; index += 1) await r.press("down"); @@ -431,7 +434,7 @@ describe("runtime hub", () => { }); const r = renderScreen("/agentcore/runtime/list", { core }); - await waitForText(r.lastFrame, "checkout"); + await waitForText(r.lastFrame, "runtime-123"); await r.press("return"); await waitForText(r.lastFrame, "invoke this Runtime"); const listCallsBeforeInvoke = core.runtime.calls.filter( @@ -457,7 +460,7 @@ describe("runtime hub", () => { hubCore.runtime.getRuntime = async () => hubPending.promise; const hub = renderScreen("/agentcore/runtime/list", { core: hubCore }); - await waitForText(hub.lastFrame, "checkout"); + await waitForText(hub.lastFrame, "runtime-123"); await hub.press("return"); await waitForText(hub.lastFrame, "Loading Runtime…"); await hub.press("escape"); @@ -471,7 +474,7 @@ describe("runtime hub", () => { }; const hub = renderScreen("/agentcore/runtime/list", { core: hubCore }); - await waitForText(hub.lastFrame, "checkout"); + await waitForText(hub.lastFrame, "runtime-123"); await hub.press("return"); await waitForText(hub.lastFrame, "hub failed"); await hub.press("escape"); @@ -482,7 +485,7 @@ describe("runtime hub", () => { jsonCore.runtime.setGetResponse(getRuntimeResponse()); const json = renderScreen("/agentcore/runtime/list", { core: jsonCore }); - await waitForText(json.lastFrame, "checkout"); + await waitForText(json.lastFrame, "runtime-123"); await json.press("return"); await waitForText(json.lastFrame, "show the full JSON definition"); jsonCore.runtime.setError(new Error("json failed")); diff --git a/src/handlers/runtime/version/version.screen.test.tsx b/src/handlers/runtime/version/version.screen.test.tsx index 1d19bd748..53d801b68 100644 --- a/src/handlers/runtime/version/version.screen.test.tsx +++ b/src/handlers/runtime/version/version.screen.test.tsx @@ -57,7 +57,7 @@ async function waitForRuntimePicker(lastFrame: () => string | undefined): Promis return ( frame.includes("agentcore → runtime → version → list") && !frame.includes("agentcore → runtime → version → list → runtime-123") && - frame.includes("checkout") + frame.includes("runtime-123") ); }); } @@ -74,7 +74,7 @@ describe("Runtime version flow", () => { }); const r = renderScreen("/agentcore/runtime/version/list", { core }); - await waitForText(r.lastFrame, "pick-runtime"); + await waitForText(r.lastFrame, runtimeId); await r.press("return"); await waitForText(r.lastFrame, "agentcore → runtime → version → list → runtime/blue one"); await waitForText(r.lastFrame, "9"); @@ -220,7 +220,7 @@ describe("Runtime version flow", () => { const parent = renderScreen("/agentcore/runtime/version/list", { core: parentCore, }); - await waitForText(parent.lastFrame, "checkout"); + await waitForText(parent.lastFrame, "runtime-123"); await parent.press("escape"); await waitForText( parent.lastFrame, @@ -237,7 +237,7 @@ describe("Runtime version flow", () => { }); listCore.runtime.setGetVersionResponse(getVersionResponse()); const list = renderScreen("/agentcore/runtime/version/list", { core: listCore }); - await waitForText(list.lastFrame, "checkout"); + await waitForText(list.lastFrame, "runtime-123"); await list.press("return"); await waitForText(list.lastFrame, "agentcore → runtime → version → list → runtime-123"); await waitForText(list.lastFrame, "3"); @@ -258,7 +258,7 @@ describe("Runtime version flow", () => { test("bare version get redirects to parent selection", async () => { const core = new TestCoreClient(); core.runtime.setListResponse({ - agentRuntimes: [runtime({ agentRuntimeName: "redirect-parent" })], + agentRuntimes: [runtime({ agentRuntimeId: "redirect-parent" })], }); const r = renderScreen("/agentcore/runtime/version/get", { core });