deepspace 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/chunk-T7V4GUIN.js +1638 -0
  3. package/dist/chunk-T7V4GUIN.js.map +1 -0
  4. package/dist/cli.js +731 -324
  5. package/dist/cli.js.map +1 -1
  6. package/dist/documentation-client-core.d.ts +18 -0
  7. package/dist/documentation-client-core.js +395 -0
  8. package/dist/documentation-client-core.js.map +1 -0
  9. package/dist/documentation-default-renderer.cjs +124 -0
  10. package/dist/documentation-react.d.ts +2 -0
  11. package/dist/documentation-react.js +35 -0
  12. package/dist/documentation-react.js.map +1 -0
  13. package/dist/documentation-runtime.js +71 -0
  14. package/dist/documentation-server-core.d.ts +11 -0
  15. package/dist/documentation-server-core.js +48 -0
  16. package/dist/documentation-server-core.js.map +1 -0
  17. package/dist/documentation.d.ts +366 -0
  18. package/dist/documentation.js +3953 -0
  19. package/dist/documentation.js.map +1 -0
  20. package/dist/feature-installer.js +145 -0
  21. package/dist/feature-installer.js.map +1 -1
  22. package/dist/index.d.ts +177 -1
  23. package/dist/index.js +133 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/public-BGRX_Cjd.d.ts +234 -0
  26. package/dist/schema.d.ts +186 -0
  27. package/dist/schema.js +610 -0
  28. package/dist/schema.js.map +1 -0
  29. package/dist/server.d.ts +83 -4
  30. package/dist/server.js +296 -1
  31. package/dist/server.js.map +1 -1
  32. package/dist/testing.d.ts +5 -8
  33. package/dist/testing.js +48 -14
  34. package/dist/testing.js.map +1 -1
  35. package/dist/worker.d.ts +249 -5
  36. package/dist/worker.js +1438 -19
  37. package/dist/worker.js.map +1 -1
  38. package/features/admin-page/src/admin-schema.ts +1 -1
  39. package/features/ai-chat/feature.json +2 -2
  40. package/features/ai-chat/src/ChatPanel.tsx +6 -11
  41. package/features/ai-chat/src/ai-chat-schema.ts +1 -2
  42. package/features/canvas/src/canvas-schema.ts +1 -1
  43. package/features/documentation/content/index.mdx +14 -0
  44. package/features/documentation/content/quickstart.mdx +12 -0
  45. package/features/documentation/documentation.json +18 -0
  46. package/features/documentation/feature.json +68 -0
  47. package/features/{docs → documents}/feature.json +27 -27
  48. package/features/{docs/src/DocsEditorPage.tsx → documents/src/DocumentsEditorPage.tsx} +74 -74
  49. package/features/{docs/src/DocsListPage.tsx → documents/src/DocumentsListPage.tsx} +102 -102
  50. package/features/{docs/src/DocsOutlinePanel.tsx → documents/src/DocumentsOutlinePanel.tsx} +9 -9
  51. package/features/{docs/src/DocsPresence.tsx → documents/src/DocumentsPresence.tsx} +18 -18
  52. package/features/{docs → documents}/src/InviteDialog.tsx +21 -21
  53. package/features/{docs → documents}/src/LibrarySidebar.tsx +25 -25
  54. package/features/documents/src/__tests__/documents-presence-access.test.ts +71 -0
  55. package/features/{docs/src/docs-library-types.ts → documents/src/documents-library-types.ts} +3 -3
  56. package/features/{docs/src/docs-schema.ts → documents/src/documents-schema.ts} +6 -6
  57. package/features/{docs/src/docs-ui.css → documents/src/documents-ui.css} +89 -89
  58. package/features/{docs → documents}/src/editor/DocEditorSurface.tsx +11 -11
  59. package/features/{docs/src/editor/DocsTiptapToolbar.tsx → documents/src/editor/DocumentsTiptapToolbar.tsx} +21 -21
  60. package/features/{docs → documents}/src/editor/useDocEditor.ts +4 -4
  61. package/features/{docs/src/use-docs-presence-access.ts → documents/src/use-documents-presence-access.ts} +51 -51
  62. package/features/file-attachments/src/attachments-schema.ts +1 -1
  63. package/features/items/src/items-schema.ts +1 -1
  64. package/features/leaderboard/src/leaderboard-schema.ts +1 -1
  65. package/features/messaging/src/ChatMultiPage.tsx +1 -1
  66. package/features/messaging/src/ChatPage.tsx +1 -1
  67. package/features/messaging/src/messaging-schema.ts +2 -2
  68. package/features/tasks/src/tasks-schema.ts +1 -1
  69. package/features/testing/src/test-schema.ts +2 -2
  70. package/package.json +26 -1
  71. package/features/docs/src/__tests__/docs-presence-access.test.ts +0 -71
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/schemas/registry.ts","../src/server/schemas/ai-chat.ts","../src/server/schemas/messaging.ts","../src/server/schemas/conversation.ts","../src/server/schemas/directory.ts","../src/server/schemas/workspace.ts"],"sourcesContent":["/**\n * Collection Schema Definitions & Validation\n *\n * All collections use typed SQL columns. No document-mode / fields-based storage.\n */\n\nimport type {\n CollectionSchema,\n ColumnDefinition,\n ColumnInterpretation,\n PermissionLevel,\n RolePermissions,\n} from '../../shared/types'\n\nexport type {\n CollectionSchema,\n ColumnDefinition,\n ColumnInterpretation,\n PermissionLevel,\n RolePermissions,\n} from '../../shared/types'\n\n// ============================================================================\n// Column Definitions\n// ============================================================================\n\nexport interface ResolvedColumn {\n id: string\n name: string\n storage: 'number' | 'text'\n interpretation: ColumnInterpretation\n expression?: string\n readonly: boolean\n userBound?: boolean\n immutable?: boolean\n required?: boolean\n default?: unknown\n timestampTrigger?: { field: string; value?: unknown }\n}\n\n// ============================================================================\n// Column Helpers\n// ============================================================================\n\nexport function collectionTableName(name: string): string {\n return `c_${name.replace(/[^a-zA-Z0-9_]/g, '_')}`\n}\n\nexport function columnId(name: string): string {\n return `col_${name.toLowerCase().replace(/[^a-z0-9]/g, '_')}`\n}\n\nexport function resolveColumn(col: ColumnDefinition): ResolvedColumn {\n const interp: ColumnInterpretation =\n typeof col.interpretation === 'string'\n ? ({ kind: col.interpretation } as ColumnInterpretation)\n : col.interpretation\n return {\n id: col.id ?? columnId(col.name),\n name: col.name,\n storage: col.storage,\n interpretation: interp,\n expression: col.expression,\n readonly: !!col.expression,\n userBound: col.userBound,\n immutable: col.immutable,\n required: col.required,\n default: col.default,\n timestampTrigger: col.timestampTrigger,\n }\n}\n\nexport function rowToData(\n row: Record<string, unknown>,\n columns: ResolvedColumn[],\n): Record<string, unknown> {\n const data: Record<string, unknown> = {}\n for (const col of columns) {\n if (row[col.id] !== undefined && row[col.id] !== null) {\n let val = row[col.id]\n if (col.interpretation.kind === 'json' && typeof val === 'string') {\n try {\n val = JSON.parse(val as string)\n } catch {\n /* keep as string */\n }\n }\n data[col.name] = val\n }\n }\n return data\n}\n\nexport function dataToColumnValues(\n data: Record<string, unknown>,\n columns: ResolvedColumn[],\n): Record<string, unknown> {\n const values: Record<string, unknown> = {}\n for (const col of columns) {\n if (col.expression || col.readonly) continue\n const val = data[col.id] ?? data[col.name]\n if (val !== undefined) {\n values[col.id] = coerceValue(val, col.storage, col.interpretation)\n }\n }\n return values\n}\n\nexport function coerceValue(\n value: unknown,\n storage: 'number' | 'text',\n interpretation: ColumnInterpretation,\n): unknown {\n if (value === null || value === undefined || value === '') return null\n\n if (storage === 'text') {\n if (interpretation.kind === 'json') {\n if (typeof value === 'string') return value\n try {\n return JSON.stringify(value)\n } catch {\n return null\n }\n }\n return typeof value === 'string' ? value : String(value)\n }\n\n if (typeof value === 'number') return isFinite(value) ? value : null\n if (typeof value === 'boolean') return value ? 1 : 0\n if (typeof value !== 'string') return String(value)\n\n const s = value.trim()\n\n if (interpretation.kind === 'boolean') {\n const lower = s.toLowerCase()\n if (lower === 'true' || lower === '1' || lower === 'yes') return 1\n if (lower === 'false' || lower === '0' || lower === 'no') return 0\n return s\n }\n\n if (interpretation.kind === 'percent') {\n const m = s.match(/^(-?\\d+(?:\\.\\d+)?)\\s*%$/)\n if (m) return parseFloat(m[1]) / 100\n }\n\n if (interpretation.kind === 'currency') {\n const cleaned = s.replace(/[^0-9.-]/g, '')\n const n = parseFloat(cleaned)\n if (!isNaN(n)) return n\n return s\n }\n\n if (interpretation.kind === 'date' || interpretation.kind === 'datetime') {\n const d = new Date(s)\n if (!isNaN(d.getTime())) return Math.floor(d.getTime() / 1000)\n return s\n }\n\n const cleaned = s.replace(/[$€£¥,\\s]/g, '')\n const n = parseFloat(cleaned)\n if (!isNaN(n) && isFinite(n)) return n\n\n return s\n}\n\nexport function buildTableSelect(collectionName: string, columns: ResolvedColumn[]): string {\n const tbl = collectionTableName(collectionName)\n const parts: string[] = ['_row_id', '_created_by', '_created_at', '_updated_at']\n for (const col of columns) {\n if (col.expression) {\n parts.push(`(${col.expression}) AS \"${col.id}\"`)\n } else {\n parts.push(`\"${col.id}\"`)\n }\n }\n return `SELECT ${parts.join(', ')} FROM \"${tbl}\"`\n}\n\nexport interface User {\n id: string\n email: string\n name: string\n imageUrl?: string\n role: string\n createdAt: string\n lastSeenAt: string\n}\n\nexport interface StoredRecord {\n collection: string\n recordId: string\n data: Record<string, unknown>\n createdBy: string\n createdAt: string\n updatedAt: string\n}\n\n// ============================================================================\n// Permission Checking\n// ============================================================================\n\nexport interface PermissionContext {\n isTeamMember: (teamId: string, userId: string) => boolean\n}\n\nexport const noopPermissionContext: PermissionContext = {\n isTeamMember: () => false,\n}\n\nexport function getRolePermissions(schema: CollectionSchema, role: string): RolePermissions {\n if (schema.permissions[role]) return schema.permissions[role]\n if (schema.permissions['*']) return schema.permissions['*']\n return { read: false, create: false, update: false, delete: false }\n}\n\nexport function isOwner(\n schema: CollectionSchema,\n record: { data: Record<string, unknown>; createdBy: string },\n userId: string,\n): boolean {\n if (schema.ownerField) return record.data[schema.ownerField] === userId\n return record.createdBy === userId\n}\n\nfunction isCollaborator(\n schema: CollectionSchema,\n record: { data: Record<string, unknown> },\n userId: string,\n): boolean {\n if (!schema.collaboratorsField) return false\n const collab = record.data[schema.collaboratorsField]\n if (typeof collab === 'string') {\n try {\n return (JSON.parse(collab) as string[]).includes(userId)\n } catch {\n return false\n }\n }\n if (Array.isArray(collab)) return collab.includes(userId)\n return false\n}\n\nfunction passesVisibilityCheck(\n schema: CollectionSchema,\n record: { data: Record<string, unknown> },\n): boolean {\n if (!schema.visibilityField) return false\n if (typeof schema.visibilityField === 'string') {\n return record.data[schema.visibilityField] === 'public'\n }\n return record.data[schema.visibilityField.field] === schema.visibilityField.value\n}\n\nfunction checkPermissionLevel(\n level: PermissionLevel,\n schema: CollectionSchema,\n record: { data: Record<string, unknown>; createdBy: string; recordId?: string },\n userId: string,\n ctx: PermissionContext = noopPermissionContext,\n): boolean {\n if (level === true) return true\n if (level === false) return false\n if (level === 'own') return isOwner(schema, record, userId)\n if (level === 'unclaimed-or-own') {\n if (schema.ownerField) {\n const ownerVal = record.data[schema.ownerField]\n if (!ownerVal || ownerVal === '') return true\n }\n return isOwner(schema, record, userId)\n }\n if (level === 'collaborator') {\n return isOwner(schema, record, userId) || isCollaborator(schema, record, userId)\n }\n if (level === 'team' || level === 'access') {\n if (isOwner(schema, record, userId)) return true\n if (isCollaborator(schema, record, userId)) return true\n if (schema.teamField) {\n const teamId = record.data[schema.teamField]\n if (typeof teamId === 'string' && ctx.isTeamMember(teamId, userId)) return true\n }\n return false\n }\n if (level === 'published') {\n return isOwner(schema, record, userId) || passesVisibilityCheck(schema, record)\n }\n if (level === 'shared') {\n return (\n isOwner(schema, record, userId) ||\n isCollaborator(schema, record, userId) ||\n passesVisibilityCheck(schema, record)\n )\n }\n return false\n}\n\nexport function canRead(\n schema: CollectionSchema,\n role: string,\n record: { data: Record<string, unknown>; createdBy: string; recordId?: string },\n userId: string,\n ctx: PermissionContext = noopPermissionContext,\n): boolean {\n return checkPermissionLevel(getRolePermissions(schema, role).read, schema, record, userId, ctx)\n}\n\nexport function canCreate(schema: CollectionSchema, role: string): boolean {\n return getRolePermissions(schema, role).create === true\n}\n\nexport function canUpdate(\n schema: CollectionSchema,\n role: string,\n record: { data: Record<string, unknown>; createdBy: string; recordId?: string },\n userId: string,\n ctx: PermissionContext = noopPermissionContext,\n): boolean {\n return checkPermissionLevel(getRolePermissions(schema, role).update, schema, record, userId, ctx)\n}\n\nexport function canDelete(\n schema: CollectionSchema,\n role: string,\n record: { data: Record<string, unknown>; createdBy: string; recordId?: string },\n userId: string,\n ctx: PermissionContext = noopPermissionContext,\n): boolean {\n return checkPermissionLevel(getRolePermissions(schema, role).delete, schema, record, userId, ctx)\n}\n\n/** Check if a field update violates writableFields restrictions. */\nexport function checkFieldPermissions(\n schema: CollectionSchema,\n role: string,\n newData: Record<string, unknown>,\n existingData?: Record<string, unknown>,\n): string | null {\n const perms = getRolePermissions(schema, role)\n if (!perms.writableFields) return null // no restrictions\n\n const allowedFields = new Set(perms.writableFields)\n for (const key of Object.keys(newData)) {\n if (existingData && newData[key] === existingData[key]) continue\n if (!allowedFields.has(key)) {\n return `Role '${role}' cannot modify field '${key}'`\n }\n }\n return null\n}\n\n// ============================================================================\n// System-Managed Columns (users collection)\n// ============================================================================\n\n/** Names of columns managed by the system (registerUser), not client mutations. */\nexport const SYSTEM_MANAGED_COLUMNS = new Set([\n 'email',\n 'name',\n 'imageUrl',\n 'role',\n 'createdAt',\n 'lastSeenAt',\n])\n\n/** Standard user columns. Apps spread these into their users schema. */\nexport const USERS_COLUMNS: ColumnDefinition[] = [\n { name: 'email', storage: 'text', interpretation: 'plain' },\n { name: 'name', storage: 'text', interpretation: 'plain' },\n { name: 'imageUrl', storage: 'text', interpretation: 'plain' },\n { name: 'role', storage: 'text', interpretation: 'plain' },\n { name: 'createdAt', storage: 'text', interpretation: { kind: 'datetime' } },\n { name: 'lastSeenAt', storage: 'text', interpretation: { kind: 'datetime' } },\n]\n\nexport const BASE_USERS_SCHEMA: CollectionSchema = {\n name: 'users',\n columns: [...USERS_COLUMNS],\n permissions: {\n '*': { read: 'own', create: false, update: false, delete: false },\n admin: { read: true, create: false, update: true, delete: true },\n },\n}\n\n// ============================================================================\n// Schema Registry\n// ============================================================================\n\n/**\n * Lint a CollectionSchema for declarations that look like they should\n * enforce something but don't, due to interactions between top-level\n * fields (visibilityField, ownerField) and per-role permission levels.\n *\n * The SDK has historically silently accepted schemas that imply more\n * enforcement than they actually deliver — e.g., `visibilityField` set\n * but every role's `read: true` means \"anyone can read everything\"\n * regardless of `visibility`. Warn loudly at registration so app\n * authors notice before shipping a privacy bug.\n *\n * Returns an array of warning messages. Empty = clean.\n */\nexport function lintSchema(schema: CollectionSchema): string[] {\n const warnings: string[] = []\n const VISIBILITY_AWARE: ReadonlyArray<PermissionLevel> = ['published', 'shared']\n\n // Roles that grant unconditional read despite visibilityField being declared.\n if (schema.visibilityField) {\n const offendingRoles = Object.entries(schema.permissions)\n .filter(([, perms]) => perms.read === true)\n .map(([role]) => role)\n if (offendingRoles.length > 0) {\n const usesAware = Object.values(schema.permissions).some(\n (p) => typeof p.read === 'string' && VISIBILITY_AWARE.includes(p.read as PermissionLevel),\n )\n if (!usesAware) {\n warnings.push(\n `[${schema.name}] visibilityField is declared but no role uses read: 'published' or 'shared'. ` +\n `Roles with read: true (${offendingRoles.join(', ')}) will see every row regardless of visibility. ` +\n `Change those to read: 'published' (owner OR public) or 'shared' (owner OR collaborator OR public) ` +\n `to actually enforce the filter, or remove visibilityField if you don't intend to gate reads by it.`,\n )\n }\n }\n }\n\n // An ordinary client role that can create rows must not be able to claim\n // someone else's ownership. Server-written collections legitimately carry\n // a recipient/subject id instead: their non-privileged roles all have\n // create:false, while owner/admin writes are already fully trusted.\n if (schema.ownerField) {\n const col = schema.columns.find((c) => c.name === schema.ownerField)\n const spoofableRoles = Object.entries(schema.permissions)\n .filter(\n ([role, permissions]) =>\n role !== 'owner' && role !== 'admin' && permissions.create === true,\n )\n .map(([role]) => role)\n if (col && !col.userBound && spoofableRoles.length > 0) {\n warnings.push(\n `[${schema.name}] ownerField is '${schema.ownerField}' but that column is not marked userBound: true. ` +\n `Client role(s) ${spoofableRoles.join(', ')} can create a row with someone else's id in this field, bypassing 'own' permission checks. ` +\n `Add userBound: true (and ideally immutable: true) to the column.`,\n )\n }\n }\n\n // userBound columns that aren't text storage — userBound sets the\n // field to the caller's userId (a string), so non-text storage is a\n // schema mistake that will surface as a coercion error at write time.\n for (const col of schema.columns) {\n if (col.userBound && col.storage !== 'text') {\n warnings.push(\n `[${schema.name}] column '${col.name}' is userBound but storage is '${col.storage}'. ` +\n `userBound stamps the user id (a string); use storage: 'text'.`,\n )\n }\n }\n\n return warnings\n}\n\nexport class SchemaRegistry {\n private trusted: Map<string, CollectionSchema> = new Map()\n\n constructor(schemas: CollectionSchema[] = []) {\n for (const schema of schemas) {\n this.registerTrusted(schema)\n }\n }\n\n registerTrusted(schema: CollectionSchema): void {\n for (const w of lintSchema(schema)) {\n console.warn(`[schema-lint] ${w}`)\n }\n this.trusted.set(schema.name, schema)\n }\n\n get(name: string): CollectionSchema | undefined {\n return this.trusted.get(name)\n }\n\n has(name: string): boolean {\n return this.trusted.has(name)\n }\n\n all(): CollectionSchema[] {\n return Array.from(this.trusted.values())\n }\n\n names(): string[] {\n return Array.from(this.trusted.keys())\n }\n}\n\n// ============================================================================\n// Permission Analysis\n// ============================================================================\n\nexport type PermissionSource = 'explicit' | 'wildcard' | 'default-deny'\n\nexport interface ResolvedPermission {\n level: PermissionLevel | boolean\n source: PermissionSource\n}\n\nexport interface CollectionPermissionSummary {\n collection: string\n ownerField?: string\n collaboratorsField?: string\n teamField?: string\n columns: ColumnDefinition[]\n permissions: Record<\n string,\n {\n read: ResolvedPermission\n create: ResolvedPermission\n update: ResolvedPermission\n delete: ResolvedPermission\n writableFields?: string[]\n }\n >\n}\n\nexport interface PermissionAnalysis {\n roles: string[]\n collections: CollectionPermissionSummary[]\n}\n\nexport function analyzePermissions(schemas: CollectionSchema[]): PermissionAnalysis {\n const roleSet = new Set<string>()\n for (const schema of schemas) {\n for (const role of Object.keys(schema.permissions)) roleSet.add(role)\n }\n roleSet.delete('*')\n const roles = Array.from(roleSet)\n\n const collections: CollectionPermissionSummary[] = schemas.map((schema) => {\n const permissions: CollectionPermissionSummary['permissions'] = {}\n for (const role of roles) {\n let source: PermissionSource\n let perms: RolePermissions\n if (schema.permissions[role]) {\n source = 'explicit'\n perms = schema.permissions[role]\n } else if (schema.permissions['*']) {\n source = 'wildcard'\n perms = schema.permissions['*']\n } else {\n source = 'default-deny'\n perms = { read: false, create: false, update: false, delete: false }\n }\n permissions[role] = {\n read: { level: perms.read, source },\n create: { level: perms.create, source },\n update: { level: perms.update, source },\n delete: { level: perms.delete, source },\n writableFields: perms.writableFields,\n }\n }\n return {\n collection: schema.name,\n ownerField: schema.ownerField,\n collaboratorsField: schema.collaboratorsField,\n teamField: schema.teamField,\n columns: schema.columns,\n permissions,\n }\n })\n\n return { roles, collections }\n}\n","/**\n * AI Chat Schemas\n *\n * Pre-built collection schemas for DO-backed AI chat history.\n * The worker is the only writer; the client reads via `useQuery`.\n */\n\nimport type { CollectionSchema } from './registry'\n\n// member.create is false on both collections: writes flow exclusively through\n// the worker's /api/ai/* routes, which use X-App-Action to bypass RBAC.\n// Allowing direct WS creates would let a user PUT fake `role: 'assistant'`\n// rows into their own chats and have the next turn's loadMessages feed them\n// to the LLM as if they were real assistant outputs.\nexport const AI_CHATS_SCHEMA: CollectionSchema = {\n name: 'ai-chats',\n columns: [\n { name: 'userId', storage: 'text', interpretation: 'plain', userBound: true, immutable: true, required: true },\n { name: 'title', storage: 'text', interpretation: 'plain' },\n { name: 'model', storage: 'text', interpretation: 'plain' },\n { name: 'compactedSummary', storage: 'text', interpretation: 'plain' },\n { name: 'compactedThroughId', storage: 'text', interpretation: 'plain' },\n ],\n ownerField: 'userId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: 'own', create: false, update: 'own', delete: 'own' },\n viewer: { read: 'own', create: false, update: false, delete: false },\n },\n}\n\nexport const AI_MESSAGES_SCHEMA: CollectionSchema = {\n name: 'ai-messages',\n columns: [\n { name: 'chatId', storage: 'text', interpretation: 'plain', immutable: true, required: true },\n { name: 'userId', storage: 'text', interpretation: 'plain', userBound: true, immutable: true, required: true },\n { name: 'role', storage: 'text', interpretation: 'plain', required: true },\n { name: 'content', storage: 'text', interpretation: 'plain' },\n { name: 'parts', storage: 'text', interpretation: { kind: 'json' } },\n ],\n ownerField: 'userId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: 'own', create: false, update: 'own', delete: 'own' },\n viewer: { read: 'own', create: false, update: false, delete: false },\n },\n}\n","/**\n * Messaging Schemas\n *\n * Pre-built collection schemas for messaging functionality.\n * Any app can import these to add channels, messages, reactions, etc.\n *\n * @example\n * ```typescript\n * import { CHANNELS_SCHEMA, MESSAGES_SCHEMA, REACTIONS_SCHEMA } from 'deepspace/worker'\n * export const schemas = [usersSchema, CHANNELS_SCHEMA, MESSAGES_SCHEMA, REACTIONS_SCHEMA]\n * ```\n */\n\nimport type { CollectionSchema } from './registry'\n\nexport const CHANNELS_SCHEMA: CollectionSchema = {\n name: 'channels',\n columns: [\n { name: 'name', storage: 'text', interpretation: 'plain' },\n { name: 'description', storage: 'text', interpretation: 'plain' },\n {\n name: 'type',\n storage: 'text',\n interpretation: { kind: 'select', options: ['public', 'private', 'dm'] },\n },\n {\n name: 'createdBy',\n storage: 'text',\n interpretation: 'plain',\n userBound: true,\n immutable: true,\n },\n { name: 'archived', storage: 'number', interpretation: { kind: 'boolean' } },\n ],\n ownerField: 'createdBy',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: true, create: true, update: 'own', delete: false },\n viewer: { read: true, create: false, update: false, delete: false },\n },\n}\n\nexport const MESSAGES_SCHEMA: CollectionSchema = {\n name: 'messages',\n columns: [\n { name: 'channelId', storage: 'text', interpretation: 'plain' },\n { name: 'content', storage: 'text', interpretation: 'plain' },\n {\n name: 'authorId',\n storage: 'text',\n interpretation: 'plain',\n userBound: true,\n immutable: true,\n },\n { name: 'parentMessageId', storage: 'text', interpretation: 'plain' },\n { name: 'edited', storage: 'number', interpretation: { kind: 'boolean' } },\n { name: 'editedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n // Soft-delete flag. Slack-style messaging keeps the row + parent IDs\n // intact (so threads remain coherent) and renders a tombstone instead.\n // Hard-delete via remove() still works if an app wants it.\n { name: 'deleted', storage: 'number', interpretation: { kind: 'boolean' } },\n ],\n ownerField: 'authorId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: true, create: true, update: 'own', delete: 'own' },\n viewer: { read: true, create: false, update: false, delete: false },\n },\n}\n\nexport const REACTIONS_SCHEMA: CollectionSchema = {\n name: 'reactions',\n columns: [\n { name: 'messageId', storage: 'text', interpretation: 'plain' },\n { name: 'channelId', storage: 'text', interpretation: 'plain' },\n { name: 'emoji', storage: 'text', interpretation: 'plain' },\n { name: 'userId', storage: 'text', interpretation: 'plain', userBound: true, immutable: true },\n ],\n ownerField: 'userId',\n uniqueOn: ['messageId', 'emoji', 'userId'],\n permissions: {\n admin: { read: true, create: true, update: false, delete: true },\n member: { read: true, create: true, update: false, delete: 'own' },\n viewer: { read: true, create: false, update: false, delete: false },\n },\n}\n\nexport const CHANNEL_MEMBERS_SCHEMA: CollectionSchema = {\n name: 'channel-members',\n columns: [\n { name: 'channelId', storage: 'text', interpretation: 'plain' },\n { name: 'userId', storage: 'text', interpretation: 'plain', userBound: true, immutable: true },\n { name: 'joinedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n ],\n ownerField: 'userId',\n uniqueOn: ['channelId', 'userId'],\n permissions: {\n admin: { read: true, create: true, update: false, delete: true },\n member: { read: true, create: true, update: false, delete: 'own' },\n viewer: { read: true, create: false, update: false, delete: false },\n },\n}\n\nexport const CHANNEL_INVITATIONS_SCHEMA: CollectionSchema = {\n name: 'channel-invitations',\n columns: [\n {\n name: 'channelId',\n storage: 'text',\n interpretation: 'plain',\n required: true,\n immutable: true,\n },\n {\n name: 'invitedUserId',\n storage: 'text',\n interpretation: 'plain',\n required: true,\n immutable: true,\n },\n {\n name: 'invitedBy',\n storage: 'text',\n interpretation: 'plain',\n userBound: true,\n immutable: true,\n },\n {\n name: 'status',\n storage: 'text',\n interpretation: { kind: 'select', options: ['pending', 'accepted', 'declined'] },\n required: true,\n },\n ],\n uniqueOn: ['channelId', 'invitedUserId'],\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: true, create: true, update: true, delete: false },\n viewer: { read: true, create: false, update: false, delete: false },\n },\n}\n\nexport const READ_RECEIPTS_SCHEMA: CollectionSchema = {\n name: 'read-receipts',\n columns: [\n { name: 'channelId', storage: 'text', interpretation: 'plain' },\n { name: 'userId', storage: 'text', interpretation: 'plain', userBound: true, immutable: true },\n { name: 'lastReadAt', storage: 'text', interpretation: { kind: 'datetime' } },\n ],\n ownerField: 'userId',\n uniqueOn: ['channelId', 'userId'],\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: true, create: true, update: 'own', delete: 'own' },\n viewer: { read: false, create: false, update: false, delete: false },\n },\n}\n","/**\n * Shared conversation schemas for RecordRoom-based conversations.\n *\n * These define the collections inside a per-conversation RecordRoom DO.\n * Used by apps that have messaging/conversation features (slack-clone,\n * helpdesk, mail, reddit-clone, etc.).\n *\n * Each conversation gets its own RecordRoom DO keyed by `conv:{id}`.\n */\n\nimport type { CollectionSchema } from './registry'\n\n// Re-export data interfaces from types (single source of truth)\nexport type {\n ConvMessageData,\n ConvReactionData,\n ConvMemberData,\n ConvReadCursorData,\n ConvVoteData,\n} from '../../shared/types'\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\nexport const CONVERSATION_SCHEMAS: CollectionSchema[] = [\n {\n name: 'conv_messages',\n columns: [\n { name: 'Content', storage: 'text', interpretation: 'plain' },\n { name: 'AuthorId', storage: 'text', interpretation: 'plain' },\n { name: 'ParentId', storage: 'text', interpretation: 'plain' },\n { name: 'Edited', storage: 'number', interpretation: 'boolean' },\n { name: 'MessageType', storage: 'text', interpretation: 'plain' },\n { name: 'Metadata', storage: 'text', interpretation: 'json' },\n ],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: 'own', delete: 'own' },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'AuthorId',\n },\n {\n name: 'conv_reactions',\n columns: [\n { name: 'MessageId', storage: 'text', interpretation: 'plain' },\n { name: 'Emoji', storage: 'text', interpretation: 'plain' },\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n ],\n uniqueOn: ['MessageId', 'Emoji', 'UserId'],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: false, delete: 'own' },\n admin: { read: true, create: true, update: false, delete: true },\n },\n ownerField: 'UserId',\n },\n {\n name: 'conv_members',\n columns: [\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n { name: 'UserName', storage: 'text', interpretation: 'plain' },\n { name: 'Role', storage: 'text', interpretation: 'plain' },\n ],\n uniqueOn: ['UserId'],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: 'own', delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'UserId',\n },\n {\n name: 'conv_read_cursors',\n columns: [\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n { name: 'LastReadAt', storage: 'text', interpretation: 'plain' },\n ],\n uniqueOn: ['UserId'],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: 'own', delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'UserId',\n },\n]\n\n/**\n * Voting schemas for Reddit-style apps.\n * Add these alongside CONVERSATION_SCHEMAS for apps that need voting.\n */\nexport const VOTING_SCHEMAS: CollectionSchema[] = [\n {\n name: 'conv_votes',\n columns: [\n { name: 'TargetId', storage: 'text', interpretation: 'plain' },\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n { name: 'Direction', storage: 'number', interpretation: 'plain' },\n ],\n uniqueOn: ['TargetId', 'UserId'],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: 'own', delete: 'own' },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'UserId',\n },\n]\n","/**\n * Directory DO Schemas\n *\n * Purpose-built collections for the `dir:{appName}` global DO type.\n * This is the cross-app-visible directory layer — any app can subscribe\n * to another app's directory in real-time via SHARED_CONNECTIONS.\n *\n * Five collections covering all standard communication/social patterns:\n * - conversations: channels, DMs, email threads, support chats\n * - conversation_state: per-user metadata (read cursor, stars, labels, folders)\n * - communities: groups, forums, boards, projects\n * - memberships: user membership in communities\n * - posts: feed items, tweets, Q&A questions, announcements\n *\n * Domain-specific data (tickets, CRM, procurement) stays in app DOs.\n * Message content stays in conv:{id} DOs (CONVERSATION_SCHEMAS).\n */\n\nimport type { CollectionSchema } from './registry'\n\n// Re-export data interfaces from types (single source of truth)\nexport type {\n DirectoryConversationData,\n ConversationStateData,\n DirectoryCommunityData,\n DirectoryMembershipData,\n DirectoryPostData,\n} from '../../shared/types'\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\nconst conversationsSchema: CollectionSchema = {\n name: 'conversations',\n columns: [\n { name: 'Name', storage: 'text', interpretation: 'plain' },\n { name: 'Description', storage: 'text', interpretation: 'plain' },\n { name: 'Type', storage: 'text', interpretation: { kind: 'select', options: ['public', 'private', 'dm', 'group', 'email', 'outbound-email', 'support', 'announcement'] } },\n { name: 'Visibility', storage: 'text', interpretation: { kind: 'select', options: ['public', 'private', 'restricted'] } },\n { name: 'CreatedBy', storage: 'text', interpretation: 'plain' },\n { name: 'ParticipantHash', storage: 'text', interpretation: 'plain' },\n { name: 'ParticipantIds', storage: 'text', interpretation: 'json' },\n { name: 'Status', storage: 'text', interpretation: { kind: 'select', options: ['active', 'archived', 'resolved', 'closed'] } },\n { name: 'AssigneeId', storage: 'text', interpretation: 'plain' },\n { name: 'LinkedRef', storage: 'text', interpretation: 'json' },\n { name: 'LastMessageAt', storage: 'text', interpretation: { kind: 'datetime' } },\n { name: 'LastMessagePreview', storage: 'text', interpretation: 'plain' },\n { name: 'LastMessageAuthor', storage: 'text', interpretation: 'plain' },\n { name: 'MessageCount', storage: 'number', interpretation: 'plain' },\n ],\n collaboratorsField: 'ParticipantIds',\n visibilityField: 'Visibility',\n permissions: {\n viewer: { read: 'shared', create: false, update: false, delete: false },\n member: { read: 'shared', create: true, update: true, delete: 'own' },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'CreatedBy',\n}\n\nconst conversationStateSchema: CollectionSchema = {\n name: 'conversation_state',\n columns: [\n { name: 'ConversationId', storage: 'text', interpretation: 'plain' },\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n { name: 'LastReadAt', storage: 'text', interpretation: { kind: 'datetime' } },\n { name: 'LastReadMessageCount', storage: 'number', interpretation: 'plain' },\n { name: 'Starred', storage: 'number', interpretation: 'boolean' },\n { name: 'Archived', storage: 'number', interpretation: 'boolean' },\n { name: 'Trashed', storage: 'number', interpretation: 'boolean' },\n { name: 'Labels', storage: 'text', interpretation: 'json' },\n { name: 'Folder', storage: 'text', interpretation: 'plain' },\n ],\n uniqueOn: ['ConversationId', 'UserId'],\n ownerField: 'UserId',\n permissions: {\n viewer: { read: false, create: false, update: false, delete: false },\n member: { read: 'own', create: true, update: 'own', delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n}\n\nconst communitiesSchema: CollectionSchema = {\n name: 'communities',\n columns: [\n { name: 'Name', storage: 'text', interpretation: 'plain' },\n { name: 'Description', storage: 'text', interpretation: 'plain' },\n { name: 'CreatedBy', storage: 'text', interpretation: 'plain' },\n { name: 'Type', storage: 'text', interpretation: { kind: 'select', options: ['community', 'forum', 'board', 'project', 'server'] } },\n { name: 'Visibility', storage: 'text', interpretation: { kind: 'select', options: ['public', 'private', 'restricted'] } },\n { name: 'MemberCount', storage: 'number', interpretation: 'plain' },\n { name: 'Rules', storage: 'text', interpretation: 'json' },\n { name: 'IconUrl', storage: 'text', interpretation: 'plain' },\n { name: 'CoverUrl', storage: 'text', interpretation: 'plain' },\n ],\n uniqueOn: ['Name'],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: 'own', delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'CreatedBy',\n}\n\nconst membershipsSchema: CollectionSchema = {\n name: 'memberships',\n columns: [\n { name: 'CommunityId', storage: 'text', interpretation: 'plain' },\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n { name: 'UserName', storage: 'text', interpretation: 'plain' },\n { name: 'Role', storage: 'text', interpretation: { kind: 'select', options: ['member', 'moderator', 'admin'] } },\n { name: 'JoinedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n ],\n uniqueOn: ['CommunityId', 'UserId'],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: 'own', delete: 'own' },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'UserId',\n}\n\nconst postsSchema: CollectionSchema = {\n name: 'posts',\n columns: [\n { name: 'Title', storage: 'text', interpretation: 'plain' },\n { name: 'Content', storage: 'text', interpretation: 'plain' },\n { name: 'AuthorId', storage: 'text', interpretation: 'plain' },\n { name: 'Type', storage: 'text', interpretation: { kind: 'select', options: ['post', 'question', 'answer', 'tweet', 'announcement', 'link'] } },\n { name: 'CommunityId', storage: 'text', interpretation: 'plain' },\n { name: 'ParentId', storage: 'text', interpretation: 'plain' },\n { name: 'ConversationId', storage: 'text', interpretation: 'plain' },\n { name: 'Status', storage: 'text', interpretation: { kind: 'select', options: ['draft', 'published', 'pinned', 'archived', 'accepted'] } },\n { name: 'Tags', storage: 'text', interpretation: 'json' },\n { name: 'LinkUrl', storage: 'text', interpretation: 'plain' },\n ],\n permissions: {\n viewer: { read: true, create: false, update: false, delete: false },\n member: { read: true, create: true, update: 'own', delete: 'own' },\n admin: { read: true, create: true, update: true, delete: true },\n },\n ownerField: 'AuthorId',\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n/** All directory schemas for the `dir:{appName}` global DO type. */\nexport const DIRECTORY_SCHEMAS: CollectionSchema[] = [\n conversationsSchema,\n conversationStateSchema,\n communitiesSchema,\n membershipsSchema,\n postsSchema,\n]\n","/**\n * Workspace DO Schemas\n *\n * All collections for the workspace:default Durable Object.\n * This DO consolidates shared, cross-app business data:\n *\n * - teams / team_members — workspace-wide team management (replaces built-in teams)\n * - tasks / projects / tags — team-scoped task management\n * - people — shared contacts directory\n * - transactions / accounts — shared financial ledger\n *\n * Team-scoped collections use teamField RBAC: members see only\n * their team's records; admins see everything.\n */\n\nimport type { CollectionSchema } from './registry'\n\n// ============================================================================\n// Teams\n// ============================================================================\n\nexport const workspaceTeamsSchema: CollectionSchema = {\n name: 'teams',\n columns: [\n { name: 'Name', storage: 'text', interpretation: 'plain' },\n { name: 'CreatedBy', storage: 'text', interpretation: 'plain' },\n { name: 'IsOpen', storage: 'number', interpretation: { kind: 'boolean' } },\n ],\n teamField: '_rowId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: 'team', create: true, update: 'team', delete: 'own' },\n },\n}\n\nexport const workspaceTeamMembersSchema: CollectionSchema = {\n name: 'team_members',\n columns: [\n { name: 'TeamId', storage: 'text', interpretation: 'plain' },\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n { name: 'RoleInTeam', storage: 'text', interpretation: { kind: 'select', options: ['admin', 'member'] } },\n { name: 'JoinedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n { name: 'Email', storage: 'text', interpretation: { kind: 'email' } },\n { name: 'Status', storage: 'text', interpretation: { kind: 'select', options: ['active', 'invited'] } },\n ],\n teamField: 'TeamId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: 'team', create: true, update: 'team', delete: 'team' },\n },\n}\n\n// ============================================================================\n// Tasks / Projects / Tags (team-scoped)\n// ============================================================================\n\nexport const workspaceTasksSchema: CollectionSchema = {\n name: 'tasks',\n columns: [\n { name: 'TeamId', storage: 'text', interpretation: 'plain' },\n { name: 'Title', storage: 'text', interpretation: 'plain' },\n { name: 'Notes', storage: 'text', interpretation: 'plain' },\n { name: 'Completed', storage: 'number', interpretation: { kind: 'boolean' } },\n { name: 'CompletedAt', storage: 'number', interpretation: 'plain' },\n { name: 'Deleted', storage: 'number', interpretation: { kind: 'boolean' } },\n { name: 'DeletedAt', storage: 'number', interpretation: 'plain' },\n { name: 'Priority', storage: 'text', interpretation: { kind: 'select', options: ['none', 'low', 'medium', 'high'] } },\n { name: 'DueDate', storage: 'text', interpretation: 'plain' },\n { name: 'ProjectId', storage: 'text', interpretation: 'plain' },\n { name: 'KanbanStatus', storage: 'text', interpretation: { kind: 'select', options: ['backlog', 'ready', 'in_progress', 'review', 'done'] } },\n { name: 'Order', storage: 'number', interpretation: 'plain' },\n { name: 'AssignedUser', storage: 'text', interpretation: { kind: 'json' } },\n { name: 'AssignedBy', storage: 'text', interpretation: { kind: 'json' } },\n { name: 'TagIds', storage: 'text', interpretation: { kind: 'json' } },\n { name: 'CreatedAt', storage: 'number', interpretation: 'plain' },\n ],\n teamField: 'TeamId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: 'team', create: true, update: 'team', delete: 'team' },\n viewer: { read: false, create: false, update: false, delete: false },\n },\n}\n\nexport const workspaceProjectsSchema: CollectionSchema = {\n name: 'projects',\n columns: [\n { name: 'TeamId', storage: 'text', interpretation: 'plain' },\n { name: 'Title', storage: 'text', interpretation: 'plain' },\n { name: 'Notes', storage: 'text', interpretation: 'plain' },\n { name: 'Color', storage: 'text', interpretation: 'plain' },\n { name: 'ParentId', storage: 'text', interpretation: 'plain' },\n { name: 'Order', storage: 'number', interpretation: 'plain' },\n { name: 'CreatedAt', storage: 'number', interpretation: 'plain' },\n ],\n teamField: 'TeamId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: 'team', create: true, update: 'team', delete: 'team' },\n viewer: { read: false, create: false, update: false, delete: false },\n },\n}\n\nexport const workspaceTagsSchema: CollectionSchema = {\n name: 'tags',\n columns: [\n { name: 'TeamId', storage: 'text', interpretation: 'plain' },\n { name: 'Name', storage: 'text', interpretation: 'plain' },\n { name: 'Color', storage: 'text', interpretation: 'plain' },\n { name: 'CreatedAt', storage: 'number', interpretation: 'plain' },\n ],\n teamField: 'TeamId',\n permissions: {\n admin: { read: true, create: true, update: true, delete: true },\n member: { read: 'team', create: true, update: 'team', delete: 'team' },\n viewer: { read: false, create: false, update: false, delete: false },\n },\n}\n\n// ============================================================================\n// People (shared contacts directory)\n// ============================================================================\n\nexport const workspacePeopleSchema: CollectionSchema = {\n name: 'people',\n columns: [\n { name: 'Name', storage: 'text', interpretation: 'plain' },\n { name: 'Email', storage: 'text', interpretation: { kind: 'email' } },\n { name: 'Type', storage: 'text', interpretation: { kind: 'select', options: ['employee', 'customer', 'vendor', 'contact'] } },\n { name: 'Status', storage: 'text', interpretation: { kind: 'select', options: ['active', 'inactive', 'archived'] } },\n { name: 'CompanyId', storage: 'text', interpretation: 'plain' },\n { name: 'Department', storage: 'text', interpretation: 'plain' },\n { name: 'Title', storage: 'text', interpretation: 'plain' },\n { name: 'LastContactedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n { name: 'Metadata', storage: 'text', interpretation: { kind: 'json' } },\n ],\n permissions: {\n '*': { read: true, create: true, update: true, delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n}\n\n// ============================================================================\n// Ledger (shared financial data)\n// ============================================================================\n\nexport const workspaceTransactionsSchema: CollectionSchema = {\n name: 'transactions',\n columns: [\n { name: 'Type', storage: 'text', interpretation: { kind: 'select', options: ['revenue', 'expense', 'payment', 'transfer', 'invoice', 'refund'] } },\n { name: 'Amount', storage: 'number', interpretation: { kind: 'currency', symbol: '$', decimals: 2 } },\n { name: 'Currency', storage: 'text', interpretation: 'plain' },\n { name: 'Description', storage: 'text', interpretation: 'plain' },\n { name: 'Category', storage: 'text', interpretation: 'plain' },\n { name: 'CounterpartyRef', storage: 'text', interpretation: 'plain' },\n { name: 'OrderRef', storage: 'text', interpretation: 'plain' },\n { name: 'Account', storage: 'text', interpretation: 'plain' },\n ],\n permissions: {\n '*': { read: true, create: true, update: true, delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n}\n\nexport const workspaceAccountsSchema: CollectionSchema = {\n name: 'accounts',\n columns: [\n { name: 'Name', storage: 'text', interpretation: 'plain' },\n { name: 'Balance', storage: 'number', interpretation: { kind: 'currency', symbol: '$', decimals: 2 } },\n { name: 'Currency', storage: 'text', interpretation: 'plain' },\n ],\n permissions: {\n '*': { read: true, create: true, update: true, delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n}\n\n// ============================================================================\n// Content Sharing (universal cross-app content discovery)\n// ============================================================================\n\n/**\n * Universal sharing index. Any app can create share records for any content type.\n *\n * ContentType: 'document' | 'slide' | 'spreadsheet' | ... (extensible)\n * ShareType: 'channel' | 'team' | 'direct' | 'link' | 'org' (extensible)\n * ShareTarget: the ID of the target (channelId, teamId, userId, linkId, orgId)\n * Permission: 'view' | 'edit' — what the share grants\n *\n * Content itself lives in the owner's app DO.\n * This table is the discovery layer: \"what has been shared, with whom, and how\".\n */\nexport const workspaceContentSharesSchema: CollectionSchema = {\n name: 'content_shares',\n ownerField: 'OwnerId',\n columns: [\n { name: 'ContentType', storage: 'text', interpretation: { kind: 'select', options: ['document', 'slide', 'spreadsheet'] } },\n { name: 'ContentId', storage: 'text', interpretation: 'plain' },\n { name: 'OwnerId', storage: 'text', interpretation: 'plain' },\n { name: 'OwnerName', storage: 'text', interpretation: 'plain' },\n { name: 'Title', storage: 'text', interpretation: 'plain' },\n { name: 'ShareType', storage: 'text', interpretation: { kind: 'select', options: ['self', 'channel', 'team', 'direct', 'link', 'org'] } },\n { name: 'ShareTarget', storage: 'text', interpretation: 'plain' },\n { name: 'Permission', storage: 'text', interpretation: { kind: 'select', options: ['view', 'edit'] } },\n { name: 'SharedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n { name: 'SharedBy', storage: 'text', interpretation: 'plain' },\n { name: 'SourceApp', storage: 'text', interpretation: 'plain' },\n { name: 'WordCount', storage: 'number', interpretation: 'plain' },\n { name: 'LastEditedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n ],\n permissions: {\n '*': { read: true, create: true, update: true, delete: 'own' },\n admin: { read: true, create: true, update: true, delete: true },\n },\n}\n\n// ============================================================================\n// Form Responses (cross-app: deepspace-forms → sheets-editor)\n// ============================================================================\n\nexport const workspaceFormResponsesSchema: CollectionSchema = {\n name: 'form_responses',\n columns: [\n { name: 'FormId', storage: 'text', interpretation: 'plain' },\n { name: 'FormTitle', storage: 'text', interpretation: 'plain' },\n { name: 'RespondentId', storage: 'text', interpretation: 'plain' },\n { name: 'RespondentEmail', storage: 'text', interpretation: { kind: 'email' } },\n { name: 'RespondentName', storage: 'text', interpretation: 'plain' },\n { name: 'Data', storage: 'text', interpretation: { kind: 'json' } },\n { name: 'SubmittedAt', storage: 'text', interpretation: { kind: 'datetime' } },\n ],\n permissions: {\n '*': { read: true, create: true, update: false, delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n}\n\n// ============================================================================\n// Email Handles (cross-app user identity)\n// ============================================================================\n\n/**\n * Maps DeepSpace users to their claimed @app.space email handles.\n * Shared across all apps so any app can look up a user's email address.\n * All handles are under the @app.space domain.\n */\nexport const workspaceEmailHandlesSchema: CollectionSchema = {\n name: 'email_handles',\n columns: [\n { name: 'UserId', storage: 'text', interpretation: 'plain' },\n { name: 'Handle', storage: 'text', interpretation: 'plain' },\n { name: 'EmailAddress', storage: 'text', interpretation: { kind: 'email' } },\n { name: 'Status', storage: 'text', interpretation: { kind: 'select', options: ['active', 'disabled'] } },\n ],\n uniqueOn: ['Handle'],\n ownerField: 'UserId',\n permissions: {\n '*': { read: true, create: true, update: 'own', delete: false },\n admin: { read: true, create: true, update: true, delete: true },\n },\n}\n\n// ============================================================================\n// Export\n// ============================================================================\n\nexport const WORKSPACE_SCHEMAS: CollectionSchema[] = [\n workspaceTeamsSchema,\n workspaceTeamMembersSchema,\n workspaceTasksSchema,\n workspaceProjectsSchema,\n workspaceTagsSchema,\n workspacePeopleSchema,\n workspaceTransactionsSchema,\n workspaceAccountsSchema,\n workspaceContentSharesSchema,\n workspaceFormResponsesSchema,\n workspaceEmailHandlesSchema,\n]\n"],"mappings":"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","names":[]}
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { LanguageModel, ToolSet, ModelMessage } from 'ai';
1
+ import { LanguageModel, ToolSet, StreamTextResult, streamText, ModelMessage } from 'ai';
2
2
  import * as Y from 'yjs';
