kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat(cli): WIP improve prompting for version when publishing
rodzic
030200ce91
commit
5d7992e672
|
@ -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": [
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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`,
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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'
|
||||
>
|
||||
>
|
||||
|
||||
|
|
2
todo.md
2
todo.md
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue