From a23fc97c567b9ea06a1a5f5c410b4f454d7ee234 Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Tue, 1 Jul 2025 14:45:34 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../[namespace]/[project-slug]/[tab]/page.tsx | 51 -------------- .../marketplace-public-project-detail.tsx | 66 ++++++++++++------- .../src/components/project-pricing-plans.tsx | 3 +- todo.md | 25 ++++--- 4 files changed, 55 insertions(+), 90 deletions(-) delete mode 100644 apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/[tab]/page.tsx diff --git a/apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/[tab]/page.tsx b/apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/[tab]/page.tsx deleted file mode 100644 index 0f1285af..00000000 --- a/apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/[tab]/page.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { parseProjectIdentifier } from '@agentic/platform-validators' -import { notFound } from 'next/navigation' - -import { toastError } from '@/lib/notifications' - -import { MarketplacePublicProjectDetail } from '../marketplace-public-project-detail' -import { - type MarketplacePublicProjectDetailTab, - marketplacePublicProjectDetailTabsSet -} from '../utils' - -export default async function PublicProjectDetailPageTabPage({ - params -}: { - params: Promise<{ - namespace: string - 'project-slug': string - tab: string - }> -}) { - const { - namespace: rawNamespace, - 'project-slug': rawProjectSlug, - tab - } = await params - - if (!marketplacePublicProjectDetailTabsSet.has(tab)) { - return notFound() - } - - try { - const namespace = decodeURIComponent(rawNamespace) - const projectSlug = decodeURIComponent(rawProjectSlug) - - const { projectIdentifier } = parseProjectIdentifier( - `${namespace}/${projectSlug}`, - { strict: true } - ) - - return ( - - ) - } catch (err: any) { - void toastError(err, { label: 'Invalid project identifier' }) - - return notFound() - } -} diff --git a/apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/marketplace-public-project-detail.tsx b/apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/marketplace-public-project-detail.tsx index ddc72197..136ea0f8 100644 --- a/apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/marketplace-public-project-detail.tsx +++ b/apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/marketplace-public-project-detail.tsx @@ -8,8 +8,8 @@ import { useRouter, useSearchParams } from 'next/navigation' import plur from 'plur' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' -import { ActiveLink } from '@/components/active-link' import { useAgentic } from '@/components/agentic-provider' +import { CodeBlock } from '@/components/code-block' import { ExampleUsage } from '@/components/example-usage' import { HeroButton } from '@/components/hero-button' import { LoadingIndicator } from '@/components/loading-indicator' @@ -29,15 +29,14 @@ import { useQuery } from '@/lib/query-client' import { type MarketplacePublicProjectDetailTab, + marketplacePublicProjectDetailTabsSet, MAX_TOOLS_TO_SHOW } from './utils' export function MarketplacePublicProjectDetail({ - projectIdentifier, - tab = 'overview' + projectIdentifier }: { projectIdentifier: string - tab?: MarketplacePublicProjectDetailTab }) { const ctx = useAgentic() const searchParams = useSearchParams() @@ -177,13 +176,18 @@ export function MarketplacePublicProjectDetail({ ) }, [deployment]) - const inferredTab = useMemo(() => { + const tab = useMemo(() => { + const tab = searchParams.get('tab')?.toLowerCase() + if (!tab || !marketplacePublicProjectDetailTabsSet.has(tab)) { + return 'overview' + } + if (tab === 'readme' && !deployment?.readme?.trim()) { return 'overview' } - return tab - }, [tab, deployment]) + return tab as MarketplacePublicProjectDetailTab + }, [searchParams, deployment]) return ( @@ -196,16 +200,16 @@ export function MarketplacePublicProjectDetail({

Project "{projectIdentifier}" not found

) : (
- + { if (value === 'overview') { router.push(`/marketplace/projects/${projectIdentifier}`) } else { router.push( - `/marketplace/projects/${projectIdentifier}/${value}` + `/marketplace/projects/${projectIdentifier}?tab=${value}` ) } }} @@ -243,7 +247,7 @@ export function MarketplacePublicProjectDetail({
- {inferredTab === 'overview' && ( + {tab === 'overview' && (

Overview @@ -292,7 +296,7 @@ export function MarketplacePublicProjectDetail({ variant='outline' > View{' '} {deployment.tools.length - @@ -328,7 +332,7 @@ export function MarketplacePublicProjectDetail({ )} - {deployment?.readme?.trim() && inferredTab === 'readme' && ( + {deployment?.readme?.trim() && tab === 'readme' && ( )} - {inferredTab === 'tools' && ( + {tab === 'tools' && (

Tools @@ -370,9 +374,15 @@ export function MarketplacePublicProjectDetail({ -
-                                  {JSON.stringify(tool.inputSchema, null, 2)}
-                                
+
@@ -389,9 +399,15 @@ export function MarketplacePublicProjectDetail({ -
-                                    {JSON.stringify(tool.outputSchema, null, 2)}
-                                  
+
)} @@ -402,7 +418,7 @@ export function MarketplacePublicProjectDetail({ )} - {inferredTab === 'pricing' && ( + {tab === 'pricing' && (

Pricing @@ -419,7 +435,7 @@ export function MarketplacePublicProjectDetail({ )} - {inferredTab === 'debug' && ( + {tab === 'debug' && (

Debug @@ -476,11 +492,11 @@ function ProjectHeader({ className='justify-self-end' disabled={tab === 'pricing'} > - Subscribe to {project.identifier} - +

diff --git a/apps/web/src/components/project-pricing-plans.tsx b/apps/web/src/components/project-pricing-plans.tsx index 8f8e2992..c138db8a 100644 --- a/apps/web/src/components/project-pricing-plans.tsx +++ b/apps/web/src/components/project-pricing-plans.tsx @@ -15,12 +15,13 @@ export function ProjectPricingPlans({ onSubscribe: (planSlug: string) => void className?: string }) { + // TODO: add support for different pricing intervals const numPricingPlans = project.lastPublishedDeployment?.pricingPlans.length || 1 return (
@agentic > search -- add a basic page + docs on pricing -- [react query prefetching for public pages](https://tanstack.com/query/latest/docs/framework/react/guides/advanced-ssr#prefetching-and-dehydrating-data) -- add [ping](https://modelcontextprotocol.io/specification/2025-03-26/basic/utilities/ping) support to mcp servers + - tool input/output schemas; move `$schema` to top +- add a basic page + docs on pricing => contact +- [**react query prefetching for public pages**](https://tanstack.com/query/latest/docs/framework/react/guides/advanced-ssr#prefetching-and-dehydrating-data) - add ability to point at remote readmes, icons, files, urls, etc and upload to our own blob storage at deploy time - **create agentic products for select legacy tools** @@ -131,3 +125,8 @@ - add support for [`@google/genai`](https://github.com/googleapis/js-genai) tools adapter - currently difficult due to their use of non-standard json schemas - validate example args against the tool's input schema during config validation +- add scroll appearance motion to hero animation +- add ts sdk examples to e2e tests +- add feature about optimized context to docs +- import react example usage component into docs +- add [ping](https://modelcontextprotocol.io/specification/2025-03-26/basic/utilities/ping) support to mcp servers