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:
+638
@@ -0,0 +1,638 @@
|
||||
export type Role = 'user' | 'assistant';
|
||||
|
||||
export type MessageContent =
|
||||
| { type: 'text'; text: string }
|
||||
| { type: 'thinking'; thinking: string; signature?: string }
|
||||
| {
|
||||
type: 'systemNotification';
|
||||
notificationType: string;
|
||||
msg: string;
|
||||
data?: Record<string, unknown>;
|
||||
}
|
||||
| { type: 'toolRequest'; id: string; toolCall: { functionName: string; arguments: unknown } }
|
||||
| { type: 'toolResponse'; id: string; toolResult: { value: unknown } }
|
||||
| {
|
||||
type: 'actionRequired';
|
||||
data: {
|
||||
actionType: 'toolConfirmation';
|
||||
id: string;
|
||||
toolName: string;
|
||||
arguments: Record<string, unknown>;
|
||||
prompt?: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
export type Message = {
|
||||
id?: string | null;
|
||||
role: Role;
|
||||
created: number;
|
||||
content: MessageContent[];
|
||||
metadata: {
|
||||
userVisible: boolean;
|
||||
agentVisible: boolean;
|
||||
displayText?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type MindSpaceChatView = 'home' | 'category' | 'page';
|
||||
|
||||
export type MindSpaceChatContext = {
|
||||
spaceId: string;
|
||||
spaceName: string;
|
||||
ownerUsername?: string;
|
||||
view: MindSpaceChatView;
|
||||
route: string;
|
||||
category?: {
|
||||
code: MindSpaceCategory['code'];
|
||||
name: string;
|
||||
itemCount?: number;
|
||||
assets?: Array<{
|
||||
id: string;
|
||||
displayName: string;
|
||||
mimeType: string;
|
||||
}>;
|
||||
};
|
||||
page?: {
|
||||
id: string;
|
||||
title: string;
|
||||
summary?: string;
|
||||
status?: string;
|
||||
versionNo?: number;
|
||||
categoryCode?: MindSpaceCategory['code'];
|
||||
templateId?: string;
|
||||
contentFormat?: MindSpaceContentFormat;
|
||||
pageType?: string;
|
||||
contentExcerpt?: string;
|
||||
publicationUrl?: string | null;
|
||||
};
|
||||
focusedAsset?: {
|
||||
id: string;
|
||||
displayName: string;
|
||||
mimeType: string;
|
||||
};
|
||||
homeCategories?: Array<{
|
||||
code: MindSpaceCategory['code'];
|
||||
name: string;
|
||||
itemCount: number;
|
||||
}>;
|
||||
recentPages?: Array<{
|
||||
id: string;
|
||||
title: string;
|
||||
status: string;
|
||||
categoryCode: MindSpaceCategory['code'];
|
||||
}>;
|
||||
};
|
||||
|
||||
export type TokenState = {
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
totalTokens: number;
|
||||
accumulatedInputTokens?: number;
|
||||
accumulatedOutputTokens?: number;
|
||||
accumulatedTotalTokens?: number;
|
||||
accumulatedCost?: number | null;
|
||||
};
|
||||
|
||||
export type SessionEvent =
|
||||
| { type: 'Message'; message: Message; token_state: TokenState }
|
||||
| { type: 'Finish'; reason: string; token_state: TokenState }
|
||||
| { type: 'Error'; error: string }
|
||||
| { type: 'UpdateConversation'; conversation: Message[] }
|
||||
| { type: 'Ping' }
|
||||
| { type: 'ActiveRequests'; request_ids: string[] };
|
||||
|
||||
export type Session = {
|
||||
id: string;
|
||||
name: string;
|
||||
working_dir: string;
|
||||
message_count: number;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
user_set_name?: boolean;
|
||||
recipe?: { title?: string | null } | null;
|
||||
conversation?: Message[] | null;
|
||||
};
|
||||
|
||||
export type SessionListResponse = {
|
||||
sessions: Session[];
|
||||
};
|
||||
|
||||
export type HarnessBootstrapResponse = {
|
||||
summary: string;
|
||||
source: string;
|
||||
refreshed: boolean;
|
||||
};
|
||||
|
||||
export type ChatState = 'idle' | 'loading' | 'streaming' | 'waiting' | 'error';
|
||||
|
||||
export type ToolConfirmation = {
|
||||
id: string;
|
||||
toolName: string;
|
||||
arguments: Record<string, unknown>;
|
||||
prompt?: string | null;
|
||||
};
|
||||
|
||||
export type BillingConfig = {
|
||||
wechatEnabled: boolean;
|
||||
tiersCents: number[];
|
||||
minRechargeCents: number;
|
||||
balanceCents: number;
|
||||
};
|
||||
|
||||
export type RechargeOrder = {
|
||||
id: string;
|
||||
amountCents: number;
|
||||
status: 'pending' | 'paid' | 'failed' | 'expired' | 'refunded';
|
||||
payMode: 'native' | 'h5';
|
||||
expireAt: number;
|
||||
codeUrl?: string | null;
|
||||
h5Url?: string | null;
|
||||
};
|
||||
|
||||
export type InsufficientBalanceDetails = {
|
||||
code: 'INSUFFICIENT_BALANCE';
|
||||
balanceCents: number;
|
||||
minRechargeCents: number;
|
||||
suggestedTiers: number[];
|
||||
};
|
||||
|
||||
export type PortalUser = {
|
||||
id: string;
|
||||
username: string;
|
||||
slug?: string;
|
||||
email?: string | null;
|
||||
displayName: string;
|
||||
role: 'user' | 'admin';
|
||||
status: 'active' | 'suspended' | 'disabled';
|
||||
planType?: 'free' | 'growth' | 'pro' | 'enterprise';
|
||||
workspaceRoot: string;
|
||||
balanceCents: number;
|
||||
totalCreditCents?: number;
|
||||
tokensUsed: number;
|
||||
publishSlug?: string;
|
||||
publishUrl?: string;
|
||||
publishSkillName?: string;
|
||||
};
|
||||
|
||||
export type MindSpaceQuota = {
|
||||
quotaBytes: number;
|
||||
usedBytes: number;
|
||||
reservedBytes: number;
|
||||
availableBytes: number;
|
||||
maxFileBytes: number;
|
||||
publicPageLimit: number;
|
||||
publicPageUsed: number;
|
||||
aiDailyLimit: number;
|
||||
aiDailyUsed: number;
|
||||
monthlyViewLimit: number;
|
||||
monthlyViewUsed: number;
|
||||
};
|
||||
|
||||
export type MindSpaceCategory = {
|
||||
id: string;
|
||||
code: 'oa' | 'private' | 'public' | 'draft' | 'archive';
|
||||
name: string;
|
||||
visibilityPolicy: string;
|
||||
aiAccessPolicy: string;
|
||||
publishPolicy: string;
|
||||
isSystem: boolean;
|
||||
sortOrder: number;
|
||||
itemCount: number;
|
||||
};
|
||||
|
||||
export type MindSpace = {
|
||||
id: string;
|
||||
userId: string;
|
||||
name: string;
|
||||
status: 'active' | 'locked' | 'deleted';
|
||||
quota: MindSpaceQuota;
|
||||
categories: MindSpaceCategory[];
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
};
|
||||
|
||||
export type MindSpaceAsset = {
|
||||
id: string;
|
||||
categoryId: string;
|
||||
categoryCode: MindSpaceCategory['code'];
|
||||
assetType: string;
|
||||
mimeType: string;
|
||||
filename: string;
|
||||
displayName: string;
|
||||
sizeBytes: number;
|
||||
checksum: string;
|
||||
riskLevel: 'none' | 'low' | 'medium' | 'high' | 'critical';
|
||||
visibility: 'private' | 'internal' | 'public_candidate';
|
||||
status: 'uploaded' | 'processing' | 'ready' | 'quarantined' | 'archived';
|
||||
scanStatus?: 'pending' | 'passed' | 'warned' | 'blocked';
|
||||
sourceType: 'upload' | 'chat' | 'agent' | 'template' | 'generated' | 'workspace';
|
||||
hasThumbnail?: boolean;
|
||||
sourcePageId?: string | null;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
};
|
||||
|
||||
export type MindSpaceUpload = {
|
||||
id: string;
|
||||
filename: string;
|
||||
expectedSize: number;
|
||||
uploadUrl: string;
|
||||
expiresAt: number;
|
||||
reservedBytes: number;
|
||||
};
|
||||
|
||||
export type MindSpacePageVersion = {
|
||||
id: string;
|
||||
versionNo: number;
|
||||
changeNote: string | null;
|
||||
immutable: boolean;
|
||||
createdAt: number;
|
||||
};
|
||||
|
||||
export type MindSpaceSecurityFinding = {
|
||||
id: string;
|
||||
type: string;
|
||||
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
||||
occurrenceCount: number;
|
||||
sampleMasked: string;
|
||||
blocking: boolean;
|
||||
};
|
||||
|
||||
export type MindSpacePublishCheck = {
|
||||
pageVersionId: string;
|
||||
urlSlug: string;
|
||||
accessMode:
|
||||
| 'public'
|
||||
| 'password'
|
||||
| 'private_link'
|
||||
| 'time_limited'
|
||||
| 'login_required'
|
||||
| 'owner_only';
|
||||
expiresAt: number | null;
|
||||
slugAvailable: boolean;
|
||||
slugConflict?: { pageId: string; title: string } | null;
|
||||
suggestedUrlSlug?: string | null;
|
||||
status: 'passed' | 'warned' | 'blocked';
|
||||
riskLevel: 'none' | 'low' | 'medium' | 'high' | 'critical';
|
||||
findings: MindSpaceSecurityFinding[];
|
||||
allowed: boolean;
|
||||
};
|
||||
|
||||
export type MindSpaceRedactionChange = {
|
||||
field: 'title' | 'summary' | 'content';
|
||||
fieldLabel: string;
|
||||
type: string;
|
||||
label: string;
|
||||
count: number;
|
||||
};
|
||||
|
||||
export type MindSpaceRedactedCopyResult = {
|
||||
page: MindSpacePage;
|
||||
originalScan: MindSpacePrivacyScan;
|
||||
redactedScan: MindSpacePrivacyScan;
|
||||
redactionsApplied: number;
|
||||
changes: MindSpaceRedactionChange[];
|
||||
};
|
||||
|
||||
export type MindSpaceCleanupItem = {
|
||||
id: string;
|
||||
kind: 'stale_upload' | 'orphan_tmp' | 'workspace_temp';
|
||||
label: string;
|
||||
path: string;
|
||||
sizeBytes: number;
|
||||
createdAt: number | null;
|
||||
detail: string;
|
||||
};
|
||||
|
||||
export type MindSpacePublication = {
|
||||
id: string;
|
||||
pageId: string;
|
||||
pageVersionId: string;
|
||||
urlSlug: string;
|
||||
publicUrl: string;
|
||||
accessMode: MindSpacePublishCheck['accessMode'];
|
||||
expiresAt: number | null;
|
||||
status: 'online' | 'offline' | 'expired' | 'blocked';
|
||||
viewCount: number;
|
||||
publishedAt: number;
|
||||
offlineAt: number | null;
|
||||
};
|
||||
|
||||
export type MindSpacePublicationStats = {
|
||||
publicationId: string;
|
||||
status: string;
|
||||
totalViews: number;
|
||||
publishedAt: number;
|
||||
daily: Array<{ day: string; views: number }>;
|
||||
devices: Array<{ deviceType: string; views: number }>;
|
||||
sources: Array<{ source: string; views: number }>;
|
||||
};
|
||||
|
||||
export type PlazaCategory = {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
icon: string;
|
||||
post_count: number;
|
||||
};
|
||||
|
||||
export type PlazaPostBrief = {
|
||||
id: string;
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type MindSpaceAgentJobAsset = {
|
||||
assetId: string;
|
||||
assetVersionId: string;
|
||||
permission: 'read' | 'write' | 'create_derivative';
|
||||
displayName: string;
|
||||
mimeType: string;
|
||||
status: string;
|
||||
scanStatus: string;
|
||||
};
|
||||
|
||||
export type MindSpaceAgentJob = {
|
||||
id: string;
|
||||
sessionId: string | null;
|
||||
jobType: string;
|
||||
instruction: string;
|
||||
status: 'queued' | 'running' | 'completed' | 'failed' | 'cancelled' | 'timed_out';
|
||||
outputType: 'page_draft' | 'html_page' | 'markdown';
|
||||
outputCategoryId: string;
|
||||
outputCategoryCode: string | null;
|
||||
progress: { stage: string; message?: string };
|
||||
permissionScope: Record<string, unknown>;
|
||||
userContext: { locale?: string; timezone?: string };
|
||||
resultPageId: string | null;
|
||||
resultAssetId: string | null;
|
||||
errorCode: string | null;
|
||||
errorMessage: string | null;
|
||||
retryable: boolean;
|
||||
queuedAt: number;
|
||||
startedAt: number | null;
|
||||
completedAt: number | null;
|
||||
expiresAt: number | null;
|
||||
assets: MindSpaceAgentJobAsset[];
|
||||
};
|
||||
|
||||
export type MindSpaceContentFormat = 'markdown' | 'html';
|
||||
|
||||
export type MindSpaceSaveCategory = 'draft' | 'oa' | 'private' | 'public';
|
||||
|
||||
export type MindSpacePrivacyFinding = {
|
||||
id: string;
|
||||
type: string;
|
||||
label?: string;
|
||||
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
||||
occurrenceCount: number;
|
||||
sampleMasked: string;
|
||||
blocking: boolean;
|
||||
};
|
||||
|
||||
export type MindSpacePrivacyScan = {
|
||||
status: 'passed' | 'warned' | 'blocked';
|
||||
riskLevel: 'none' | 'low' | 'medium' | 'high' | 'critical';
|
||||
findings: MindSpacePrivacyFinding[];
|
||||
allowed: boolean;
|
||||
};
|
||||
|
||||
export type ChatSaveContentMode = 'markdown' | 'static_html';
|
||||
|
||||
export type ChatSaveAnalysis = {
|
||||
contentMode: ChatSaveContentMode;
|
||||
links: Array<{
|
||||
publicUrl: string;
|
||||
owner: string;
|
||||
relativePath: string;
|
||||
filename: string;
|
||||
}>;
|
||||
selectedLinkIndex: number;
|
||||
suggestedTitle: string;
|
||||
suggestedSummary: string;
|
||||
previewUrl: string | null;
|
||||
previewFrameUrl: string | null;
|
||||
localPreviewUrl: string | null;
|
||||
localThumbnailUrl: string | null;
|
||||
thumbnailUrl: string | null;
|
||||
thumbnailReady: boolean;
|
||||
relativePath: string | null;
|
||||
filename: string | null;
|
||||
hasHtmlContent: boolean;
|
||||
privacyScan: MindSpacePrivacyScan;
|
||||
};
|
||||
|
||||
export type ChatSaveResult =
|
||||
| { kind: 'page'; categoryCode: 'draft'; page: MindSpacePage }
|
||||
| { kind: 'asset'; categoryCode: Exclude<MindSpaceSaveCategory, 'draft'>; asset: MindSpaceAsset };
|
||||
|
||||
export type MindSpacePage = {
|
||||
id: string;
|
||||
categoryId: string;
|
||||
categoryCode: MindSpaceCategory['code'];
|
||||
sourceSessionId: string | null;
|
||||
sourceMessageId: string | null;
|
||||
sourceAssetId: string | null;
|
||||
title: string;
|
||||
summary: string;
|
||||
pageType: string;
|
||||
contentFormat?: MindSpaceContentFormat;
|
||||
hasThumbnail?: boolean;
|
||||
templateId: string;
|
||||
status: 'draft' | 'reviewing' | 'risk_found' | 'ready' | 'published' | 'protected' | 'expired' | 'offline';
|
||||
visibility: 'private' | 'internal' | 'public';
|
||||
publicationAccessMode?: 'public' | 'password' | 'private_link' | 'time_limited' | 'login_required' | 'owner_only' | null;
|
||||
currentVersionId: string;
|
||||
versionNo: number;
|
||||
content?: string;
|
||||
versions?: MindSpacePageVersion[];
|
||||
publication?: MindSpacePublication | null;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
};
|
||||
|
||||
export type MindSpacePageDeletePreview = {
|
||||
page: {
|
||||
id: string;
|
||||
title: string;
|
||||
status: MindSpacePage['status'];
|
||||
versionCount: number;
|
||||
};
|
||||
onlinePublication: {
|
||||
id: string;
|
||||
publicUrl: string;
|
||||
accessMode: MindSpacePublication['accessMode'];
|
||||
viewCount: number;
|
||||
} | null;
|
||||
offlinePublicationCount: number;
|
||||
linkedAssets: Array<{
|
||||
id: string;
|
||||
displayName: string;
|
||||
sizeBytes: number;
|
||||
kind: 'content' | 'bundle';
|
||||
}>;
|
||||
linkedAssetBytes: number;
|
||||
linkedAgentJobCount: number;
|
||||
preservesSourceAsset: boolean;
|
||||
summaryLines: string[];
|
||||
};
|
||||
|
||||
export type MindSpacePageDeleteResult = {
|
||||
deleted: boolean;
|
||||
pageId: string;
|
||||
title: string;
|
||||
offlinedPublicationCount: number;
|
||||
deletedAssetCount: number;
|
||||
freedBytes: number;
|
||||
clearedAgentJobCount: number;
|
||||
};
|
||||
|
||||
export type CapabilityDefinition = {
|
||||
key: string;
|
||||
label: string;
|
||||
description: string;
|
||||
risk: 'low' | 'medium' | 'high';
|
||||
category: string;
|
||||
};
|
||||
|
||||
export type CapabilityMap = Record<string, boolean>;
|
||||
|
||||
export type PolicyValue = string | boolean;
|
||||
|
||||
export type PolicyMap = Record<string, PolicyValue>;
|
||||
|
||||
export type SkillMap = Record<string, boolean>;
|
||||
|
||||
export type SkillDefinition = {
|
||||
name: string;
|
||||
dirName: string;
|
||||
label: string;
|
||||
description: string;
|
||||
category: string;
|
||||
requiresPublish?: boolean;
|
||||
};
|
||||
|
||||
export type PolicyDefinition = {
|
||||
key: string;
|
||||
label: string;
|
||||
description: string;
|
||||
type: 'select' | 'boolean';
|
||||
options?: Array<{ value: string; label: string }>;
|
||||
defaultValue: PolicyValue;
|
||||
category: string;
|
||||
risk: 'low' | 'medium' | 'high';
|
||||
};
|
||||
|
||||
export type AuthStatus = {
|
||||
authenticated: boolean;
|
||||
mode?: 'user' | 'legacy' | 'none';
|
||||
user?: PortalUser | null;
|
||||
capabilities?: CapabilityMap;
|
||||
grantedSkills?: string[];
|
||||
unrestricted?: boolean;
|
||||
};
|
||||
|
||||
export type PathGrant = {
|
||||
path: string;
|
||||
mode: 'read' | 'readwrite';
|
||||
};
|
||||
|
||||
export type AdminUserRow = PortalUser & {
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
};
|
||||
|
||||
export type LlmProviderDefinition = {
|
||||
id: string;
|
||||
label: string;
|
||||
kind?: 'builtin' | 'custom';
|
||||
apiKeyEnv: string | null;
|
||||
defaultModel: string;
|
||||
models: string[];
|
||||
};
|
||||
|
||||
export type LlmProviderKeyRow = {
|
||||
id: string;
|
||||
providerId: string;
|
||||
providerKind: 'builtin' | 'custom';
|
||||
providerLabel: string;
|
||||
name: string;
|
||||
defaultModel: string;
|
||||
models: string[];
|
||||
apiUrl: string | null;
|
||||
basePath: string | null;
|
||||
engine: string;
|
||||
relayProvider: string | null;
|
||||
goosedProviderId: string | null;
|
||||
status: 'active' | 'disabled';
|
||||
isSelected: boolean;
|
||||
apiKeyMasked: string;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
};
|
||||
|
||||
export type LlmGlobalSettings = {
|
||||
keyId: string | null;
|
||||
keyName: string | null;
|
||||
providerLabel: string | null;
|
||||
globalModel: string | null;
|
||||
availableModels: string[];
|
||||
};
|
||||
|
||||
export type LlmConnectionTestResult = {
|
||||
ok: boolean;
|
||||
latencyMs?: number;
|
||||
reply?: string;
|
||||
model?: string;
|
||||
message?: string;
|
||||
};
|
||||
|
||||
export type UsageRecord = {
|
||||
id: number;
|
||||
userId: string;
|
||||
username: string;
|
||||
agentSessionId: string;
|
||||
requestId: string | null;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
costCents: number;
|
||||
balanceAfterCents: number;
|
||||
createdAt: number;
|
||||
};
|
||||
|
||||
export type LedgerEntry = {
|
||||
id: number;
|
||||
userId: string;
|
||||
username: string;
|
||||
type: 'recharge' | 'deduct' | 'refund' | 'adjust';
|
||||
amountCents: number;
|
||||
tokens: number;
|
||||
sessionId: string | null;
|
||||
note: string | null;
|
||||
createdAt: number;
|
||||
};
|
||||
|
||||
export type AdminDashboardSummary = {
|
||||
users: {
|
||||
total: number;
|
||||
active: number;
|
||||
lowBalance: number;
|
||||
totalBalanceCents: number;
|
||||
};
|
||||
usage24h: {
|
||||
count: number;
|
||||
costCents: number;
|
||||
};
|
||||
lowBalanceUsers: Array<{
|
||||
id: string;
|
||||
username: string;
|
||||
displayName: string;
|
||||
balanceCents: number;
|
||||
}>;
|
||||
recentUsage: UsageRecord[];
|
||||
recentLedger: LedgerEntry[];
|
||||
llm: {
|
||||
keyCount: number;
|
||||
selectedKeyName: string | null;
|
||||
globalModel: string | null;
|
||||
} | null;
|
||||
};
|
||||
Reference in New Issue
Block a user