@shepai/cli 1.99.0 → 1.100.0-pr300.db7a82d
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/src/presentation/web/app/api/npm-version/route.d.ts +3 -0
- package/dist/src/presentation/web/app/api/npm-version/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/npm-version/route.js +18 -0
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +7 -6
- package/dist/src/presentation/web/components/common/version-badge/version-badge.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/version-badge/version-badge.js +5 -2
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts +6 -0
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.js +67 -0
- package/dist/src/presentation/web/hooks/use-npm-version-check.d.ts +10 -0
- package/dist/src/presentation/web/hooks/use-npm-version-check.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/use-npm-version-check.js +34 -0
- package/dist/src/presentation/web/lib/compare-versions.d.ts +7 -0
- package/dist/src/presentation/web/lib/compare-versions.d.ts.map +1 -0
- package/dist/src/presentation/web/lib/compare-versions.js +19 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +1 -0
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/routes-manifest.json +6 -0
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +25 -25
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +25 -25
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +20 -20
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +25 -25
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +25 -25
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +18 -18
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/npm-version/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/npm-version/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/npm-version/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/npm-version/route.js +7 -0
- package/web/.next/server/app/api/npm-version/route.js.map +5 -0
- package/web/.next/server/app/api/npm-version/route.js.nft.json +1 -0
- package/web/.next/server/app/api/npm-version/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
- 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 +6 -6
- 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_client-reference-manifest.js +1 -1
- package/web/.next/server/app-paths-manifest.json +1 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_npm-version_route_actions_3acb9a87.js +3 -0
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_npm-version_route_actions_3acb9a87.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js.map +1 -0
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_c757eb00.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_c757eb00.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_7eb49631.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_7eb49631.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__19fb0bfe._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__19fb0bfe._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3d6f6b0e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3d6f6b0e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__42020c54._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__42020c54._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__845a9d2a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9cb60e1e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9cb60e1e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_3fafea0f._.js → _1c6ab51b._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_3fafea0f._.js.map → _1c6ab51b._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_eca4aa07._.js → _3084f619._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_eca4aa07._.js.map → _3084f619._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_cb93a788._.js → _5ea6943e._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_cb93a788._.js.map → _5ea6943e._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_3c53a23d._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_3c53a23d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_befd865a.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_befd865a.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ec8c7a4f._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_ec8c7a4f._.js.map +1 -1
- 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 +30 -30
- package/web/.next/static/chunks/0a113dc589f3a485.css +1 -0
- package/web/.next/static/chunks/{71f3fb72d47e709b.js → 105544eda28b848d.js} +1 -1
- package/web/.next/static/chunks/{356b41f959ceb6dc.js → 1f2a8defedb705ef.js} +1 -1
- package/web/.next/static/chunks/2d9cd04a8caa4cd7.js +1 -0
- package/web/.next/static/chunks/{133cef90b3975d8f.js → 3707755dd9dd0ba9.js} +1 -1
- package/web/.next/static/chunks/45747d2ddb2f9e95.js +2 -0
- package/web/.next/static/chunks/57209325510f250a.js +1 -0
- package/web/.next/static/chunks/6d71524e05ac43fd.js +1 -0
- package/web/.next/static/chunks/{43ac66e5699a245a.js → 988266fb4cea5f2c.js} +1 -1
- package/web/.next/static/chunks/{24e64b7a634794ad.js → da114e54edab0df4.js} +1 -1
- package/web/.next/static/chunks/{e01c63f00ba7ec95.js → da83d86cc8f061a4.js} +1 -1
- package/web/.next/static/chunks/{6b3282453b0bdc6e.js → e838d58237f52c10.js} +1 -1
- package/web/.next/static/chunks/17c31f43cf41eda4.js +0 -1
- package/web/.next/static/chunks/4d4019cbe85eaedc.css +0 -1
- package/web/.next/static/chunks/761b0946d122beec.js +0 -1
- package/web/.next/static/chunks/d1f5da71a9abf369.js +0 -1
- package/web/.next/static/chunks/e7d1e440160f9fc2.js +0 -2
- /package/web/.next/static/{kPS64EVb81p_02U5q_c7b → NkO6WC62HwbkuDY-u8yVG}/_buildManifest.js +0 -0
- /package/web/.next/static/{kPS64EVb81p_02U5q_c7b → NkO6WC62HwbkuDY-u8yVG}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{kPS64EVb81p_02U5q_c7b → NkO6WC62HwbkuDY-u8yVG}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/app/api/npm-version/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAsB,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC,CAejD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
export async function GET() {
|
|
3
|
+
const packageName = '@shepai/cli';
|
|
4
|
+
try {
|
|
5
|
+
const res = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
|
|
6
|
+
next: { revalidate: 300 },
|
|
7
|
+
});
|
|
8
|
+
if (!res.ok) {
|
|
9
|
+
return NextResponse.json({ error: `npm registry returned ${res.status}` }, { status: 502 });
|
|
10
|
+
}
|
|
11
|
+
const data = (await res.json());
|
|
12
|
+
return NextResponse.json({ latest: data.version ?? null });
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
const message = error instanceof Error ? error.message : 'Failed to check npm version';
|
|
16
|
+
return NextResponse.json({ error: message }, { status: 502 });
|
|
17
|
+
}
|
|
18
|
+
}
|
package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawer-action-bar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAoB,MAAM,4BAA4B,CAAC;AAmEzF,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,YAAoB,EACpB,WAAmB,EACnB,QAAQ,EACR,SAAS,EAAE,mBAAmB,EAC9B,iBAAiB,GAClB,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"drawer-action-bar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAoB,MAAM,4BAA4B,CAAC;AAmEzF,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,YAAoB,EACpB,WAAmB,EACnB,QAAQ,EACR,SAAS,EAAE,mBAAmB,EAC9B,iBAAiB,GAClB,EAAE,oBAAoB,2CA2XtB"}
|
|
@@ -83,8 +83,9 @@ export function DrawerActionBar({ onReject, onApprove, approveLabel, revisionPla
|
|
|
83
83
|
const [hoverExpanded, setHoverExpanded] = useState(false);
|
|
84
84
|
const [ctrlHeld, setCtrlHeld] = useState(false);
|
|
85
85
|
const [shiftHeld, setShiftHeld] = useState(false);
|
|
86
|
-
const
|
|
87
|
-
const
|
|
86
|
+
const hasText = chatInput.trim().length > 0;
|
|
87
|
+
const approveExpanded = hasText ? hoverExpanded || (ctrlHeld && shiftHeld) : !hoverExpanded;
|
|
88
|
+
const rejectHighlighted = hasText ? ctrlHeld && !shiftHeld : false;
|
|
88
89
|
const dragCounterRef = useRef(0);
|
|
89
90
|
const sessionIdRef = useRef(crypto.randomUUID());
|
|
90
91
|
const formRef = useRef(null);
|
|
@@ -247,8 +248,8 @@ export function DrawerActionBar({ onReject, onApprove, approveLabel, revisionPla
|
|
|
247
248
|
function handleFormSubmit(e) {
|
|
248
249
|
e.preventDefault();
|
|
249
250
|
const text = chatInput.trim();
|
|
250
|
-
if (
|
|
251
|
-
// Approve mode
|
|
251
|
+
if (approveExpanded) {
|
|
252
|
+
// Approve mode
|
|
252
253
|
approveSound.play();
|
|
253
254
|
onApprove();
|
|
254
255
|
clearForm();
|
|
@@ -269,13 +270,13 @@ export function DrawerActionBar({ onReject, onApprove, approveLabel, revisionPla
|
|
|
269
270
|
}
|
|
270
271
|
}, []);
|
|
271
272
|
const modKey = typeof navigator !== 'undefined' && /Mac/i.test(navigator.userAgent) ? '⌘' : 'Ctrl';
|
|
272
|
-
return (_jsxs("div", { className: "border-border shrink-0 border-t", children: [children, onReject ? (_jsx(TooltipProvider, { delayDuration: 400, children: _jsx("form", { ref: formRef, onSubmit: handleFormSubmit, className: "p-3", children: _jsx("div", { role: "region", "aria-label": "File drop zone", "data-drag-over": isDragOver ? 'true' : 'false', onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, className: cn('rounded-md border-2 border-transparent transition-colors', isDragOver && 'border-primary/50 bg-primary/5'), children: _jsxs("div", { className: "border-input focus-within:ring-ring/50 focus-within:border-ring flex flex-col overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] focus-within:ring-[3px]", children: [_jsx(Textarea, { placeholder: revisionPlaceholder ?? 'Ask AI to revise...', "aria-label": revisionPlaceholder ?? 'Ask AI to revise...', disabled: disabled, value: chatInput, onChange: (e) => setChatInput(e.target.value), onKeyDown: handleKeyDown, onPaste: handlePaste, rows: 3, className: "max-h-[35dvh] min-h-0 flex-1 resize-none overflow-y-auto rounded-none border-0 shadow-none focus-visible:ring-0", "data-testid": "drawer-chat-input" }), attachments.length > 0 && (_jsx("div", { className: "flex flex-wrap items-center gap-1.5 px-3 py-2", children: attachments.map((file) => (_jsx(AttachmentChip, { name: file.name, size: file.size, mimeType: file.mimeType, path: file.path, onRemove: () => handleRemoveFile(file.id), disabled: disabled, loading: file.loading }, file.id))) })), uploadError ? (_jsx("p", { className: "text-destructive px-3 pb-2 text-xs", children: uploadError })) : null, _jsxs("div", { className: "border-input flex items-center gap-2 border-t px-3 py-1.5", children: [_jsxs("span", { className: "text-muted-foreground flex-1 truncate text-[11px]", children: [_jsxs("kbd", { className: "bg-muted rounded px-1 py-0.5 font-mono text-[10px]", children: [modKey, "+Enter"] }), ' ',
|
|
273
|
+
return (_jsxs("div", { className: "border-border shrink-0 border-t", children: [children, onReject ? (_jsx(TooltipProvider, { delayDuration: 400, children: _jsx("form", { ref: formRef, onSubmit: handleFormSubmit, className: "p-3", children: _jsx("div", { role: "region", "aria-label": "File drop zone", "data-drag-over": isDragOver ? 'true' : 'false', onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, className: cn('rounded-md border-2 border-transparent transition-colors', isDragOver && 'border-primary/50 bg-primary/5'), children: _jsxs("div", { className: "border-input focus-within:ring-ring/50 focus-within:border-ring flex flex-col overflow-hidden rounded-md border shadow-xs transition-[color,box-shadow] focus-within:ring-[3px]", children: [_jsx(Textarea, { placeholder: revisionPlaceholder ?? 'Ask AI to revise...', "aria-label": revisionPlaceholder ?? 'Ask AI to revise...', disabled: disabled, value: chatInput, onChange: (e) => setChatInput(e.target.value), onKeyDown: handleKeyDown, onPaste: handlePaste, rows: 3, className: "max-h-[35dvh] min-h-0 flex-1 resize-none overflow-y-auto rounded-none border-0 shadow-none focus-visible:ring-0", "data-testid": "drawer-chat-input" }), attachments.length > 0 && (_jsx("div", { className: "flex flex-wrap items-center gap-1.5 px-3 py-2", children: attachments.map((file) => (_jsx(AttachmentChip, { name: file.name, size: file.size, mimeType: file.mimeType, path: file.path, onRemove: () => handleRemoveFile(file.id), disabled: disabled, loading: file.loading }, file.id))) })), uploadError ? (_jsx("p", { className: "text-destructive px-3 pb-2 text-xs", children: uploadError })) : null, _jsxs("div", { className: "border-input flex items-center gap-2 border-t px-3 py-1.5", children: [_jsxs("span", { className: "text-muted-foreground flex-1 truncate text-[11px]", children: [_jsxs("kbd", { className: "bg-muted rounded px-1 py-0.5 font-mono text-[10px]", children: [modKey, "+Enter"] }), ' ', hasText ? 'reject' : 'approve'] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: handleAddFiles, disabled: disabled, "aria-label": "Attach files", className: "text-muted-foreground hover:text-foreground cursor-pointer rounded p-1 transition-colors", children: _jsx(PaperclipIcon, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { side: "top", children: "Attach files" })] }), _jsx("div", { onMouseLeave: () => setHoverExpanded(false), children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "submit", disabled: disabled, "data-testid": "drawer-action-submit", className: cn('relative flex h-8 min-w-[10rem] cursor-pointer items-center overflow-hidden rounded-md border pr-10 pl-4 text-sm font-medium whitespace-nowrap transition-colors', 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50', approveExpanded
|
|
273
274
|
? 'border-blue-400/60 text-white'
|
|
274
275
|
: rejectHighlighted
|
|
275
276
|
? 'border-primary bg-muted ring-primary/30 shadow-sm ring-1'
|
|
276
277
|
: 'border-border bg-muted/50 hover:bg-muted shadow-sm'), children: [_jsx("div", { className: "pointer-events-none absolute inset-0 bg-blue-500/85 transition-transform duration-300 ease-in-out", style: {
|
|
277
278
|
transform: approveExpanded ? 'translateX(0)' : 'translateX(100%)',
|
|
278
|
-
} }), _jsxs("span", { className: cn('absolute inset-0 z-10 flex items-center justify-center gap-1.5 pr-8 transition-opacity duration-300', approveExpanded ? 'opacity-0' : 'opacity-100'), children: [_jsx(Send, { className: "h-3.5 w-3.5 shrink-0" }), "Reject"] }), _jsxs("span", { className: cn('absolute inset-0 z-10 flex items-center justify-center gap-1.5 text-white transition-opacity duration-300', approveExpanded ? 'opacity-100' : 'opacity-0'), children: [_jsx(Check, { className: "h-3.5 w-3.5 shrink-0" }), approveLabel] }), _jsx("span", { className: cn('border-input/60 absolute inset-y-0 right-0 z-20 flex w-8 cursor-pointer items-center justify-center rounded-r-[5px] border-l bg-blue-500/85 transition-opacity duration-300',
|
|
279
|
+
} }), _jsxs("span", { className: cn('absolute inset-0 z-10 flex items-center justify-center gap-1.5 pr-8 transition-opacity duration-300', approveExpanded ? 'opacity-0' : 'opacity-100'), children: [_jsx(Send, { className: "h-3.5 w-3.5 shrink-0" }), "Reject"] }), _jsxs("span", { className: cn('absolute inset-0 z-10 flex items-center justify-center gap-1.5 text-white transition-opacity duration-300', approveExpanded ? 'opacity-100' : 'opacity-0'), children: [_jsx(Check, { className: "h-3.5 w-3.5 shrink-0" }), approveLabel] }), _jsx("span", { className: cn('border-input/60 absolute inset-y-0 right-0 z-20 flex w-8 cursor-pointer items-center justify-center rounded-r-[5px] border-l bg-blue-500/85 transition-opacity duration-300', !hasText && !hoverExpanded && 'pointer-events-none opacity-0'), onMouseEnter: () => setHoverExpanded(true), children: _jsx(ChevronLeft, { className: "h-3.5 w-3.5 text-white" }) })] }) }), _jsx(TooltipContent, { side: "top", children: approveExpanded ? approveLabel : 'Send revision feedback' })] }) })] })] }) }) }) })) : (_jsx("div", { className: "flex items-center gap-2 px-4 pb-4", children: _jsx(Button, { type: "button", className: "flex-1", disabled: disabled, onClick: () => {
|
|
279
280
|
approveSound.play();
|
|
280
281
|
onApprove();
|
|
281
282
|
}, children: approveLabel }) }))] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-badge.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"version-badge.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,MAAM,EACN,UAAU,EACV,KAAa,EACb,WAA2B,EAC3B,WAAW,EACX,YAAY,GACb,EAAE,iBAAiB,2CAyDnB"}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
|
|
4
|
+
import { useNpmVersionCheck } from '../../../hooks/use-npm-version-check.js';
|
|
4
5
|
export function VersionBadge({ version, branch, commitHash, isDev = false, packageName = '@shepai/cli', description, instancePath, }) {
|
|
5
6
|
const shortHash = commitHash?.slice(0, 7);
|
|
7
|
+
const { latest, updateAvailable } = useNpmVersionCheck(version);
|
|
6
8
|
// In dev mode show "1.92.2-dev", in production show "v1.92.2"
|
|
7
9
|
const displayVersion = isDev ? `${version}-dev` : `v${version}`;
|
|
8
|
-
|
|
10
|
+
const npmUrl = `https://www.npmjs.com/package/${packageName}`;
|
|
11
|
+
return (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { className: "text-muted-foreground/80 hover:text-muted-foreground relative cursor-default text-[11px] leading-tight transition-colors", "data-testid": "version-label", children: [displayVersion, updateAvailable ? (_jsx("span", { className: "absolute -top-0.5 -right-1.5 size-1.5 rounded-full bg-emerald-400", "data-testid": "update-dot" })) : null] }) }), _jsxs(TooltipContent, { side: "right", className: "max-w-[280px] space-y-1 p-3 text-left", children: [_jsx("div", { className: "mb-1.5 text-xs font-semibold", children: packageName }), description ? (_jsx("div", { className: "text-[10px] leading-snug opacity-70", children: description })) : null, _jsxs("div", { className: "border-t border-white/10 pt-1.5", children: [_jsx(Row, { label: "Version", value: displayVersion }), isDev && branch ? _jsx(Row, { label: "Branch", value: branch }) : null, isDev && shortHash ? _jsx(Row, { label: "Commit", value: shortHash, mono: true }) : null, isDev && instancePath ? _jsx(Row, { label: "Path", value: instancePath, mono: true }) : null, latest ? (_jsx(Row, { label: "Latest", value: `v${latest}`, highlight: updateAvailable })) : null] }), updateAvailable ? (_jsx("div", { className: "border-t border-white/10 pt-1.5", children: _jsxs("a", { href: npmUrl, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-[10px] font-medium text-emerald-400 transition-colors hover:text-emerald-300", "data-testid": "upgrade-link", children: ["Upgrade to v", latest, " \u2192"] }) })) : null] })] }) }));
|
|
9
12
|
}
|
|
10
13
|
function Row({ label, value, highlight, mono, }) {
|
|
11
14
|
return (_jsxs("div", { className: "flex items-center justify-between gap-4 text-[10px]", children: [_jsx("span", { className: "opacity-60", children: label }), _jsx("span", { className: [
|
|
12
|
-
highlight ? 'font-medium text-
|
|
15
|
+
highlight ? 'font-medium text-emerald-400' : '',
|
|
13
16
|
mono || !highlight ? 'font-mono' : '',
|
|
14
17
|
]
|
|
15
18
|
.filter(Boolean)
|
package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts
CHANGED
|
@@ -11,4 +11,10 @@ export declare const Development: Story;
|
|
|
11
11
|
export declare const LongBranch: Story;
|
|
12
12
|
/** Minimal info — no optional fields. */
|
|
13
13
|
export declare const Minimal: Story;
|
|
14
|
+
/** Update available — green dot appears, tooltip shows "Upgrade to v2.0.0" link. */
|
|
15
|
+
export declare const UpdateAvailable: Story;
|
|
16
|
+
/** Update available in dev mode — green dot + upgrade link alongside dev info. */
|
|
17
|
+
export declare const UpdateAvailableDev: Story;
|
|
18
|
+
/** Fetch error — no update info shown, badge behaves normally. */
|
|
19
|
+
export declare const FetchError: Story;
|
|
14
20
|
//# sourceMappingURL=version-badge.stories.d.ts.map
|
package/dist/src/presentation/web/components/common/version-badge/version-badge.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-badge.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"version-badge.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/version-badge/version-badge.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAa,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAmC/C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CAOnC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,YAAY,CAAC,CAAC;AAE3C,mFAAmF;AACnF,eAAO,MAAM,UAAU,EAAE,KAOxB,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,WAAW,EAAE,KAWzB,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,UAAU,EAAE,KAWxB,CAAC;AAEF,yCAAyC;AACzC,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,eAAe,EAAE,KAO7B,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,kBAAkB,EAAE,KAWhC,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,UAAU,EAAE,KAOxB,CAAC"}
|
|
@@ -1,4 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
import { VersionBadge } from './version-badge.js';
|
|
3
|
+
/**
|
|
4
|
+
* Decorator that mocks the /api/npm-version endpoint to return a specific latest version.
|
|
5
|
+
*/
|
|
6
|
+
function withNpmVersion(latest) {
|
|
7
|
+
return (Story) => {
|
|
8
|
+
const originalFetch = window.fetch;
|
|
9
|
+
window.fetch = (async (input, init) => {
|
|
10
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
|
|
11
|
+
if (url.includes('/api/npm-version')) {
|
|
12
|
+
return new Response(JSON.stringify({ latest }), {
|
|
13
|
+
status: 200,
|
|
14
|
+
headers: { 'Content-Type': 'application/json' },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return originalFetch(input, init);
|
|
18
|
+
});
|
|
19
|
+
return _jsx(Story, {});
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Decorator that mocks fetch to return an error for the npm version endpoint. */
|
|
23
|
+
const withNpmVersionError = (Story) => {
|
|
24
|
+
const originalFetch = window.fetch;
|
|
25
|
+
window.fetch = (async (input, init) => {
|
|
26
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
|
|
27
|
+
if (url.includes('/api/npm-version')) {
|
|
28
|
+
return new Response(JSON.stringify({ error: 'Not found' }), { status: 502 });
|
|
29
|
+
}
|
|
30
|
+
return originalFetch(input, init);
|
|
31
|
+
});
|
|
32
|
+
return _jsx(Story, {});
|
|
33
|
+
};
|
|
2
34
|
const meta = {
|
|
3
35
|
title: 'Common/VersionBadge',
|
|
4
36
|
component: VersionBadge,
|
|
@@ -10,6 +42,7 @@ const meta = {
|
|
|
10
42
|
export default meta;
|
|
11
43
|
/** Production mode — shows "v1.90.0" as dimmed text, no dev details in tooltip. */
|
|
12
44
|
export const Production = {
|
|
45
|
+
decorators: [withNpmVersion('1.90.0')],
|
|
13
46
|
args: {
|
|
14
47
|
version: '1.90.0',
|
|
15
48
|
packageName: '@shepai/cli',
|
|
@@ -18,6 +51,7 @@ export const Production = {
|
|
|
18
51
|
};
|
|
19
52
|
/** Development mode — shows "1.90.0-dev", tooltip includes branch, commit, and path. */
|
|
20
53
|
export const Development = {
|
|
54
|
+
decorators: [withNpmVersion('1.90.0')],
|
|
21
55
|
args: {
|
|
22
56
|
version: '1.90.0',
|
|
23
57
|
isDev: true,
|
|
@@ -30,6 +64,7 @@ export const Development = {
|
|
|
30
64
|
};
|
|
31
65
|
/** Development mode with a long branch name — shown in tooltip. */
|
|
32
66
|
export const LongBranch = {
|
|
67
|
+
decorators: [withNpmVersion('1.90.0')],
|
|
33
68
|
args: {
|
|
34
69
|
version: '1.90.0',
|
|
35
70
|
isDev: true,
|
|
@@ -42,7 +77,39 @@ export const LongBranch = {
|
|
|
42
77
|
};
|
|
43
78
|
/** Minimal info — no optional fields. */
|
|
44
79
|
export const Minimal = {
|
|
80
|
+
decorators: [withNpmVersion('1.0.0')],
|
|
45
81
|
args: {
|
|
46
82
|
version: '1.0.0',
|
|
47
83
|
},
|
|
48
84
|
};
|
|
85
|
+
/** Update available — green dot appears, tooltip shows "Upgrade to v2.0.0" link. */
|
|
86
|
+
export const UpdateAvailable = {
|
|
87
|
+
decorators: [withNpmVersion('2.0.0')],
|
|
88
|
+
args: {
|
|
89
|
+
version: '1.90.0',
|
|
90
|
+
packageName: '@shepai/cli',
|
|
91
|
+
description: 'Autonomous AI Native SDLC Platform',
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
/** Update available in dev mode — green dot + upgrade link alongside dev info. */
|
|
95
|
+
export const UpdateAvailableDev = {
|
|
96
|
+
decorators: [withNpmVersion('2.0.0')],
|
|
97
|
+
args: {
|
|
98
|
+
version: '1.90.0',
|
|
99
|
+
isDev: true,
|
|
100
|
+
branch: 'feat/npm-version-checker',
|
|
101
|
+
commitHash: '5a84c148b3e2f1a9c7d6e8b4a2f1c3d5e7f9a1b3',
|
|
102
|
+
packageName: '@shepai/cli',
|
|
103
|
+
description: 'Autonomous AI Native SDLC Platform',
|
|
104
|
+
instancePath: '/home/user/projects/shep',
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
/** Fetch error — no update info shown, badge behaves normally. */
|
|
108
|
+
export const FetchError = {
|
|
109
|
+
decorators: [withNpmVersionError],
|
|
110
|
+
args: {
|
|
111
|
+
version: '1.90.0',
|
|
112
|
+
packageName: '@shepai/cli',
|
|
113
|
+
description: 'Autonomous AI Native SDLC Platform',
|
|
114
|
+
},
|
|
115
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface NpmVersionCheckResult {
|
|
2
|
+
/** Latest version on npm, or null if not yet fetched / error */
|
|
3
|
+
latest: string | null;
|
|
4
|
+
/** Whether a newer version is available on npm */
|
|
5
|
+
updateAvailable: boolean;
|
|
6
|
+
/** True while the fetch is in progress */
|
|
7
|
+
loading: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function useNpmVersionCheck(currentVersion: string): NpmVersionCheckResult;
|
|
10
|
+
//# sourceMappingURL=use-npm-version-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-npm-version-check.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-npm-version-check.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kDAAkD;IAClD,eAAe,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,qBAAqB,CA+BhF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { compareVersions } from '../lib/compare-versions.js';
|
|
4
|
+
export function useNpmVersionCheck(currentVersion) {
|
|
5
|
+
const [latest, setLatest] = useState(null);
|
|
6
|
+
const [loading, setLoading] = useState(true);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
let cancelled = false;
|
|
9
|
+
async function check() {
|
|
10
|
+
try {
|
|
11
|
+
const res = await fetch('/api/npm-version');
|
|
12
|
+
if (!res.ok)
|
|
13
|
+
return;
|
|
14
|
+
const data = (await res.json());
|
|
15
|
+
if (!cancelled && data.latest) {
|
|
16
|
+
setLatest(data.latest);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Silently fail — version check is non-critical
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
if (!cancelled)
|
|
24
|
+
setLoading(false);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
check();
|
|
28
|
+
return () => {
|
|
29
|
+
cancelled = true;
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
const updateAvailable = latest !== null && compareVersions(latest, currentVersion) > 0;
|
|
33
|
+
return { latest, updateAvailable, loading };
|
|
34
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two semver version strings.
|
|
3
|
+
* Returns 1 if a > b, -1 if a < b, 0 if equal.
|
|
4
|
+
* Only compares major.minor.patch (ignores pre-release/build metadata).
|
|
5
|
+
*/
|
|
6
|
+
export declare function compareVersions(a: string, b: string): -1 | 0 | 1;
|
|
7
|
+
//# sourceMappingURL=compare-versions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare-versions.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/compare-versions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAWhE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two semver version strings.
|
|
3
|
+
* Returns 1 if a > b, -1 if a < b, 0 if equal.
|
|
4
|
+
* Only compares major.minor.patch (ignores pre-release/build metadata).
|
|
5
|
+
*/
|
|
6
|
+
export function compareVersions(a, b) {
|
|
7
|
+
const parse = (v) => v.split('-')[0].split('.').map(Number);
|
|
8
|
+
const pa = parse(a);
|
|
9
|
+
const pb = parse(b);
|
|
10
|
+
for (let i = 0; i < 3; i++) {
|
|
11
|
+
const na = pa[i] ?? 0;
|
|
12
|
+
const nb = pb[i] ?? 0;
|
|
13
|
+
if (na > nb)
|
|
14
|
+
return 1;
|
|
15
|
+
if (na < nb)
|
|
16
|
+
return -1;
|
|
17
|
+
}
|
|
18
|
+
return 0;
|
|
19
|
+
}
|