3
3
  import * as zod_v4_core from 'zod/v4/core';
4
4
  import * as zod from 'zod';
@@ -704,6 +704,46 @@ interface CronEnv extends ApiWorkerEnv {
704
704
  */
705
705
  declare function buildCronContext(env: CronEnv, ownerUserId: string, roomId?: string): CronContext;
706
706
 
707
+ /**
708
+ * Canonical DeepSpace model catalog and agent policy.
709
+ *
710
+ * Provider catalogs are discovery inputs, not a safe runtime allowlist: a
711
+ * model is promoted here only after its tool loop, transport, pricing, and
712
+ * streaming contract have been verified end to end through the DeepSpace
713
+ * proxy. Every client picker and server agent profile consumes this module.
714
+ */
715
+ type DeepSpaceAIProvider = 'anthropic' | 'openai' | 'cerebras';
716
+ type DeepSpaceAgentProfileId = 'application' | 'documentation';
717
+ type DeepSpaceAgentSupport = 'multi-step' | 'single-step' | 'none';
718
+ interface DeepSpaceAIModel {
719
+ id: string;
720
+ label: string;
721
+ provider: DeepSpaceAIProvider;
722
+ providerLabel: string;
723
+ family: string;
724
+ /** Whether the model is eligible for DeepSpace's server-owned agent loop. */
725
+ agentSupport: DeepSpaceAgentSupport;
726
+ /** Profiles in which the model has passed the complete runtime contract. */
727
+ agentProfiles: readonly DeepSpaceAgentProfileId[];
728
+ /** Provider transport currently used by the DeepSpace proxy adapter. */
729
+ transport: 'messages' | 'chat-completions';
730
+ recommendation: 'frontier' | 'balanced' | 'fast' | 'available' | 'limited';
731
+ note?: string;
732
+ }
733
+ interface DeepSpaceAgentProfile {
734
+ id: DeepSpaceAgentProfileId;
735
+ defaultModel: string;
736
+ maxSteps: number;
737
+ maxToolCalls?: number;
738
+ allowedTools: 'application-defined' | readonly string[];
739
+ }
740
+ interface ResolvedDeepSpaceAgentModel {
741
+ modelId: string;
742
+ provider: DeepSpaceAIProvider;
743
+ model: DeepSpaceAIModel;
744
+ profile: DeepSpaceAgentProfile;
745
+ }
746
+
707
747
  /**
708
748
  * AI provider helpers — create Vercel AI SDK providers that route through
709
749
  * the DeepSpace API worker proxy for per-user billing.
@@ -744,7 +784,6 @@ declare function buildCronContext(env: CronEnv, ownerUserId: string, roomId?: st
744
784
  * paths into the published `dist/index.d.ts`.
745
785
  */
746
786
  type DeepSpaceModelFactory = (modelId: string) => LanguageModel;
747
- type Provider = 'anthropic' | 'openai' | 'cerebras';
748
787
  interface DeepSpaceAIEnv extends ApiWorkerEnv {
749
788
  /**
750
789
  * Long-lived owner-scoped JWT minted at deploy time (or by `deepspace dev start`).
@@ -772,7 +811,39 @@ interface DeepSpaceAIOptions {
772
811
  * (explicit or `env.APP_OWNER_JWT`) automatically. Throws a clear error if
773
812
  * either is unconfigured.
774
813
  */
775
- declare function createDeepSpaceAI(env: DeepSpaceAIEnv, provider: Provider, options?: DeepSpaceAIOptions): DeepSpaceModelFactory;
814
+ declare function createDeepSpaceAI(env: DeepSpaceAIEnv, provider: DeepSpaceAIProvider, options?: DeepSpaceAIOptions): DeepSpaceModelFactory;
815
+
816
+ type StreamTextOptions<TOOLS extends ToolSet> = Parameters<typeof streamText<TOOLS>>[0];
817
+ type DeepSpaceAgentStreamOptions<TOOLS extends ToolSet> = Omit<StreamTextOptions<TOOLS>, 'model' | 'providerOptions' | 'stopWhen'> & {
818
+ profile: DeepSpaceAgentProfileId;
819
+ modelId?: unknown;
820
+ authToken?: string;
821
+ };
822
+ interface DeepSpaceAgentStream<TOOLS extends ToolSet> {
823
+ selection: ResolvedDeepSpaceAgentModel;
824
+ result: StreamTextResult<TOOLS, never>;
825
+ }
826
+ declare class DeepSpaceAgentModelError extends Error {
827
+ readonly modelId: unknown;
828
+ readonly profile: DeepSpaceAgentProfileId;
829
+ readonly code = "unsupported_agent_model";
830
+ constructor(modelId: unknown, profile: DeepSpaceAgentProfileId);
831
+ }
832
+ declare class DeepSpaceAgentProfileError extends Error {
833
+ readonly profile: DeepSpaceAgentProfileId;
834
+ readonly toolName: string;
835
+ readonly code = "agent_profile_violation";
836
+ constructor(profile: DeepSpaceAgentProfileId, toolName: string);
837
+ }
838
+ /** The sole provider/model/tool-loop implementation for every DeepSpace agent surface. */
839
+ declare function streamDeepSpaceAgent<TOOLS extends ToolSet>(env: DeepSpaceAIEnv, options: DeepSpaceAgentStreamOptions<TOOLS>): DeepSpaceAgentStream<TOOLS>;
840
+ interface DeepSpaceAgentDiagnosticContext {
841
+ profile?: DeepSpaceAgentProfileId;
842
+ provider?: string;
843
+ modelId?: string;
844
+ }
845
+ /** Preserve safe structured provider diagnostics in bounded Worker logs. */
846
+ declare function deepSpaceAgentErrorSummary(error: unknown, context?: DeepSpaceAgentDiagnosticContext): string;
776
847
 
777
848
  /**
778
849
  * Composio tools for the Vercel AI SDK.
@@ -2497,6 +2568,14 @@ type CustomBinding = {
2497
2568
  type: 'hyperdrive';
2498
2569
  name: string;
2499
2570
  id: string;
2571
+ } | {
2572
+ type: 'ratelimit';
2573
+ name: string;
2574
+ namespace_id: string;
2575
+ simple: {
2576
+ limit: number;
2577
+ period: 10 | 60;
2578
+ };
2500
2579
  };
2501
2580
  type CustomBindingManifest = CustomBinding[];
2502
2581
  /** Sentinel string in an ID field that requests platform-side provisioning. */
@@ -4436,4 +4515,4 @@ declare class RefundError extends Error {
4436
4515
  constructor(message: string, status: number);
4437
4516
  }
4438
4517
 
4439
- export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, APP_ID_RE, APP_NAME_RULES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type ApiWorkerEnv, type AppNameResolution, type AppNameValidation, type AuthWorkerEnv, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CONVERSATION_SCHEMAS, COST_RATES, CancelSubscriptionError, type CancelSubscriptionOpts, type CancelSubscriptionResult, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type CollectionPermissionSummary, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, type ConvMemberData, type ConvMessageData, type ConvReactionData, type ConvReadCursorData, type ConvVoteData, type ConversationStateData, type CronContext, type CronExecution, CronRoom, type CronRoomConfig, type CronTask, type CustomBinding, type CustomBindingManifest, DEFAULT_CONTEXT_CONFIG, DEFAULT_DO_MANIFEST, DEFAULT_QUERY_LIMIT, DEPLOYED_APPS_DEFAULTS, DIRECTORY_SCHEMAS, type DOBindings, type DOManifest, type DOManifestEntry, type DebugApiContext, type DeepSpaceAIEnv, type DeepSpaceAIOptions, type DeepSpaceAuth, type DeepSpaceAuthConfig, type DirectoryCommunityData, type DirectoryConversationData, type DirectoryMembershipData, type DirectoryPostData, type DoMigrationDirective, type DoMigrationPlan, type ExistingDOBinding, GLOBAL_DO_TYPES, GLOBAL_DO_TYPE_NAMES, type GameInput, GameRoom, type GameRoomConfig, type GetActionData, type GlobalDOType, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, MESSAGES_SCHEMA, type MutateActionData, type PermissionAnalysis, type PermissionContext, type PermissionLevel, type PermissionSource, type PlanInfo, type PlatformWorkerEnv, type Player, type PrefixResult, type PresencePeer, PresenceRoom, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, REGISTRY_INSTANCE, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, RESOURCE_ID_RE, type RecordContext, RecordRoom, type RecordRoomConfig, RefundError, type RefundOpts, type RefundResult, RegistryClientError, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, STRICT_APP_ID_RE, SYSTEM_COLLECTION_SCHEMAS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotResult, type SharedConnection, type StoredRecord, SubscriptionAuthError, type SubscriptionContext, type SubscriptionRead, SubscriptionRequiredError, type SubscriptionStatus, type Summarizer, TEST_ACCOUNT_EMAIL_SUFFIX, type TokenDebugInfo, type ToolResult, type ToolSchema, type ToolsApiContext, USERS_COLUMNS, type User, type UserAttachment, type UserContext, VOTING_SCHEMAS, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKSPACE_SCHEMAS, type YjsContext, YjsRoom, analyzePermissions, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, authWorkerFetch, bindingManifestFromOutputConfig, broadcastChange, broadcastYjsUpdate, buildCronContext, buildTableSelect, buildUiParts, callRegistry, canCreate, canDelete, canRead, canUpdate, cancelSubscription, capToolResultSize, captureScreenshot, checkFieldPermissions, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDeepSpaceAI, createDeepSpaceAuth, createScopedR2Handler, dataToColumnValues, decodeJwtPayload, deleteChatCascade, deleteRecord, enqueueJob, executeQuery, getAllUsers, getChat, getGlobalDOSchemas, getGlobalDOType, getOrCreateYjsDoc, getRecord, getRolePermissions, getSubscription, getUser, getYjsDocKey, handleApiRequest, handleDelete, handlePut, handleSetRole, handleSubscribe, handleToolsRequest, handleUnsubscribe, handleUserList, handleUserUpdate, handleYjsBinaryMessage, handleYjsJoin, handleYjsLeave, isAutoProvision, isOwner, isTestAccountClaims, isTestAccountEmail, isTestAccountTier, lintSchema, loadMessages, makeDefaultSummarizer, matchOrigin, meterAi, meterUsage, meterVectorize, noopPermissionContext, parseQuotaLimit, platformCorsPatterns, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, putRecord, readRecord, recordMatchesSubscription, refundInvoice, registerUser, registryErrorJson, registryStub, requireSubscription, resolveAppName, resolveColumn, rowToData, runMigrations, saveYjsDoc, timingSafeEqualHex, timingSafeEqualStrings, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema };
4518
+ export { AI_CHATS_SCHEMA, AI_MESSAGES_SCHEMA, ALLOWED_BINDING_TYPES, APP_ID_RE, APP_NAME_RULES, AUTO_PROVISIONABLE_TYPES, AUTO_PROVISION_SENTINEL, type ActionContext, type ActionHandler, type ActionResult, type ActionTools, type ApiWorkerEnv, type AppNameResolution, type AppNameValidation, type AuthWorkerEnv, BASE_USERS_SCHEMA, BUILT_IN_TOOLS, BaseRoom, CHANNELS_SCHEMA, CHANNEL_INVITATIONS_SCHEMA, CHANNEL_MEMBERS_SCHEMA, CONVERSATION_SCHEMAS, COST_RATES, CancelSubscriptionError, type CancelSubscriptionOpts, type CancelSubscriptionResult, CanvasRoom, type CanvasShape, type ChatContextConfig, type ChatMessageRow, type ChatRow, type ChatTurn, type CollectionPermissionSummary, type CollectionSchema, type ColumnDefinition, type ColumnInterpretation, type ComposioToolsOptions, type ConvMemberData, type ConvMessageData, type ConvReactionData, type ConvReadCursorData, type ConvVoteData, type ConversationStateData, type CronContext, type CronExecution, CronRoom, type CronRoomConfig, type CronTask, type CustomBinding, type CustomBindingManifest, DEFAULT_CONTEXT_CONFIG, DEFAULT_DO_MANIFEST, DEFAULT_QUERY_LIMIT, DEPLOYED_APPS_DEFAULTS, DIRECTORY_SCHEMAS, type DOBindings, type DOManifest, type DOManifestEntry, type DebugApiContext, type DeepSpaceAIEnv, type DeepSpaceAIOptions, type DeepSpaceAgentDiagnosticContext, DeepSpaceAgentModelError, DeepSpaceAgentProfileError, type DeepSpaceAgentStream, type DeepSpaceAgentStreamOptions, type DeepSpaceAuth, type DeepSpaceAuthConfig, type DirectoryCommunityData, type DirectoryConversationData, type DirectoryMembershipData, type DirectoryPostData, type DoMigrationDirective, type DoMigrationPlan, type ExistingDOBinding, GLOBAL_DO_TYPES, GLOBAL_DO_TYPE_NAMES, type GameInput, GameRoom, type GameRoomConfig, type GetActionData, type GlobalDOType, type Job, type JobContext, JobRoom, type JobRoomConfig, type JobStatus, type JwtClaims, type JwtVerifierConfig, MESSAGES_SCHEMA, type MutateActionData, type PermissionAnalysis, type PermissionContext, type PermissionLevel, type PermissionSource, type PlanInfo, type PlatformWorkerEnv, type Player, type PrefixResult, type PresencePeer, PresenceRoom, type QueryActionData, REACTIONS_SCHEMA, READ_RECEIPTS_SCHEMA, REGISTRY_INSTANCE, RESERVED_BINDING_NAMES, RESERVED_COLLECTION_NAMES, RESOURCE_ID_RE, type RecordContext, RecordRoom, type RecordRoomConfig, RefundError, type RefundOpts, type RefundResult, RegistryClientError, type ResolvedColumn, type ResolvedPermission, type RolePermissions, type RunMigrationsResult, STRICT_APP_ID_RE, SYSTEM_COLLECTION_SCHEMAS, SYSTEM_MANAGED_COLUMNS, SchemaRegistry, type ScopeContext, type ScopedR2Auth, type ScopedR2Config, type ScopedR2Handler, type ScreenshotEnv, type ScreenshotResult, type SharedConnection, type StoredRecord, SubscriptionAuthError, type SubscriptionContext, type SubscriptionRead, SubscriptionRequiredError, type SubscriptionStatus, type Summarizer, TEST_ACCOUNT_EMAIL_SUFFIX, type TokenDebugInfo, type ToolResult, type ToolSchema, type ToolsApiContext, USERS_COLUMNS, type User, type UserAttachment, type UserContext, VOTING_SCHEMAS, type ValidationError, type VerifiedAuth, type VerifyOutcome, type VerifyResult, type Viewport, WORKSPACE_SCHEMAS, type YjsContext, YjsRoom, analyzePermissions, apiWorkerFetch, appendMessage, applyAiToolDefaults, applySlidingWindow, authWorkerFetch, bindingManifestFromOutputConfig, broadcastChange, broadcastYjsUpdate, buildCronContext, buildTableSelect, buildUiParts, callRegistry, canCreate, canDelete, canRead, canUpdate, cancelSubscription, capToolResultSize, captureScreenshot, checkFieldPermissions, coerceValue, collectionTableName, columnId, composioTools, computeDoMigration, computeHmacHex, createChat, createDeepSpaceAI, createDeepSpaceAuth, createScopedR2Handler, dataToColumnValues, decodeJwtPayload, deepSpaceAgentErrorSummary, deleteChatCascade, deleteRecord, enqueueJob, executeQuery, getAllUsers, getChat, getGlobalDOSchemas, getGlobalDOType, getOrCreateYjsDoc, getRecord, getRolePermissions, getSubscription, getUser, getYjsDocKey, handleApiRequest, handleDelete, handlePut, handleSetRole, handleSubscribe, handleToolsRequest, handleUnsubscribe, handleUserList, handleUserUpdate, handleYjsBinaryMessage, handleYjsJoin, handleYjsLeave, isAutoProvision, isOwner, isTestAccountClaims, isTestAccountEmail, isTestAccountTier, lintSchema, loadMessages, makeDefaultSummarizer, matchOrigin, meterAi, meterUsage, meterVectorize, noopPermissionContext, parseQuotaLimit, platformCorsPatterns, platformWorkerFetch, prepareMessagesWithCompaction, priceBindingUsageEvent, putRecord, readRecord, recordMatchesSubscription, refundInvoice, registerUser, registryErrorJson, registryStub, requireSubscription, resolveAppName, resolveColumn, rowToData, runMigrations, saveYjsDoc, streamDeepSpaceAgent, timingSafeEqualHex, timingSafeEqualStrings, totalChars, truncateOldToolResults, turnsToCoreMessages, unwrapToolOutput, updateChat, validateAppName, validateBindingManifest, validateDoManifest, verifyJwt, workspaceAccountsSchema, workspaceContentSharesSchema, workspaceEmailHandlesSchema, workspaceFormResponsesSchema, workspacePeopleSchema, workspaceProjectsSchema, workspaceTagsSchema, workspaceTasksSchema, workspaceTeamMembersSchema, workspaceTeamsSchema, workspaceTransactionsSchema };