@shepai/cli 1.62.0 → 1.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/application/ports/output/agents/agent-executor-factory.interface.d.ts +18 -0
- package/dist/packages/core/src/application/ports/output/agents/agent-executor-factory.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/agents/index.d.ts +1 -1
- package/dist/packages/core/src/application/ports/output/agents/index.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts +2 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +7 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/mock-executor-factory.service.d.ts +2 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/mock-executor-factory.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/mock-executor-factory.service.js +3 -0
- package/dist/packages/core/src/infrastructure/services/filesystem/shep-directory.service.d.ts +7 -0
- package/dist/packages/core/src/infrastructure/services/filesystem/shep-directory.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/filesystem/shep-directory.service.js +9 -0
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +18 -4
- package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js +1 -1
- package/dist/src/presentation/cli/commands/daemon/start-daemon.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/daemon/start-daemon.js +24 -15
- package/dist/src/presentation/cli/commands/status.command.d.ts +7 -0
- package/dist/src/presentation/cli/commands/status.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/status.command.js +167 -3
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts +17 -0
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +23 -0
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts +22 -0
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.js +56 -0
- package/dist/src/presentation/web/components/common/base-drawer/index.d.ts +2 -0
- package/dist/src/presentation/web/components/common/base-drawer/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/base-drawer/index.js +1 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +9 -16
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +14 -14
- package/dist/src/presentation/web/components/common/repository-node/index.d.ts +1 -0
- package/dist/src/presentation/web/components/common/repository-node/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/repository-node/index.js +1 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts +7 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.js +12 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts +9 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.js +34 -0
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.js +4 -6
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +20 -2
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts +3 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +4 -2
- package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.js +3 -6
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/page/server-reference-manifest.json +14 -14
- package/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js +3 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
- package/web/.next/server/chunks/ssr/_73d14b70._.js +3 -0
- package/web/.next/server/chunks/ssr/_73d14b70._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_7f386377._.js +3 -0
- package/web/.next/server/chunks/ssr/_7f386377._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_d3711354._.js +2 -2
- package/web/.next/server/chunks/ssr/_d3711354._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_a64b7b24._.js → _d81184e2._.js} +2 -2
- package/web/.next/server/chunks/ssr/_d81184e2._.js.map +1 -0
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_fe355030._.js → server/chunks/ssr/node_modules__pnpm_87f920e7._.js} +2 -2
- package/web/.next/server/chunks/ssr/{node_modules__pnpm_fe355030._.js.map → node_modules__pnpm_87f920e7._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js.map +1 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +3 -0
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -0
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +15 -15
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +14 -14
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_73d14b70._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_7f386377._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_d3711354._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_a64b7b24._.js → _d81184e2._.js} +2 -2
- package/web/.next/{server/chunks/ssr/node_modules__pnpm_fe355030._.js → standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_87f920e7._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +3 -0
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +15 -15
- package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.stories.tsx +207 -0
- package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +90 -0
- package/web/.next/standalone/src/presentation/web/components/common/base-drawer/index.ts +1 -0
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +1 -1
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +143 -172
- package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/feature-drawer.tsx +119 -133
- package/web/.next/standalone/src/presentation/web/components/common/repository-node/index.ts +1 -0
- package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-drawer.stories.tsx +58 -0
- package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-drawer.tsx +82 -0
- package/web/.next/standalone/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.tsx +79 -96
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +30 -2
- package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +7 -0
- package/web/.next/standalone/src/presentation/web/components/features/skills/skill-detail-drawer.tsx +71 -77
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/04d22f0d67c6671b.js +10 -0
- package/web/.next/static/chunks/0c6654ec27f11c7e.js +1 -0
- package/web/.next/static/chunks/12c70bfd5951cf9b.js +1 -0
- package/web/.next/static/chunks/21541b346dd4dd28.js +1 -0
- package/web/.next/static/chunks/{cb1b27e4a21415d3.js → 3b941e59ac013e12.js} +2 -2
- package/web/.next/static/chunks/{09d898be63c54f20.js → 78919481e7c5ad4f.js} +1 -1
- package/web/.next/static/chunks/a5b6a22de303e877.css +2 -0
- package/web/.next/static/chunks/af7a5bcb7c49e46e.js +1 -0
- package/web/.next/static/chunks/bcd97add650ece51.js +1 -0
- package/web/.next/static/chunks/be784143669bb992.js +1 -0
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js.map +0 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js +0 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_9915d2a7._.js +0 -3
- package/web/.next/server/chunks/ssr/_9915d2a7._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_a64b7b24._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_e7a4b0e4._.js +0 -3
- package/web/.next/server/chunks/ssr/_e7a4b0e4._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9915d2a7._.js +0 -3
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_e7a4b0e4._.js +0 -3
- package/web/.next/static/chunks/13664c029245afc8.js +0 -1
- package/web/.next/static/chunks/25f42652257ff43d.js +0 -1
- package/web/.next/static/chunks/2934854f0378f815.js +0 -1
- package/web/.next/static/chunks/45f510f84c7c417d.css +0 -2
- package/web/.next/static/chunks/8e4c719503d9387e.js +0 -1
- package/web/.next/static/chunks/cd44f06f18e3425a.js +0 -10
- /package/web/.next/static/{2z-UoCok36_D1hh1-N88G → R37CbaEU-TK9xR6x4aI_Z}/_buildManifest.js +0 -0
- /package/web/.next/static/{2z-UoCok36_D1hh1-N88G → R37CbaEU-TK9xR6x4aI_Z}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{2z-UoCok36_D1hh1-N88G → R37CbaEU-TK9xR6x4aI_Z}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { BaseDrawer } from './base-drawer.js';
|
|
4
|
+
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
5
|
+
import { Button } from '../../ui/button.js';
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Common/BaseDrawer',
|
|
8
|
+
component: BaseDrawer,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'fullscreen',
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
/* ---------------------------------------------------------------------------
|
|
16
|
+
* Trigger wrapper — starts closed, click to open
|
|
17
|
+
* ------------------------------------------------------------------------- */
|
|
18
|
+
function DrawerTrigger(props) {
|
|
19
|
+
const [open, setOpen] = useState(false);
|
|
20
|
+
return (_jsxs("div", { className: "flex h-screen items-start p-4", children: [_jsx(Button, { variant: "outline", onClick: () => setOpen(true), children: "Open Drawer" }), _jsx(BaseDrawer, { ...props, open: open, onClose: () => setOpen(false) })] }));
|
|
21
|
+
}
|
|
22
|
+
/* ---------------------------------------------------------------------------
|
|
23
|
+
* Stories
|
|
24
|
+
* ------------------------------------------------------------------------- */
|
|
25
|
+
/** Default drawer with sm size, non-modal, children only. */
|
|
26
|
+
export const Default = {
|
|
27
|
+
render: () => (_jsx(DrawerTrigger, { children: _jsx("div", { className: "p-4", children: _jsx("p", { className: "text-muted-foreground text-sm", children: "Default drawer content" }) }) })),
|
|
28
|
+
};
|
|
29
|
+
/** Explicit sm size with inspector-style content. */
|
|
30
|
+
export const SmallSize = {
|
|
31
|
+
render: () => (_jsx(DrawerTrigger, { size: "sm", children: _jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("h3", { className: "text-sm font-semibold", children: "Feature Inspector" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: "Status" }), _jsx("span", { className: "text-sm", children: "Running" })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("span", { className: "text-muted-foreground text-xs", children: "Progress" }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: "bg-primary h-full w-[45%] rounded-full" }) })] })] }) })),
|
|
32
|
+
};
|
|
33
|
+
/** Medium size with content-rich review-style content. */
|
|
34
|
+
export const MediumSize = {
|
|
35
|
+
render: () => (_jsx(DrawerTrigger, { size: "md", children: _jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsx("h3", { className: "text-sm font-semibold", children: "Review Content" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "This drawer uses size=\"md\" (w-xl / 576px) for content-rich review panels that need more horizontal space for diff summaries, tables, and code blocks." }), _jsx("div", { className: "bg-muted rounded-md p-3", children: _jsx("pre", { className: "text-xs", children: `+ Added authentication middleware\n- Removed legacy session handler\n Updated user model schema` }) })] }) })),
|
|
36
|
+
};
|
|
37
|
+
/** Modal drawer with overlay. */
|
|
38
|
+
export const Modal = {
|
|
39
|
+
render: () => (_jsx(DrawerTrigger, { modal: true, children: _jsx("div", { className: "p-4", children: _jsx("p", { className: "text-muted-foreground text-sm", children: "This drawer is modal \u2014 an overlay blocks background interaction and focus is trapped." }) }) })),
|
|
40
|
+
};
|
|
41
|
+
/** Drawer with header slot containing DrawerTitle and DrawerDescription. */
|
|
42
|
+
export const WithHeader = {
|
|
43
|
+
render: () => (_jsx(DrawerTrigger, { header: _jsxs(_Fragment, { children: [_jsx(DrawerTitle, { children: "Feature Details" }), _jsx(DrawerDescription, { children: "FEAT-042 \u2014 Authentication Flow" })] }), children: _jsx("div", { className: "p-4", children: _jsx("p", { className: "text-muted-foreground text-sm", children: "Content below the header." }) }) })),
|
|
44
|
+
};
|
|
45
|
+
/** Drawer with footer slot containing action buttons. */
|
|
46
|
+
export const WithFooter = {
|
|
47
|
+
render: () => (_jsx(DrawerTrigger, { footer: _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", className: "flex-1", children: "Cancel" }), _jsx(Button, { className: "flex-1", children: "Save" })] }), children: _jsx("div", { className: "p-4", children: _jsx("p", { className: "text-muted-foreground text-sm", children: "Content above the footer." }) }) })),
|
|
48
|
+
};
|
|
49
|
+
/** Drawer with both header and footer slots populated. */
|
|
50
|
+
export const WithHeaderAndFooter = {
|
|
51
|
+
render: () => (_jsx(DrawerTrigger, { header: _jsxs(_Fragment, { children: [_jsx(DrawerTitle, { children: "Create Feature" }), _jsx(DrawerDescription, { children: "Fill in the details below" })] }), footer: _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", className: "flex-1", children: "Cancel" }), _jsx(Button, { className: "flex-1", children: "Create" })] }), children: _jsxs("div", { className: "flex flex-col gap-4 p-4", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { className: "text-sm font-medium", children: "Name" }), _jsx("input", { type: "text", className: "border-input bg-background rounded-md border px-3 py-2 text-sm", placeholder: "Feature name" })] }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("label", { className: "text-sm font-medium", children: "Description" }), _jsx("textarea", { className: "border-input bg-background rounded-md border px-3 py-2 text-sm", rows: 3, placeholder: "Optional description" })] })] }) })),
|
|
52
|
+
};
|
|
53
|
+
/** Drawer with content that exceeds viewport to demonstrate scroll behavior. */
|
|
54
|
+
export const ScrollableContent = {
|
|
55
|
+
render: () => (_jsx(DrawerTrigger, { header: _jsxs(_Fragment, { children: [_jsx(DrawerTitle, { children: "Scrollable Content" }), _jsx(DrawerDescription, { children: "Content below overflows and scrolls" })] }), children: _jsx("div", { className: "flex flex-col gap-4 p-4", children: Array.from({ length: 30 }, (_, i) => (_jsxs("div", { className: "border-border rounded-md border p-3", children: [_jsxs("h4", { className: "text-sm font-medium", children: ["Item ", i + 1] }), _jsx("p", { className: "text-muted-foreground text-xs", children: "This is a scrollable content item to demonstrate overflow handling." })] }, i))) }) })),
|
|
56
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/base-drawer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BaseDrawer } from './base-drawer.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,MAAM,0DAA0D,CAAC;AAE/F,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAcD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,YAAoB,EACpB,gBAAgB,EAChB,QAAQ,EACR,eAAe,GAChB,EAAE,wBAAwB,2CAsR1B"}
|
package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { PlusIcon, FileIcon, FileTextIcon, ImageIcon, CodeIcon, Trash2Icon, ChevronsUpDown, CheckIcon, } from 'lucide-react';
|
|
5
5
|
import { cn } from '../../../lib/utils.js';
|
|
6
6
|
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
7
|
-
import {
|
|
7
|
+
import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
8
|
+
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
8
9
|
import { Button } from '../../ui/button.js';
|
|
9
10
|
import { Input } from '../../ui/input.js';
|
|
10
11
|
import { Textarea } from '../../ui/textarea.js';
|
|
@@ -68,12 +69,10 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
|
|
|
68
69
|
setOpenPr(defaultOpenPr);
|
|
69
70
|
setParentId(undefined);
|
|
70
71
|
}, [defaultGates, defaultPush, defaultOpenPr]);
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
onClose();
|
|
76
|
-
}
|
|
72
|
+
const handleClose = useCallback(() => {
|
|
73
|
+
drawerCloseSound.play();
|
|
74
|
+
resetForm();
|
|
75
|
+
onClose();
|
|
77
76
|
}, [onClose, resetForm, drawerCloseSound]);
|
|
78
77
|
const handleSubmit = useCallback((e) => {
|
|
79
78
|
e.preventDefault();
|
|
@@ -124,13 +123,7 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
|
|
|
124
123
|
setAttachments((prev) => prev.filter((f) => f.path !== path));
|
|
125
124
|
}, []);
|
|
126
125
|
const hasFeatures = features && features.length > 0;
|
|
127
|
-
return (
|
|
128
|
-
drawerCloseSound.play();
|
|
129
|
-
onClose();
|
|
130
|
-
}, className: "ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden", children: _jsx(XIcon, { className: "size-4" }) }), _jsxs(DrawerHeader, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500" }), _jsx(DrawerTitle, { children: "NEW FEATURE" })] }), _jsx(DrawerDescription, { asChild: true, children: _jsx("div", { children: _jsx(Badge, { variant: "secondary", children: "Creating..." }) }) })] }), _jsx(Separator, {}), _jsx("div", { className: "flex-1 overflow-y-auto p-4", children: _jsxs("form", { id: "create-feature-form", onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-name", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "FEATURE NAME" }), _jsx(Input, { id: "feature-name", placeholder: "e.g. GitHub OAuth Login", value: name, onChange: (e) => setName(e.target.value), required: true, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-description", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "DESCRIPTION" }), _jsx(Textarea, { id: "feature-description", placeholder: "Describe what this feature does...", value: description, onChange: (e) => setDescription(e.target.value), rows: 4, disabled: isSubmitting })] }), hasFeatures ? (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "parent-feature", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "PARENT FEATURE" }), _jsx(ParentFeatureCombobox, { features: features, value: parentId, onChange: setParentId, disabled: isSubmitting })] })) : null, _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "APPROVE" }), _jsx(CheckboxGroup, { label: "Autonomous Mode", description: "YOLO!", parentAriaLabel: "Auto approve all", options: AUTO_APPROVE_OPTIONS, value: approvalGates, onValueChange: setApprovalGates, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "GIT" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(CheckboxGroupItem, { id: "push", label: "Push", description: "Push branch to remote after implementation.", checked: push || openPr, onCheckedChange: setPush, disabled: openPr || isSubmitting }), _jsx(CheckboxGroupItem, { id: "open-pr", label: "Create PR", description: "Open a pull request after pushing.", checked: openPr, onCheckedChange: setOpenPr, disabled: isSubmitting })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: ["ATTACHMENTS", attachments.length > 0 && (_jsxs("span", { className: "text-muted-foreground/60 ml-1.5", children: ["(", attachments.length, ")"] }))] }), _jsxs(Button, { type: "button", variant: "outline", size: "xs", onClick: handleAddFiles, disabled: isSubmitting, children: [_jsx(PlusIcon, { className: "size-3" }), "Add Files"] })] }), attachments.length > 0 && (_jsx("div", { className: "flex flex-col gap-2", children: attachments.map((file) => (_jsx(AttachmentCard, { file: file, onRemove: () => handleRemoveFile(file.path), disabled: isSubmitting }, file.path))) }))] })] }) }), _jsx(Separator, {}), _jsxs(DrawerFooter, { className: "flex-row justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => {
|
|
131
|
-
drawerCloseSound.play();
|
|
132
|
-
onClose();
|
|
133
|
-
}, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", form: "create-feature-form", disabled: !name.trim() || isSubmitting, children: isSubmitting ? 'Creating...' : '+ Create Feature' })] })] }) }));
|
|
126
|
+
return (_jsxs(BaseDrawer, { open: open, onClose: handleClose, size: "md", modal: false, "data-testid": "feature-create-drawer", header: _jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "h-2.5 w-2.5 shrink-0 rounded-full bg-blue-500" }), _jsx(DrawerTitle, { children: "NEW FEATURE" })] }), _jsx(DrawerDescription, { asChild: true, children: _jsx("div", { children: _jsx(Badge, { variant: "secondary", children: "Creating..." }) }) })] }), footer: _jsxs("div", { className: "flex flex-row justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: handleClose, disabled: isSubmitting, children: "Cancel" }), _jsx(Button, { type: "submit", form: "create-feature-form", disabled: !name.trim() || isSubmitting, children: isSubmitting ? 'Creating...' : '+ Create Feature' })] }), children: [_jsx(Separator, {}), _jsx("div", { className: "p-4", children: _jsxs("form", { id: "create-feature-form", onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-name", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "FEATURE NAME" }), _jsx(Input, { id: "feature-name", placeholder: "e.g. GitHub OAuth Login", value: name, onChange: (e) => setName(e.target.value), required: true, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "feature-description", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "DESCRIPTION" }), _jsx(Textarea, { id: "feature-description", placeholder: "Describe what this feature does...", value: description, onChange: (e) => setDescription(e.target.value), rows: 4, disabled: isSubmitting })] }), hasFeatures ? (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { htmlFor: "parent-feature", className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "PARENT FEATURE" }), _jsx(ParentFeatureCombobox, { features: features, value: parentId, onChange: setParentId, disabled: isSubmitting })] })) : null, _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "APPROVE" }), _jsx(CheckboxGroup, { label: "Autonomous Mode", description: "YOLO!", parentAriaLabel: "Auto approve all", options: AUTO_APPROVE_OPTIONS, value: approvalGates, onValueChange: setApprovalGates, disabled: isSubmitting })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "GIT" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(CheckboxGroupItem, { id: "push", label: "Push", description: "Push branch to remote after implementation.", checked: push || openPr, onCheckedChange: setPush, disabled: openPr || isSubmitting }), _jsx(CheckboxGroupItem, { id: "open-pr", label: "Create PR", description: "Open a pull request after pushing.", checked: openPr, onCheckedChange: setOpenPr, disabled: isSubmitting })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(Label, { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: ["ATTACHMENTS", attachments.length > 0 && (_jsxs("span", { className: "text-muted-foreground/60 ml-1.5", children: ["(", attachments.length, ")"] }))] }), _jsxs(Button, { type: "button", variant: "outline", size: "xs", onClick: handleAddFiles, disabled: isSubmitting, children: [_jsx(PlusIcon, { className: "size-3" }), "Add Files"] })] }), attachments.length > 0 && (_jsx("div", { className: "flex flex-col gap-2", children: attachments.map((file) => (_jsx(AttachmentCard, { file: file, onRemove: () => handleRemoveFile(file.path), disabled: isSubmitting }, file.path))) }))] })] }) })] }));
|
|
134
127
|
}
|
|
135
128
|
function ParentFeatureCombobox({ features, value, onChange, disabled, }) {
|
|
136
129
|
const [open, setOpen] = useState(false);
|
|
@@ -26,7 +26,7 @@ import { FeatureCreateDrawer } from './feature-create-drawer.js';
|
|
|
26
26
|
* - Submit button is disabled when name is empty
|
|
27
27
|
* - `approvalGates` always included: `{ allowPrd, allowPlan, allowMerge }` (all false by default)
|
|
28
28
|
* - Non-modal (`modal={false}`) — canvas stays interactive behind the drawer
|
|
29
|
-
* - Fixed width:
|
|
29
|
+
* - Fixed width: 448px (`w-xl`) — matches review drawers (PRD, Plan, Merge)
|
|
30
30
|
* - Attachments use native OS file picker via `pickFiles()` — returns `FileAttachment[]`
|
|
31
31
|
* with full absolute paths, filenames, and sizes
|
|
32
32
|
*/
|
|
@@ -32,7 +32,7 @@ import { Button } from '../../ui/button.js';
|
|
|
32
32
|
* - Submit button is disabled when name is empty
|
|
33
33
|
* - `approvalGates` always included: `{ allowPrd, allowPlan, allowMerge }` (all false by default)
|
|
34
34
|
* - Non-modal (`modal={false}`) — canvas stays interactive behind the drawer
|
|
35
|
-
* - Fixed width:
|
|
35
|
+
* - Fixed width: 448px (`w-xl`) — matches review drawers (PRD, Plan, Merge)
|
|
36
36
|
* - Attachments use native OS file picker via `pickFiles()` — returns `FileAttachment[]`
|
|
37
37
|
* with full absolute paths, filenames, and sizes
|
|
38
38
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer/feature-drawer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"feature-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer/feature-drawer.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGxE,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,EAC5B,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,UAAkB,GACnB,EAAE,kBAAkB,2CAoIpB"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useCallback, useEffect } from 'react';
|
|
4
|
+
import { Loader2, Trash2, ExternalLink, GitCommitHorizontal } from 'lucide-react';
|
|
4
5
|
import { PrStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
|
|
5
6
|
import { cn } from '../../../lib/utils.js';
|
|
6
7
|
import { useSoundAction } from '../../../hooks/use-sound-action.js';
|
|
7
8
|
import { OpenActionMenu } from '../../common/open-action-menu/index.js';
|
|
8
|
-
import {
|
|
9
|
+
import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
10
|
+
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
9
11
|
import { Button } from '../../ui/button.js';
|
|
10
12
|
import { Badge } from '../../ui/badge.js';
|
|
11
13
|
import { Separator } from '../../ui/separator.js';
|
|
@@ -17,18 +19,16 @@ import { useFeatureActions } from './use-feature-actions.js';
|
|
|
17
19
|
export function FeatureDrawer({ selectedNode, onClose, onDelete, isDeleting = false, }) {
|
|
18
20
|
const drawerOpenSound = useSoundAction('drawer-open');
|
|
19
21
|
const drawerCloseSound = useSoundAction('drawer-close');
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
onClose();
|
|
31
|
-
}, className: "ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden", children: _jsx(XIcon, { className: "size-4" }) }), _jsxs(DrawerHeader, { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: selectedNode.name }), _jsx(DrawerDescription, { children: selectedNode.featureId })] }), selectedNode.repositoryPath && selectedNode.branch ? (_jsx(DrawerActions, { repositoryPath: selectedNode.repositoryPath, branch: selectedNode.branch, specPath: selectedNode.specPath })) : null, _jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-status", className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: lifecycleDisplayLabels[selectedNode.lifecycle] }), _jsx(StateBadge, { data: selectedNode }), selectedNode.progress > 0 ? (_jsxs("div", { "data-testid": "feature-drawer-progress", className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-xs", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { children: [selectedNode.progress, "%"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', featureNodeStateConfig[selectedNode.state].progressClass), style: { width: `${selectedNode.progress}%` } }) })] })) : null] }), selectedNode.pr ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx(PrInfoSection, { pr: selectedNode.pr })] })) : null, _jsx(Separator, {}), _jsx(DetailsSection, { data: selectedNode }), onDelete ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx("div", { "data-testid": "feature-drawer-delete", className: "p-4", children: _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "destructive", className: "w-full", disabled: isDeleting, children: [_jsx(Trash2, { className: "mr-2 h-4 w-4" }), "Delete feature"] }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: selectedNode.name }), " (", selectedNode.featureId, "). This action cannot be undone.", selectedNode.state === 'running' ? (_jsx(_Fragment, { children: " This feature has a running agent that will be stopped." })) : null] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onDelete(selectedNode.featureId), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] })] }) })] })) : null] })) : null }) }));
|
|
22
|
+
const isOpen = selectedNode !== null;
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (isOpen)
|
|
25
|
+
drawerOpenSound.play();
|
|
26
|
+
}, [isOpen, drawerOpenSound]);
|
|
27
|
+
const handleClose = useCallback(() => {
|
|
28
|
+
drawerCloseSound.play();
|
|
29
|
+
onClose();
|
|
30
|
+
}, [onClose, drawerCloseSound]);
|
|
31
|
+
return (_jsx(BaseDrawer, { open: selectedNode !== null, onClose: handleClose, size: "sm", modal: false, "data-testid": "feature-drawer", header: selectedNode ? (_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: selectedNode.name }), _jsx(DrawerDescription, { children: selectedNode.featureId })] })) : undefined, children: selectedNode ? (_jsxs(_Fragment, { children: [selectedNode.repositoryPath && selectedNode.branch ? (_jsx(DrawerActions, { repositoryPath: selectedNode.repositoryPath, branch: selectedNode.branch, specPath: selectedNode.specPath })) : null, _jsx(Separator, {}), _jsxs("div", { "data-testid": "feature-drawer-status", className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: lifecycleDisplayLabels[selectedNode.lifecycle] }), _jsx(StateBadge, { data: selectedNode }), selectedNode.progress > 0 ? (_jsxs("div", { "data-testid": "feature-drawer-progress", className: "flex flex-col gap-1", children: [_jsxs("div", { className: "text-muted-foreground flex items-center justify-between text-xs", children: [_jsx("span", { children: "Progress" }), _jsxs("span", { children: [selectedNode.progress, "%"] })] }), _jsx("div", { className: "bg-muted h-2 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', featureNodeStateConfig[selectedNode.state].progressClass), style: { width: `${selectedNode.progress}%` } }) })] })) : null] }), selectedNode.pr ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx(PrInfoSection, { pr: selectedNode.pr })] })) : null, _jsx(Separator, {}), _jsx(DetailsSection, { data: selectedNode }), onDelete ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsx("div", { "data-testid": "feature-drawer-delete", className: "p-4", children: _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsxs(Button, { variant: "destructive", className: "w-full", disabled: isDeleting, children: [_jsx(Trash2, { className: "mr-2 h-4 w-4" }), "Delete feature"] }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: selectedNode.name }), " (", selectedNode.featureId, "). This action cannot be undone.", selectedNode.state === 'running' ? (_jsx(_Fragment, { children: " This feature has a running agent that will be stopped." })) : null] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onDelete(selectedNode.featureId), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] })] }) })] })) : null] })) : null }));
|
|
32
32
|
}
|
|
33
33
|
function StateBadge({ data }) {
|
|
34
34
|
const config = featureNodeStateConfig[data.state];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { RepositoryNode } from './repository-node.js';
|
|
2
|
+
export { RepositoryDrawer, type RepositoryDrawerProps } from './repository-drawer.js';
|
|
2
3
|
export type { RepositoryNodeData, RepositoryNodeType } from './repository-node-config.js';
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACnF,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RepositoryNodeData } from './repository-node-config.js';
|
|
2
|
+
export interface RepositoryDrawerProps {
|
|
3
|
+
data: RepositoryNodeData | null;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function RepositoryDrawer({ data, onClose }: RepositoryDrawerProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=repository-drawer.d.ts.map
|
package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-drawer.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,qBAAqB,2CAkExE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Code2, Terminal, FolderOpen } from 'lucide-react';
|
|
4
|
+
import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
5
|
+
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
6
|
+
import { Separator } from '../../ui/separator.js';
|
|
7
|
+
import { ActionButton } from '../../common/action-button/index.js';
|
|
8
|
+
import { useRepositoryActions } from './use-repository-actions.js';
|
|
9
|
+
export function RepositoryDrawer({ data, onClose }) {
|
|
10
|
+
const actions = useRepositoryActions(data?.repositoryPath ? { repositoryPath: data.repositoryPath } : null);
|
|
11
|
+
return (_jsx(BaseDrawer, { open: data !== null, onClose: onClose, size: "sm", modal: false, "data-testid": "repository-drawer", header: data ? (_jsxs("div", { "data-testid": "repository-drawer-header", children: [_jsx(DrawerTitle, { children: data.name }), data.repositoryPath ? (_jsx(DrawerDescription, { className: "truncate font-mono text-xs", children: data.repositoryPath })) : null] })) : undefined, children: data?.repositoryPath ? (_jsxs(_Fragment, { children: [_jsx(Separator, {}), _jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "text-muted-foreground text-xs font-semibold tracking-wider", children: "OPEN WITH" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(ActionButton, { label: "Open in IDE", onClick: actions.openInIde, loading: actions.ideLoading, error: !!actions.ideError, icon: Code2, variant: "outline", size: "sm" }), _jsx(ActionButton, { label: "Open in Shell", onClick: actions.openInShell, loading: actions.shellLoading, error: !!actions.shellError, icon: Terminal, variant: "outline", size: "sm" }), _jsx(ActionButton, { label: "Open Folder", onClick: actions.openFolder, loading: actions.folderLoading, error: !!actions.folderError, icon: FolderOpen, variant: "outline", size: "sm" })] })] })] })) : null }));
|
|
12
|
+
}
|
package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { RepositoryDrawer } from './repository-drawer.js';
|
|
3
|
+
declare const meta: Meta<typeof RepositoryDrawer>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof RepositoryDrawer>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const LongPath: Story;
|
|
8
|
+
export declare const WithoutPath: Story;
|
|
9
|
+
//# sourceMappingURL=repository-drawer.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/repository-node/repository-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAOvC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAqB/C,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAIzB,CAAC"}
|
package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button } from '../../ui/button.js';
|
|
4
|
+
import { RepositoryDrawer } from './repository-drawer.js';
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'Composed/RepositoryDrawer',
|
|
7
|
+
component: RepositoryDrawer,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'fullscreen',
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
const repoData = {
|
|
15
|
+
id: 'repo-1',
|
|
16
|
+
name: 'shep-ai/cli',
|
|
17
|
+
repositoryPath: '/home/user/shep-ai/cli',
|
|
18
|
+
};
|
|
19
|
+
function DrawerTrigger({ data, label }) {
|
|
20
|
+
const [selected, setSelected] = useState(null);
|
|
21
|
+
return (_jsxs("div", { className: "flex h-screen items-start p-4", children: [_jsx(Button, { variant: "outline", onClick: () => setSelected(data), children: label }), _jsx(RepositoryDrawer, { data: selected, onClose: () => setSelected(null) })] }));
|
|
22
|
+
}
|
|
23
|
+
export const Default = {
|
|
24
|
+
render: () => _jsx(DrawerTrigger, { data: repoData, label: "Open Repository" }),
|
|
25
|
+
};
|
|
26
|
+
export const LongPath = {
|
|
27
|
+
render: () => (_jsx(DrawerTrigger, { data: {
|
|
28
|
+
...repoData,
|
|
29
|
+
repositoryPath: '/home/user/projects/company/some-very-long-path/shep-ai/cli',
|
|
30
|
+
}, label: "Open Long Path" })),
|
|
31
|
+
};
|
|
32
|
+
export const WithoutPath = {
|
|
33
|
+
render: () => (_jsx(DrawerTrigger, { data: { ...repoData, repositoryPath: undefined }, label: "Open Without Path" })),
|
|
34
|
+
};
|
package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review-drawer-shell.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"review-drawer-shell.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAE3E,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,GACT,EAAE,sBAAsB,2CA0FxB"}
|
package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { Loader2, Trash2
|
|
4
|
-
import {
|
|
3
|
+
import { Loader2, Trash2 } from 'lucide-react';
|
|
4
|
+
import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
5
|
+
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
5
6
|
import { Button } from '../../ui/button.js';
|
|
6
7
|
import { Separator } from '../../ui/separator.js';
|
|
7
8
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from '../../ui/alert-dialog.js';
|
|
@@ -10,8 +11,5 @@ import { useFeatureActions } from '../../common/feature-drawer/use-feature-actio
|
|
|
10
11
|
export function ReviewDrawerShell({ open, onClose, featureName, featureDescription, featureId, repositoryPath, branch, specPath, onDelete, isDeleting, children, }) {
|
|
11
12
|
const actionsInput = repositoryPath && branch ? { repositoryPath, branch, specPath } : null;
|
|
12
13
|
const actions = useFeatureActions(actionsInput);
|
|
13
|
-
return (
|
|
14
|
-
if (!isOpen)
|
|
15
|
-
onClose();
|
|
16
|
-
}, children: _jsxs(DrawerContent, { direction: "right", className: "w-xl", showCloseButton: false, children: [_jsx("button", { type: "button", "aria-label": "Close", onClick: onClose, className: "ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden", children: _jsx(XIcon, { className: "size-4" }) }), _jsxs(DrawerHeader, { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureName }), featureDescription ? (_jsx(DrawerDescription, { children: featureDescription })) : featureId ? (_jsx(DrawerDescription, { className: "sr-only", children: featureId })) : null] }), actionsInput ? (_jsxs("div", { className: "flex items-center gap-2 px-4 pb-3", children: [_jsx(OpenActionMenu, { actions: actions, repositoryPath: actionsInput.repositoryPath, showSpecs: !!specPath }), onDelete && featureId ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-border mx-1 h-4 w-px" }), _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Delete feature", disabled: isDeleting, className: "text-muted-foreground hover:text-destructive", "data-testid": "review-drawer-delete", children: isDeleting ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(Trash2, { className: "size-4" })) }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: featureName }), " (", featureId, "). This action cannot be undone."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onDelete(featureId), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] })] })] })) : null] })) : null, _jsx(Separator, {}), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: children })] }) }));
|
|
14
|
+
return (_jsxs(BaseDrawer, { open: open, onClose: onClose, size: "md", modal: false, "data-testid": "review-drawer", header: _jsxs(_Fragment, { children: [_jsxs("div", { "data-testid": "feature-drawer-header", children: [_jsx(DrawerTitle, { children: featureName }), featureDescription ? (_jsx(DrawerDescription, { children: featureDescription })) : featureId ? (_jsx(DrawerDescription, { className: "sr-only", children: featureId })) : null] }), actionsInput ? (_jsxs("div", { className: "flex items-center gap-2 pt-2", children: [_jsx(OpenActionMenu, { actions: actions, repositoryPath: actionsInput.repositoryPath, showSpecs: !!specPath }), onDelete && featureId ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-border mx-1 h-4 w-px" }), _jsxs(AlertDialog, { children: [_jsx(AlertDialogTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": "Delete feature", disabled: isDeleting, className: "text-muted-foreground hover:text-destructive", "data-testid": "review-drawer-delete", children: isDeleting ? (_jsx(Loader2, { className: "size-4 animate-spin" })) : (_jsx(Trash2, { className: "size-4" })) }) }), _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Delete feature?" }), _jsxs(AlertDialogDescription, { children: ["This will permanently delete ", _jsx("strong", { children: featureName }), " (", featureId, "). This action cannot be undone."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: isDeleting, children: "Cancel" }), _jsx(AlertDialogAction, { variant: "destructive", disabled: isDeleting, onClick: () => onDelete(featureId), children: isDeleting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Deleting\u2026"] })) : ('Delete') })] })] })] })] })) : null] })) : null] }), children: [_jsx(Separator, {}), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: children })] }));
|
|
17
15
|
}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAgB1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAgB1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAc5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CAoczF"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -10,6 +10,7 @@ import { getWorkflowDefaults } from '../../../app/actions/get-workflow-defaults.
|
|
|
10
10
|
import { getMergeReviewData } from '../../../app/actions/get-merge-review-data.js';
|
|
11
11
|
import { FeaturesCanvas } from '../../features/features-canvas/index.js';
|
|
12
12
|
import { FeatureDrawer, FeatureCreateDrawer } from '../../common/index.js';
|
|
13
|
+
import { RepositoryDrawer } from '../../common/repository-node/index.js';
|
|
13
14
|
import { PrdQuestionnaireDrawer } from '../../common/prd-questionnaire/index.js';
|
|
14
15
|
import { TechDecisionsDrawer } from '../../common/tech-decisions-review/index.js';
|
|
15
16
|
import { MergeReviewDrawer } from '../../common/merge-review/index.js';
|
|
@@ -50,9 +51,26 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
50
51
|
// Merge review drawer state
|
|
51
52
|
const [mergeReviewData, setMergeReviewData] = useState(null);
|
|
52
53
|
const [isLoadingMergeReview, setIsLoadingMergeReview] = useState(false);
|
|
54
|
+
// Repository drawer state
|
|
55
|
+
const [selectedRepoNode, setSelectedRepoNode] = useState(null);
|
|
56
|
+
// Clear all drawers — used for pane click and canvas drag
|
|
57
|
+
const handleClearDrawers = useCallback(() => {
|
|
58
|
+
clearSelection();
|
|
59
|
+
setSelectedRepoNode(null);
|
|
60
|
+
closeCreateDrawer();
|
|
61
|
+
}, [clearSelection, closeCreateDrawer]);
|
|
62
|
+
// Open repository drawer when a repo node is clicked
|
|
63
|
+
const handleRepositoryClick = useCallback((nodeId) => {
|
|
64
|
+
const node = nodes.find((n) => n.id === nodeId);
|
|
65
|
+
if (node?.type === 'repositoryNode') {
|
|
66
|
+
clearSelection();
|
|
67
|
+
setSelectedRepoNode(node.data);
|
|
68
|
+
}
|
|
69
|
+
}, [nodes, clearSelection]);
|
|
53
70
|
const showPrdDrawer = selectedNode?.lifecycle === 'requirements' && selectedNode?.state === 'action-required';
|
|
54
71
|
const showTechDecisionsDrawer = selectedNode?.lifecycle === 'implementation' && selectedNode?.state === 'action-required';
|
|
55
|
-
const showMergeReviewDrawer = selectedNode?.lifecycle === 'review' &&
|
|
72
|
+
const showMergeReviewDrawer = selectedNode?.lifecycle === 'review' &&
|
|
73
|
+
(selectedNode?.state === 'action-required' || selectedNode?.state === 'error');
|
|
56
74
|
const handlePrdSelect = useCallback((questionId, optionId) => {
|
|
57
75
|
setPrdSelections((prev) => ({ ...prev, [questionId]: optionId }));
|
|
58
76
|
}, []);
|
|
@@ -257,5 +275,5 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
257
275
|
if (!hasRepositories) {
|
|
258
276
|
return (_jsxs(_Fragment, { children: [_jsx(NotificationPermissionBanner, {}), _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }), _jsx(FeatureCreateDrawer, { open: isCreateDrawerOpen, onClose: closeCreateDrawer, onSubmit: handleCreateFeatureSubmit, repositoryPath: pendingRepositoryPath, workflowDefaults: workflowDefaults, features: featureOptions, initialParentId: pendingParentFeatureId })] }));
|
|
259
277
|
}
|
|
260
|
-
return (_jsxs(_Fragment, { children: [_jsx(NotificationPermissionBanner, {}), _jsx(FeaturesCanvas, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeAction: handleAddFeatureToFeature, onNodeClick: handleNodeClick, onPaneClick:
|
|
278
|
+
return (_jsxs(_Fragment, { children: [_jsx(NotificationPermissionBanner, {}), _jsx(FeaturesCanvas, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeAction: handleAddFeatureToFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onRepositoryAdd: handleAddFeatureToRepo, onRepositoryClick: handleRepositoryClick, onRepositoryDelete: handleDeleteRepository, onRepositorySelect: handleAddRepository, onCanvasDrag: handleClearDrawers, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) }), _jsx(FeatureDrawer, { selectedNode: showPrdDrawer || showTechDecisionsDrawer || showMergeReviewDrawer ? null : selectedNode, onClose: clearSelection, onDelete: handleDeleteFeature, isDeleting: isDeleting }), showPrdDrawer ? (_jsx(PrdQuestionnaireDrawer, { open: true, onClose: clearSelection, featureName: selectedNode?.name ?? '', featureDescription: selectedNode?.description, featureId: selectedNode?.featureId, repositoryPath: selectedNode?.repositoryPath, branch: selectedNode?.branch, specPath: selectedNode?.specPath, data: questionnaireData, selections: prdSelections, onSelect: handlePrdSelect, onApprove: handlePrdApprove, onReject: handlePrdReject, isRejecting: isRejecting, onDelete: handleDeleteFeature, isDeleting: isDeleting, isProcessing: isLoadingQuestionnaire })) : null, showTechDecisionsDrawer ? (_jsx(TechDecisionsDrawer, { open: true, onClose: clearSelection, featureName: selectedNode?.name ?? '', featureId: selectedNode?.featureId, repositoryPath: selectedNode?.repositoryPath, branch: selectedNode?.branch, specPath: selectedNode?.specPath, data: techDecisionsData, onApprove: handleTechDecisionsApprove, onReject: handleTechDecisionsReject, isRejecting: isRejecting, onDelete: handleDeleteFeature, isDeleting: isDeleting, isProcessing: isLoadingTechDecisions })) : null, showMergeReviewDrawer ? (_jsx(MergeReviewDrawer, { open: true, onClose: clearSelection, featureName: selectedNode?.name ?? '', featureId: selectedNode?.featureId, repositoryPath: selectedNode?.repositoryPath, branch: selectedNode?.branch, specPath: selectedNode?.specPath, data: mergeReviewData, onApprove: handleMergeApprove, onReject: handleMergeReject, isRejecting: isRejecting, onDelete: handleDeleteFeature, isDeleting: isDeleting, isProcessing: isLoadingMergeReview })) : null, _jsx(FeatureCreateDrawer, { open: isCreateDrawerOpen, onClose: closeCreateDrawer, onSubmit: handleCreateFeatureSubmit, repositoryPath: pendingRepositoryPath, workflowDefaults: workflowDefaults, features: featureOptions, initialParentId: pendingParentFeatureId }), _jsx(RepositoryDrawer, { data: selectedRepoNode, onClose: () => setSelectedRepoNode(null) })] }));
|
|
261
279
|
}
|
|
@@ -13,11 +13,13 @@ export interface FeaturesCanvasProps {
|
|
|
13
13
|
onNodeClick?: (event: React.MouseEvent, node: CanvasNodeType) => void;
|
|
14
14
|
onPaneClick?: (event: React.MouseEvent) => void;
|
|
15
15
|
onRepositoryAdd?: (repoNodeId: string) => void;
|
|
16
|
+
onRepositoryClick?: (nodeId: string) => void;
|
|
16
17
|
onRepositoryDelete?: (repositoryId: string) => void;
|
|
17
18
|
onConnect?: (connection: Connection) => void;
|
|
18
19
|
onRepositorySelect?: (path: string) => void;
|
|
20
|
+
onCanvasDrag?: () => void;
|
|
19
21
|
toolbar?: React.ReactNode;
|
|
20
22
|
emptyState?: React.ReactNode;
|
|
21
23
|
}
|
|
22
|
-
export declare function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNodeAction, onNodeSettings, onConnect, onNodeClick, onPaneClick, onRepositoryAdd, onRepositoryDelete, onRepositorySelect, toolbar, emptyState, }: FeaturesCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export declare function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNodeAction, onNodeSettings, onConnect, onNodeClick, onPaneClick, onRepositoryAdd, onRepositoryClick, onRepositoryDelete, onRepositorySelect, onCanvasDrag, toolbar, emptyState, }: FeaturesCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
23
25
|
//# sourceMappingURL=features-canvas.d.ts.map
|
package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAGrF,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,WAAW,EACX,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAGrF,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,WAAW,EACX,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CAsHrB"}
|
|
@@ -9,7 +9,7 @@ import { FeatureNode } from '../../common/feature-node/index.js';
|
|
|
9
9
|
import { RepositoryNode } from '../../common/repository-node/index.js';
|
|
10
10
|
import { AddRepositoryNode } from '../../common/add-repository-node/index.js';
|
|
11
11
|
import { DependencyEdge } from './dependency-edge.js';
|
|
12
|
-
export function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNodeAction, onNodeSettings, onConnect, onNodeClick, onPaneClick, onRepositoryAdd, onRepositoryDelete, onRepositorySelect, toolbar, emptyState, }) {
|
|
12
|
+
export function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNodeAction, onNodeSettings, onConnect, onNodeClick, onPaneClick, onRepositoryAdd, onRepositoryClick, onRepositoryDelete, onRepositorySelect, onCanvasDrag, toolbar, emptyState, }) {
|
|
13
13
|
const nodeTypes = useMemo(() => ({
|
|
14
14
|
featureNode: FeatureNode,
|
|
15
15
|
repositoryNode: RepositoryNode,
|
|
@@ -42,6 +42,7 @@ export function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNo
|
|
|
42
42
|
: {}),
|
|
43
43
|
...(node.type === 'repositoryNode' && {
|
|
44
44
|
onAdd: onRepositoryAdd ? () => onRepositoryAdd(node.id) : undefined,
|
|
45
|
+
onClick: onRepositoryClick ? () => onRepositoryClick(node.id) : undefined,
|
|
45
46
|
onDelete: onRepositoryDelete,
|
|
46
47
|
}),
|
|
47
48
|
...(node.type === 'addRepositoryNode' && {
|
|
@@ -54,6 +55,7 @@ export function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNo
|
|
|
54
55
|
onNodeAction,
|
|
55
56
|
onNodeSettings,
|
|
56
57
|
onRepositoryAdd,
|
|
58
|
+
onRepositoryClick,
|
|
57
59
|
onRepositoryDelete,
|
|
58
60
|
onRepositorySelect,
|
|
59
61
|
]);
|
|
@@ -63,5 +65,5 @@ export function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNo
|
|
|
63
65
|
}
|
|
64
66
|
return (_jsx("div", { "data-testid": "features-canvas-empty", children: _jsx(EmptyState, { title: "No features yet", description: "Get started by creating your first feature.", action: _jsxs(Button, { onClick: onAddFeature, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "New Feature"] }) }) }));
|
|
65
67
|
}
|
|
66
|
-
return (_jsx("div", { "data-testid": "features-canvas", className: "h-full w-full", children: _jsx(ReactFlowProvider, { children: _jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, isValidConnection: isValidConnection, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, defaultViewport: { x: 30, y: 30, zoom: 0.85 }, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, children: [_jsx(Background, {}), _jsx(Controls, {}), toolbar] }) }) }));
|
|
68
|
+
return (_jsx("div", { "data-testid": "features-canvas", className: "h-full w-full", children: _jsx(ReactFlowProvider, { children: _jsxs(ReactFlow, { nodes: enrichedNodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, isValidConnection: isValidConnection, onConnect: onConnect, onNodesChange: onNodesChange, onNodeClick: onNodeClick, onPaneClick: onPaneClick, onMoveStart: onCanvasDrag, defaultViewport: { x: 30, y: 30, zoom: 0.85 }, nodesDraggable: false, nodesConnectable: false, elementsSelectable: false, children: [_jsx(Background, {}), _jsx(Controls, {}), toolbar] }) }) }));
|
|
67
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-detail-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skill-detail-drawer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skill-detail-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skill-detail-drawer.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,sBAAsB,2CA+E3E"}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { BaseDrawer } from '../../common/base-drawer/index.js';
|
|
4
|
+
import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
|
|
4
5
|
import { Badge } from '../../ui/badge.js';
|
|
5
|
-
import { ScrollArea } from '../../ui/scroll-area.js';
|
|
6
6
|
import { Separator } from '../../ui/separator.js';
|
|
7
7
|
import { FolderOpen } from 'lucide-react';
|
|
8
8
|
export function SkillDetailDrawer({ skill, onClose }) {
|
|
9
|
-
return (_jsx(
|
|
10
|
-
if (!open)
|
|
11
|
-
onClose();
|
|
12
|
-
}, children: _jsx(SheetContent, { side: "right", className: "w-full sm:max-w-lg", children: skill ? (_jsxs(_Fragment, { children: [_jsxs(SheetHeader, { children: [_jsx(SheetTitle, { children: skill.displayName }), _jsx(SheetDescription, { children: skill.name })] }), _jsxs(ScrollArea, { className: "flex-1 px-4 pb-4", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: skill.description }), _jsxs("div", { className: "mt-4 flex flex-wrap items-center gap-1.5", children: [_jsx(Badge, { variant: skill.source === 'project' ? 'secondary' : 'outline', children: skill.source === 'project' ? 'Project' : 'Global' }), _jsx(Badge, { variant: "outline", children: skill.category }), skill.context ? _jsx(Badge, { variant: "outline", children: skill.context }) : null] }), skill.allowedTools ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Allowed Tools" }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: skill.allowedTools })] })] })) : null, skill.resources.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Resources" }), _jsx("ul", { className: "mt-2 space-y-1.5", children: skill.resources.map((resource) => (_jsxs("li", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(FolderOpen, { className: "size-3.5 shrink-0" }), _jsxs("span", { children: [resource.name, "/ \u2014 ", resource.fileCount, ' ', resource.fileCount === 1 ? 'file' : 'files'] })] }, resource.name))) })] })] })) : null, skill.body ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsx("pre", { className: "text-muted-foreground text-sm leading-relaxed whitespace-pre-wrap", children: skill.body })] })) : null] })] })) : null }) }));
|
|
9
|
+
return (_jsx(BaseDrawer, { open: skill !== null, onClose: onClose, size: "sm", modal: true, "data-testid": "skill-detail-drawer", header: skill ? (_jsxs(_Fragment, { children: [_jsx(DrawerTitle, { children: skill.displayName }), _jsx(DrawerDescription, { children: skill.name })] })) : undefined, children: skill ? (_jsxs("div", { className: "px-4 pb-4", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: skill.description }), _jsxs("div", { className: "mt-4 flex flex-wrap items-center gap-1.5", children: [_jsx(Badge, { variant: skill.source === 'project' ? 'secondary' : 'outline', children: skill.source === 'project' ? 'Project' : 'Global' }), _jsx(Badge, { variant: "outline", children: skill.category }), skill.context ? _jsx(Badge, { variant: "outline", children: skill.context }) : null] }), skill.allowedTools ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Allowed Tools" }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: skill.allowedTools })] })] })) : null, skill.resources.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Resources" }), _jsx("ul", { className: "mt-2 space-y-1.5", children: skill.resources.map((resource) => (_jsxs("li", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(FolderOpen, { className: "size-3.5 shrink-0" }), _jsxs("span", { children: [resource.name, "/ \u2014 ", resource.fileCount, ' ', resource.fileCount === 1 ? 'file' : 'files'] })] }, resource.name))) })] })] })) : null, skill.body ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsx("pre", { className: "text-muted-foreground text-sm leading-relaxed whitespace-pre-wrap", children: skill.body })] })) : null] })) : null }));
|
|
13
10
|
}
|