Skip to content

Commit 964dd60

Browse files
authored
feat(remove): add a TUI for removing resources from project. (#2310)
* feat(project): add interactive remove TUI screen * feat(project): wire remove into the project TUI * refactor(remove): make customer facing messages more concise * feat(remove): list online-insight separately from online-eval * feat(remove): support removing runtime endpoints * feat(remove): offer remove-all for import-only collections * fix(remove): hint at paging on multi-page resource lists
1 parent 5807c4e commit 964dd60

6 files changed

Lines changed: 973 additions & 5 deletions

File tree

‎src/components/Root.tsx‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ import { ProjectInvokePickerScreen } from "../handlers/project/invoke/screen.tsx
121121
import { AddRuntimeScreen } from "../handlers/project/add/runtime/screen.tsx";
122122
import { AddMemoryScreen } from "../handlers/project/add/memory/screen.tsx";
123123
import { ProjectStatusScreen } from "../handlers/project/status/screen.tsx";
124+
import { ProjectRemoveScreen } from "../handlers/project/remove/screen.tsx";
124125
import { HelpScreen, RootScreen } from "../handlers/screen.tsx";
125126
import type { Context } from "../router";
126127

@@ -821,6 +822,18 @@ export function Root({ path, ctx, core, queryClient }: RootProps) {
821822
path="agentcore/project/add/memory"
822823
element={<AddMemoryScreen ctx={ctx} core={core} />}
823824
/>
825+
<Route
826+
path="agentcore/project/remove"
827+
element={<ProjectRemoveScreen ctx={ctx} core={core} />}
828+
/>
829+
<Route
830+
path="agentcore/project/remove/:resourceType"
831+
element={<ProjectRemoveScreen ctx={ctx} core={core} />}
832+
/>
833+
<Route
834+
path="agentcore/project/remove/:resourceType/:resourceIndex"
835+
element={<ProjectRemoveScreen ctx={ctx} core={core} />}
836+
/>
824837
{/* Every known command without a screen of its own: a group opens its
825838
menu and a leaf its interactive help. Unknown routes retain the
826839
help-and-exit fallback. */}

‎src/handlers/project/index.ts‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export function createProjectHandler({ core, io }: ProjectHandlerConfig): Router
4040
"deploy",
4141
"status",
4242
"add",
43+
"remove",
4344
);
4445

4546
// Without a default, a bare `agentcore project` falls back to Commander's help
@@ -60,9 +61,14 @@ export function createProjectHandler({ core, io }: ProjectHandlerConfig): Router
6061
project.handler(createAddProjectResourceHandler(config, core));
6162
project.handler(createExportProjectResourceHandler({ projectManager, core, io }));
6263
project.handler(
63-
withProject({ projectManager: config.projectManager })(
64-
createRemoveProjectHandler({ projectManager: config.projectManager, io: config.io }),
65-
),
64+
createRemoveProjectHandler({
65+
projectManager: config.projectManager,
66+
io: config.io,
67+
middlewares: [
68+
withProject({ projectManager: config.projectManager }),
69+
withTuiWhenInteractive(core, io),
70+
],
71+
}),
6672
);
6773
project.handler(
6874
withProject({ projectManager: config.projectManager })(

‎src/handlers/project/project.screen.test.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ describe("project menu: command-line-only subcommands", () => {
7575
const r = renderScreen("/agentcore/project");
7676

7777
await waitForText(r.lastFrame, "command line only");
78-
const withScreens = ["create", "deploy", "invoke", "build", "status", "add"];
78+
const withScreens = ["create", "deploy", "invoke", "build", "status", "add", "remove"];
7979
const { screens, cliOnly } = menuEntries(r.lastFrame()!);
8080
expect(screens.toSorted()).toEqual(withScreens.toSorted());
8181
expect(cliOnly.toSorted()).toEqual(

‎src/handlers/project/remove/index.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createInterface } from "node:readline/promises";
2-
import { argument, createHandler, flag, ProjectKey } from "../../../router";
2+
import { argument, createHandler, flag, ProjectKey, type Middleware } from "../../../router";
33
import { InputValidationError, UserCancellationError } from "../../../errors";
44
import z from "zod";
55
import type { AppIO } from "../../../io";
@@ -12,12 +12,14 @@ import { projectMutationResource, projectReference, type ProjectMutationResult }
1212
type RemoveProjectResourceConfig = {
1313
projectManager: ProjectManager;
1414
io: AppIO;
15+
middlewares?: Middleware[];
1516
};
1617

1718
export const createRemoveProjectHandler = (config: RemoveProjectResourceConfig) =>
1819
createHandler({
1920
name: "remove",
2021
description: "remove a resource from the project",
22+
middlewares: config.middlewares,
2123
flags: [
2224
flag("name", "name of the resource to remove", z.string().min(1).optional()),
2325
flag("gateway", "name of the parent Gateway for a Target", z.string().min(1).optional()),

0 commit comments

Comments
 (0)