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:
John
2026-06-15 15:04:43 -07:00
commit 2e14873f2d
272 changed files with 64133 additions and 0 deletions
+638
View File
@@ -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;
};