feat(cli): WIP improve prompting for version when publishing

pull/717/head
Travis Fischer 2025-07-01 02:35:31 -05:00
rodzic 030200ce91
commit 5d7992e672
9 zmienionych plików z 164 dodań i 58 usunięć

Wyświetl plik

@ -35,6 +35,11 @@
"format": "uri",
"description": "Optional URL to the source code of the project (eg, GitHub repo)."
},
"websiteUrl": {
"type": "string",
"format": "uri",
"description": "Optional URL to the product's website."
},
"origin": {
"anyOf": [
{

Wyświetl plik

@ -1,6 +1,8 @@
'use client'
import { assert, omit, sanitizeSearchParams } from '@agentic/platform-core'
import { ExternalLinkIcon } from 'lucide-react'
import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation'
import { useCallback, useEffect, useRef, useState } from 'react'
@ -8,6 +10,7 @@ import { useAgentic } from '@/components/agentic-provider'
import { LoadingIndicator } from '@/components/loading-indicator'
import { PageContainer } from '@/components/page-container'
import { ProjectPricingPlans } from '@/components/project-pricing-plans'
import { GitHubIcon } from '@/icons/github'
import { toast, toastError } from '@/lib/notifications'
import { useQuery } from '@/lib/query-client'
@ -148,13 +151,52 @@ export function MarketplaceProjectIndex({
) : !project ? (
<p>Project "{projectIdentifier}" not found</p>
) : (
<>
<h1
className='text-center text-balance leading-snug md:leading-none
text-4xl font-extrabold'
>
{project.name}
</h1>
<div className='flex flex-col'>
<div className='flex flex-col gap-2'>
<div className='flex flex-row gap-2.5 items-center'>
<img
src={
project.lastPublishedDeployment?.iconUrl ||
project.user?.image ||
'/agentic-icon-circle-light.svg'
}
alt={project.name}
className='aspect-square w-8 h-8'
/>
<h1 className='font-semibold text-balance text-lg text-gray-900 leading-tight'>
{project.name}
</h1>
</div>
<div className='flex flex-row gap-2.5 items-center'>
<div className='text-sm text-gray-500'>
{project.identifier}
</div>
{project.lastPublishedDeployment?.websiteUrl && (
<Link
href={project.lastPublishedDeployment.websiteUrl}
className='text-sm text-gray-500'
>
<ExternalLinkIcon />
<span>Homepage</span>
</Link>
)}
{project.lastPublishedDeployment?.sourceUrl && (
<Link
href={project.lastPublishedDeployment.sourceUrl}
className='text-sm text-gray-500'
>
<GitHubIcon />
<span>GitHub</span>
</Link>
)}
</div>
</div>
<div className='mt-8'>
<pre className='max-w-lg'>
@ -172,7 +214,7 @@ export function MarketplaceProjectIndex({
isLoadingStripeCheckoutForPlan={isLoadingStripeCheckoutForPlan}
onSubscribe={onSubscribe}
/>
</>
</div>
)}
</section>
</PageContainer>

Wyświetl plik

@ -11,6 +11,9 @@ export default defineConfig({
type: 'mcp',
url: process.env.MCP_ORIGIN_URL!
},
sourceUrl:
'https://github.com/transitive-bullshit/agentic/tree/main/examples/mcp-servers/search',
websiteUrl: 'https://agentic.so',
toolConfigs: [
{
name: 'search',

Wyświetl plik

@ -19,7 +19,8 @@ export function registerDeployCommand({
'The directory to load the Agentic project config from (defaults to cwd). This directory must contain an "agentic.config.{ts,js,json}" project file.'
)
.option('-d, --debug', 'Print out the parsed agentic config and return.')
.option('-p, --publish', 'Publishes the deployment after creating it.')
// TODO
//.option('-p, --publish', 'Publishes the deployment after creating it.')
.action(async (opts) => {
AuthStore.requireAuth()
@ -47,12 +48,17 @@ export function registerDeployCommand({
return
}
// Create the deployment on the backend, validate it, and optionally
// publish it.
// Create the deployment on the backend, validating it in the process.
// Note that the backend performs more validation than the client does
// and is the ultimate source of truth.
const deployment = await oraPromise(
client.createDeployment(config, {
publish: opts.publish ? 'true' : 'false'
}),
client.createDeployment(
config
// TODO: need to prompt to get or confirm version before publishing
// {
// publish: opts.publish ? 'true' : 'false'
// }
),
{
text: `Creating deployment for project "${config.slug}"`,
successText: `Deployment created successfully`,

Wyświetl plik

@ -1,11 +1,10 @@
import { select } from '@clack/prompts'
import { Command } from 'commander'
import { gracefulExit } from 'exit-hook'
import { oraPromise } from 'ora'
import semver from 'semver'
import type { Context } from '../types'
import { AuthStore } from '../lib/auth-store'
import { promptForDeploymentVersion } from '../lib/prompt-for-deployment-version'
import { resolveDeployment } from '../lib/resolve-deployment'
export function registerPublishCommand({
@ -65,39 +64,10 @@ export function registerPublishCommand({
return gracefulExit(1)
}
const initialVersion = deployment.version
const baseVersion =
initialVersion || project.lastPublishedDeploymentVersion || '0.0.0'
const options = [
initialVersion
? { value: initialVersion, label: initialVersion }
: null,
{
value: semver.inc(baseVersion, 'patch'),
label: `${semver.inc(baseVersion, 'patch')} (patch)`
},
{
value: semver.inc(baseVersion, 'minor'),
label: `${semver.inc(baseVersion, 'minor')} (minor)`
},
{
value: semver.inc(baseVersion, 'major'),
label: `${semver.inc(baseVersion, 'major')} (major)`
}
].filter(Boolean)
if (project.lastPublishedDeploymentVersion) {
logger.info(
`Project "${project.identifier}" latest published version is "${project.lastPublishedDeploymentVersion}".\n`
)
} else {
logger.info(`Project "${project.identifier}" is not published yet.\n`)
}
const version = await select({
message: `Select version of deployment "${deployment.identifier}" to publish:`,
options
const version = await promptForDeploymentVersion({
deployment,
project,
logger
})
if (!version || typeof version !== 'string') {

Wyświetl plik

@ -0,0 +1,57 @@
import type { Deployment, Project } from '@agentic/platform-types'
import { select } from '@clack/prompts'
import { gracefulExit } from 'exit-hook'
import semver from 'semver'
import type { Context } from '../types'
export async function promptForDeploymentVersion({
deployment,
project,
logger
}: {
deployment: Deployment
project: Project
logger: Context['logger']
}): Promise<string | undefined> {
const initialVersion = deployment.version
const baseVersion =
initialVersion || project.lastPublishedDeploymentVersion || '0.0.0'
const options = [
initialVersion ? { value: initialVersion, label: initialVersion } : null,
{
value: semver.inc(baseVersion, 'patch'),
label: `${semver.inc(baseVersion, 'patch')} (patch)`
},
{
value: semver.inc(baseVersion, 'minor'),
label: `${semver.inc(baseVersion, 'minor')} (minor)`
},
{
value: semver.inc(baseVersion, 'major'),
label: `${semver.inc(baseVersion, 'major')} (major)`
}
].filter(Boolean)
if (project.lastPublishedDeploymentVersion) {
logger.info(
`Project "${project.identifier}" latest published version is "${project.lastPublishedDeploymentVersion}".\n`
)
} else {
logger.info(`Project "${project.identifier}" is not published yet.\n`)
}
const version = await select({
message: `Select version of deployment "${deployment.identifier}" to publish:`,
options
})
if (!version || typeof version !== 'string') {
logger.error('No version selected')
gracefulExit(1)
return
}
return version
}

Wyświetl plik

@ -768,6 +768,11 @@ export interface components {
* @description Optional URL to the source code of the project (eg, GitHub repo).
*/
sourceUrl?: string;
/**
* Format: uri
* @description Optional URL to the product's website.
*/
websiteUrl?: string;
/** @description User id (e.g. "user_tz4a98xxat96iws9zmbrgj3a") */
userId: string;
/** @description Team id (e.g. "team_tz4a98xxat96iws9zmbrgj3a") */
@ -1040,6 +1045,11 @@ export interface components {
* @description Optional URL to the source code of the project (eg, GitHub repo).
*/
sourceUrl?: string;
/**
* Format: uri
* @description Optional URL to the product's website.
*/
websiteUrl?: string;
/** @description User id (e.g. "user_tz4a98xxat96iws9zmbrgj3a") */
userId: string;
/** @description Team id (e.g. "team_tz4a98xxat96iws9zmbrgj3a") */
@ -2409,6 +2419,11 @@ export interface operations {
* @description Optional URL to the source code of the project (eg, GitHub repo).
*/
sourceUrl?: string;
/**
* Format: uri
* @description Optional URL to the product's website.
*/
websiteUrl?: string;
origin: components["schemas"]["OriginAdapterConfig"];
/**
* @description List of PricingPlans configuring which Stripe subscriptions should be available for the project. Defaults to a single free plan which is useful for developing and testing your project.

Wyświetl plik

@ -38,11 +38,14 @@ export type Consumer = Simplify<
}
>
export type Project = Simplify<
components['schemas']['Project'] & {
Omit<
components['schemas']['Project'],
'lastPublishedDeployment' | 'lastDeployment'
> & {
user?: User
team?: Team
lastPublishedDeployment?: Deployment
lastDeployment?: Deployment
lastPublishedDeployment?: Simplify<Omit<Deployment, 'project'>>
lastDeployment?: Simplify<Omit<Deployment, 'project'>>
/**
* The public base HTTP URL for the project supporting HTTP POST requests for
@ -78,12 +81,14 @@ export type Project = Simplify<
export type Deployment = Simplify<
Omit<
components['schemas']['Deployment'],
'pricingPlans' | 'toolConfigs' | 'defaultRateLimit'
'pricingPlans' | 'toolConfigs' | 'defaultRateLimit' | 'project'
> & {
pricingPlans: PricingPlan[]
toolConfigs: ToolConfig[]
defaultRateLimit: RateLimit
project?: components['schemas']['Project']
project?: Simplify<
Omit<Project, 'lastPublishedDeployment' | 'lastDeployment'>
>
/**
* The public base HTTP URL for the deployment supporting HTTP POST requests
@ -123,16 +128,19 @@ export type Deployment = Simplify<
export type AdminDeployment = Simplify<
Omit<
components['schemas']['AdminDeployment'],
'pricingPlans' | 'toolConfigs' | 'defaultRateLimit' | 'origin'
'pricingPlans' | 'toolConfigs' | 'defaultRateLimit' | 'origin' | 'project'
> & {
pricingPlans: PricingPlan[]
toolConfigs: ToolConfig[]
defaultRateLimit: RateLimit
origin: OriginAdapter
project?: components['schemas']['Project']
} & Pick<
Deployment,
'gatewayBaseUrl' | 'gatewayMcpUrl' | 'marketplaceUrl' | 'adminUrl'
| 'gatewayBaseUrl'
| 'gatewayMcpUrl'
| 'marketplaceUrl'
| 'adminUrl'
| 'project'
>
>

Wyświetl plik

@ -53,7 +53,7 @@
- stripe
- re-add coupons
- declarative json-based pricing
- like https://github.com/tierrun/tier and Saasify
- like Saasify and https://github.com/tierrun/tier
- https://github.com/tierrun/tier/blob/main/pricing/schema.json
- https://blog.tier.run/tier-hello-world-demo
- stripe connect