Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,975 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { plazaOpenApiExtensions } from './plaza-openapi.mjs';
|
||||
|
||||
const OUTPUT_PATH = path.join(import.meta.dirname, '..', 'openapi.json');
|
||||
const plazaOpenApi = plazaOpenApiExtensions();
|
||||
|
||||
const jsonContent = {
|
||||
openapi: '3.0.3',
|
||||
info: {
|
||||
title: 'MindSpace H5 API',
|
||||
version: '0.1.0',
|
||||
description: 'Generated OpenAPI contract for MindSpace H5, Plaza, and public publication routes.',
|
||||
},
|
||||
servers: [
|
||||
{ url: '/api', description: 'Authenticated H5 API' },
|
||||
{ url: '/', description: 'Public publication and homepage routes' },
|
||||
],
|
||||
tags: [
|
||||
{ name: 'Auth' },
|
||||
{ name: 'Space' },
|
||||
{ name: 'Uploads' },
|
||||
{ name: 'Assets' },
|
||||
{ name: 'Pages' },
|
||||
{ name: 'Publications' },
|
||||
{ name: 'Agent Jobs' },
|
||||
{ name: 'Public Web' },
|
||||
...plazaOpenApi.tags,
|
||||
],
|
||||
paths: {
|
||||
'/auth/register': {
|
||||
post: {
|
||||
tags: ['Auth'],
|
||||
summary: 'Register a user and initialize a MindSpace workspace',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/RegisterRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Registration succeeded',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/RegisterResponseEnvelope' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/auth/login': {
|
||||
post: {
|
||||
tags: ['Auth'],
|
||||
summary: 'Login with username and password',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/LoginRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Authenticated session',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/AuthStatus' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/auth/logout': {
|
||||
post: {
|
||||
tags: ['Auth'],
|
||||
summary: 'Logout current user session',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Logged out',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/SuccessEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/auth/status': {
|
||||
get: {
|
||||
tags: ['Auth'],
|
||||
summary: 'Inspect current auth/session status',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Current auth status',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/AuthStatus' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/space': {
|
||||
get: {
|
||||
tags: ['Space'],
|
||||
summary: 'Get current MindSpace summary, quota, and categories',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Current space',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/DataEnvelope' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/space/quota': {
|
||||
get: {
|
||||
tags: ['Space'],
|
||||
summary: 'Get current quota state',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Quota state',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/space/categories': {
|
||||
get: {
|
||||
tags: ['Space'],
|
||||
summary: 'List current space categories',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Category list',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/space/cleanup': {
|
||||
get: {
|
||||
tags: ['Space'],
|
||||
summary: 'Preview cleanup candidates',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Cleanup candidates',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
tags: ['Space'],
|
||||
summary: 'Delete selected cleanup candidates',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/CleanupRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Cleanup result',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/uploads': {
|
||||
post: {
|
||||
tags: ['Uploads'],
|
||||
summary: 'Create an upload session',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/CreateUploadRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Upload session created',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/uploads/{uploadId}/content': {
|
||||
put: {
|
||||
tags: ['Uploads'],
|
||||
summary: 'Upload raw file bytes',
|
||||
parameters: [{ $ref: '#/components/parameters/UploadId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/octet-stream': {
|
||||
schema: { type: 'string', format: 'binary' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Bytes written',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/uploads/{uploadId}/complete': {
|
||||
post: {
|
||||
tags: ['Uploads'],
|
||||
summary: 'Complete an upload and materialize the asset',
|
||||
parameters: [{ $ref: '#/components/parameters/UploadId' }],
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Asset created',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/uploads/{uploadId}': {
|
||||
delete: {
|
||||
tags: ['Uploads'],
|
||||
summary: 'Cancel upload session',
|
||||
parameters: [{ $ref: '#/components/parameters/UploadId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Upload cancelled',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/assets': {
|
||||
get: {
|
||||
tags: ['Assets'],
|
||||
summary: 'List assets',
|
||||
parameters: [
|
||||
{ name: 'category_id', in: 'query', schema: { type: 'string' } },
|
||||
{ name: 'category_code', in: 'query', schema: { type: 'string' } },
|
||||
],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Asset list',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/assets/{assetId}/download': {
|
||||
get: {
|
||||
tags: ['Assets'],
|
||||
summary: 'Download asset bytes',
|
||||
parameters: [{ $ref: '#/components/parameters/AssetId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Asset content',
|
||||
content: { '*/*': { schema: { type: 'string', format: 'binary' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/assets/{assetId}/thumbnail': {
|
||||
get: {
|
||||
tags: ['Assets'],
|
||||
summary: 'Render asset thumbnail',
|
||||
parameters: [{ $ref: '#/components/parameters/AssetId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'SVG thumbnail',
|
||||
content: { 'image/svg+xml': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/assets/{assetId}/preview': {
|
||||
get: {
|
||||
tags: ['Assets'],
|
||||
summary: 'Render asset preview HTML',
|
||||
parameters: [{ $ref: '#/components/parameters/AssetId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Preview HTML',
|
||||
content: { 'text/html': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/assets/{assetId}': {
|
||||
delete: {
|
||||
tags: ['Assets'],
|
||||
summary: 'Delete asset',
|
||||
parameters: [{ $ref: '#/components/parameters/AssetId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Delete result',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/analyze-chat-save': {
|
||||
post: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Analyze whether an assistant message should be saved as page or asset',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/AnalyzeChatSaveRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Chat save analysis',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/save-from-chat': {
|
||||
post: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Save assistant message into MindSpace',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/SaveFromChatRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Saved page or asset',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/from-asset': {
|
||||
post: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Convert an owned asset into a draft page',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/PageFromAssetRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Draft page created',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages': {
|
||||
get: {
|
||||
tags: ['Pages'],
|
||||
summary: 'List pages',
|
||||
parameters: [{ name: 'status', in: 'query', schema: { type: 'string' } }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Page list',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Create a draft page',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/CreatePageRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Page created',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/{pageId}': {
|
||||
get: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Get page detail and versions',
|
||||
parameters: [{ $ref: '#/components/parameters/PageId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Page detail',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
put: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Create a new page version',
|
||||
parameters: [{ $ref: '#/components/parameters/PageId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/UpdatePageRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Updated page',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/{pageId}/thumbnail': {
|
||||
get: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Render page thumbnail',
|
||||
parameters: [{ $ref: '#/components/parameters/PageId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'SVG thumbnail',
|
||||
content: { 'image/svg+xml': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/{pageId}/preview': {
|
||||
get: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Render safe page preview HTML',
|
||||
parameters: [{ $ref: '#/components/parameters/PageId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Preview HTML',
|
||||
content: { 'text/html': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/{pageId}/publish-check': {
|
||||
post: {
|
||||
tags: ['Publications'],
|
||||
summary: 'Check whether page can be published',
|
||||
parameters: [{ $ref: '#/components/parameters/PageId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/PublishCheckRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Publish check result',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/{pageId}/redacted-copy': {
|
||||
post: {
|
||||
tags: ['Pages'],
|
||||
summary: 'Create a redacted copy of the current page version',
|
||||
parameters: [{ $ref: '#/components/parameters/PageId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/RedactedCopyRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Redacted page created',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/pages/{pageId}/publish': {
|
||||
post: {
|
||||
tags: ['Publications'],
|
||||
summary: 'Publish the current page version',
|
||||
parameters: [{ $ref: '#/components/parameters/PageId' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/PublishPageRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Publication created',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/publications/{publicationId}/offline': {
|
||||
post: {
|
||||
tags: ['Publications'],
|
||||
summary: 'Offline an online publication',
|
||||
parameters: [{ $ref: '#/components/parameters/PublicationId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Publication offlined',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/publications/{publicationId}/stats': {
|
||||
get: {
|
||||
tags: ['Publications'],
|
||||
summary: 'Get publication statistics',
|
||||
parameters: [{ $ref: '#/components/parameters/PublicationId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Publication stats',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/agent/jobs': {
|
||||
get: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'List current user agent jobs',
|
||||
parameters: [{ name: 'limit', in: 'query', schema: { type: 'integer' } }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Job list',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/ListEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Create an agent job bound to owned assets',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/CreateAgentJobRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
201: {
|
||||
description: 'Job created',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/agent/jobs/{jobId}': {
|
||||
get: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Get agent job detail',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Job detail',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/agent/jobs/{jobId}/cancel': {
|
||||
post: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Cancel agent job',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Cancelled job',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/agent/jobs/{jobId}/retry': {
|
||||
post: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Retry agent job',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Retried job',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/mindspace/v1/agent/jobs/{jobId}/run': {
|
||||
post: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Start queued agent job execution',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }],
|
||||
responses: {
|
||||
202: {
|
||||
description: 'Execution started',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/internal/agent/jobs/{jobId}/claim': {
|
||||
post: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Internal worker claims a queued job',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }],
|
||||
security: [{ bearerAuth: [] }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Claimed job payload',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/internal/agent/jobs/{jobId}/assets/{assetId}': {
|
||||
get: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Internal worker downloads an authorized job asset',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }, { $ref: '#/components/parameters/AssetId' }],
|
||||
security: [{ bearerAuth: [] }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Asset content',
|
||||
content: { '*/*': { schema: { type: 'string', format: 'binary' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/internal/agent/jobs/{jobId}/heartbeat': {
|
||||
post: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Internal worker posts heartbeat/progress updates',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }],
|
||||
security: [{ bearerAuth: [] }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/HeartbeatRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Progress updated',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/internal/agent/jobs/{jobId}/complete': {
|
||||
post: {
|
||||
tags: ['Agent Jobs'],
|
||||
summary: 'Internal worker completes or fails a job',
|
||||
parameters: [{ $ref: '#/components/parameters/JobId' }],
|
||||
security: [{ bearerAuth: [] }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/CompleteJobRequest' } } },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Final job state',
|
||||
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataEnvelope' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/u/{ownerSlug}': {
|
||||
get: {
|
||||
tags: ['Public Web'],
|
||||
summary: 'Render public homepage for a user slug',
|
||||
parameters: [{ $ref: '#/components/parameters/OwnerSlug' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Public homepage HTML',
|
||||
content: { 'text/html': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/u/{ownerSlug}/pages/{urlSlug}': {
|
||||
get: {
|
||||
tags: ['Public Web'],
|
||||
summary: 'Render a published page via long public route',
|
||||
parameters: [{ $ref: '#/components/parameters/OwnerSlug' }, { $ref: '#/components/parameters/UrlSlug' }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Published page HTML',
|
||||
content: { 'text/html': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
tags: ['Public Web'],
|
||||
summary: 'Submit password gate for a protected page',
|
||||
parameters: [{ $ref: '#/components/parameters/OwnerSlug' }, { $ref: '#/components/parameters/UrlSlug' }],
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/x-www-form-urlencoded': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['password'],
|
||||
properties: { password: { type: 'string' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Published page HTML or password gate',
|
||||
content: { 'text/html': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/s/{token}': {
|
||||
get: {
|
||||
tags: ['Public Web'],
|
||||
summary: 'Render a private-link publication',
|
||||
parameters: [{ name: 'token', in: 'path', required: true, schema: { type: 'string' } }],
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Published page HTML',
|
||||
content: { 'text/html': { schema: { type: 'string' } } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
...plazaOpenApi.paths,
|
||||
},
|
||||
components: {
|
||||
securitySchemes: {
|
||||
bearerAuth: {
|
||||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
UploadId: { name: 'uploadId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
AssetId: { name: 'assetId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
PageId: { name: 'pageId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
PublicationId: { name: 'publicationId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
JobId: { name: 'jobId', in: 'path', required: true, schema: { type: 'string' } },
|
||||
OwnerSlug: { name: 'ownerSlug', in: 'path', required: true, schema: { type: 'string' } },
|
||||
UrlSlug: { name: 'urlSlug', in: 'path', required: true, schema: { type: 'string' } },
|
||||
...plazaOpenApi.parameters,
|
||||
},
|
||||
schemas: {
|
||||
SuccessEnvelope: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ok: { type: 'boolean' },
|
||||
request_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
DataEnvelope: {
|
||||
type: 'object',
|
||||
required: ['data', 'request_id'],
|
||||
properties: {
|
||||
data: { type: 'object', additionalProperties: true },
|
||||
request_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
ListEnvelope: {
|
||||
type: 'object',
|
||||
required: ['data', 'request_id'],
|
||||
properties: {
|
||||
data: { type: 'array', items: { type: 'object', additionalProperties: true } },
|
||||
page: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
next_cursor: { type: ['string', 'null'] },
|
||||
has_more: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
request_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
AuthStatus: {
|
||||
type: 'object',
|
||||
additionalProperties: true,
|
||||
},
|
||||
RegisterRequest: {
|
||||
type: 'object',
|
||||
required: ['username', 'password', 'displayName', 'email'],
|
||||
properties: {
|
||||
username: { type: 'string' },
|
||||
password: { type: 'string' },
|
||||
displayName: { type: 'string' },
|
||||
email: { type: 'string' },
|
||||
},
|
||||
},
|
||||
RegisterResponseEnvelope: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
ok: { type: 'boolean' },
|
||||
user: { type: 'object', additionalProperties: true },
|
||||
},
|
||||
},
|
||||
LoginRequest: {
|
||||
type: 'object',
|
||||
required: ['username', 'password'],
|
||||
properties: {
|
||||
username: { type: 'string' },
|
||||
password: { type: 'string' },
|
||||
},
|
||||
},
|
||||
CleanupRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
item_ids: { type: 'array', items: { type: 'string' } },
|
||||
},
|
||||
},
|
||||
CreateUploadRequest: {
|
||||
type: 'object',
|
||||
required: ['category_id', 'filename', 'size_bytes'],
|
||||
properties: {
|
||||
category_id: { type: 'string' },
|
||||
filename: { type: 'string' },
|
||||
size_bytes: { type: 'integer' },
|
||||
declared_mime_type: { type: 'string' },
|
||||
},
|
||||
},
|
||||
AnalyzeChatSaveRequest: {
|
||||
type: 'object',
|
||||
required: ['session_id', 'message_id'],
|
||||
properties: {
|
||||
session_id: { type: 'string' },
|
||||
message_id: { type: 'string' },
|
||||
selected_link_index: { type: 'integer' },
|
||||
},
|
||||
},
|
||||
SaveFromChatRequest: {
|
||||
type: 'object',
|
||||
required: ['session_id', 'message_id'],
|
||||
properties: {
|
||||
session_id: { type: 'string' },
|
||||
message_id: { type: 'string' },
|
||||
title: { type: 'string' },
|
||||
summary: { type: 'string' },
|
||||
template_id: { type: 'string' },
|
||||
category_code: { type: 'string' },
|
||||
page_type: { type: 'string' },
|
||||
selected_link_index: { type: 'integer' },
|
||||
acknowledged_finding_ids: { type: 'array', items: { type: 'string' } },
|
||||
},
|
||||
},
|
||||
PageFromAssetRequest: {
|
||||
type: 'object',
|
||||
required: ['asset_id'],
|
||||
properties: {
|
||||
asset_id: { type: 'string' },
|
||||
title: { type: 'string' },
|
||||
summary: { type: 'string' },
|
||||
template_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
CreatePageRequest: {
|
||||
type: 'object',
|
||||
required: ['title', 'content'],
|
||||
properties: {
|
||||
title: { type: 'string' },
|
||||
summary: { type: 'string' },
|
||||
content: { type: 'string' },
|
||||
content_format: { type: 'string', enum: ['markdown', 'html'] },
|
||||
template_id: { type: 'string' },
|
||||
page_type: { type: 'string' },
|
||||
category_code: { type: 'string' },
|
||||
},
|
||||
},
|
||||
UpdatePageRequest: {
|
||||
type: 'object',
|
||||
required: ['expected_version', 'title', 'content'],
|
||||
properties: {
|
||||
expected_version: { type: 'integer' },
|
||||
title: { type: 'string' },
|
||||
summary: { type: 'string' },
|
||||
content: { type: 'string' },
|
||||
template_id: { type: 'string' },
|
||||
page_type: { type: 'string' },
|
||||
change_note: { type: 'string' },
|
||||
},
|
||||
},
|
||||
PublishCheckRequest: {
|
||||
type: 'object',
|
||||
required: ['page_version_id', 'access_mode', 'url_slug'],
|
||||
properties: {
|
||||
page_version_id: { type: 'string' },
|
||||
access_mode: { type: 'string' },
|
||||
url_slug: { type: 'string' },
|
||||
password: { type: 'string' },
|
||||
expires_at: { type: 'integer' },
|
||||
},
|
||||
},
|
||||
RedactedCopyRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
page_version_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
PublishPageRequest: {
|
||||
type: 'object',
|
||||
required: ['page_version_id', 'access_mode', 'url_slug'],
|
||||
properties: {
|
||||
page_version_id: { type: 'string' },
|
||||
access_mode: { type: 'string' },
|
||||
url_slug: { type: 'string' },
|
||||
password: { type: 'string' },
|
||||
expires_at: { type: 'integer' },
|
||||
acknowledged_finding_ids: { type: 'array', items: { type: 'string' } },
|
||||
},
|
||||
},
|
||||
CreateAgentJobRequest: {
|
||||
type: 'object',
|
||||
required: ['job_type', 'instruction', 'allowed_asset_ids'],
|
||||
properties: {
|
||||
job_type: { type: 'string' },
|
||||
instruction: { type: 'string' },
|
||||
allowed_asset_ids: { type: 'array', items: { type: 'string' } },
|
||||
output_category_id: { type: 'string' },
|
||||
output_type: { type: 'string' },
|
||||
idempotency_key: { type: 'string' },
|
||||
locale: { type: 'string' },
|
||||
timezone: { type: 'string' },
|
||||
capabilities: { type: 'object', additionalProperties: { type: 'boolean' } },
|
||||
},
|
||||
},
|
||||
HeartbeatRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
stage: { type: 'string' },
|
||||
message: { type: 'string' },
|
||||
},
|
||||
},
|
||||
CompleteJobRequest: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
status: { type: 'string' },
|
||||
error_code: { type: 'string' },
|
||||
error_message: { type: 'string' },
|
||||
output_type: { type: 'string' },
|
||||
title: { type: 'string' },
|
||||
summary: { type: 'string' },
|
||||
content: { type: 'string' },
|
||||
content_format: { type: 'string' },
|
||||
page_type: { type: 'string' },
|
||||
template_id: { type: 'string' },
|
||||
source_asset_ids: { type: 'array', items: { type: 'string' } },
|
||||
},
|
||||
},
|
||||
ErrorResponse: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
error: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
code: { type: 'string' },
|
||||
message: { type: 'string' },
|
||||
details: { type: 'object', additionalProperties: true },
|
||||
},
|
||||
},
|
||||
request_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
...plazaOpenApi.schemas,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const rendered = `${JSON.stringify(jsonContent, null, 2)}\n`;
|
||||
if (process.argv.includes('--print')) {
|
||||
process.stdout.write(rendered);
|
||||
return;
|
||||
}
|
||||
await fs.writeFile(OUTPUT_PATH, rendered);
|
||||
process.stdout.write(`Generated ${OUTPUT_PATH}\n`);
|
||||
}
|
||||
|
||||
await main();
|
||||
Reference in New Issue
Block a user