@undefineds.co/models 0.2.3 → 0.2.12

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.
package/README.md CHANGED
@@ -40,6 +40,23 @@ LinX 的所有数据存储在 Solid Pod 中,使用标准的 RDF 格式。本
40
40
 
41
41
  ---
42
42
 
43
+ ## Chat / Thread / Message / Session 语义
44
+
45
+ 这组语义是 CLI、App、watch/runtime 共享的 models 级业务真相,不应在 UI、CLI 壳层或 skill 文件中重新定义。
46
+
47
+ - **Chat** 表示对话对象/counterpart:用户正在和谁或什么对话,例如默认 AI secretary、某个人、群组、Codex、Claude Code,或后续具体 AI 身份。
48
+ - **Thread** 表示具体场所、时间线和 runtime context:workspace、watch 场景、AI 产品运行时 session、外部 agent session 等上下文都归在 thread 上。
49
+ - **Message** 同时属于一个 `chat` 和一个 `thread`:chat 回答“跟谁聊”,thread 回答“在哪个运行/时间线里聊”。
50
+ - **Session** 表示通用 AI 产品/agent runtime 的运行生命周期投影:它必须指向对应的 `chat` URI 和 `thread` URI,不能作为另一套对话根。
51
+
52
+ 存储层规则:
53
+
54
+ - Pod schema 使用 `chat`、`thread` 这类 URI-valued RDF relation 字段。
55
+ - `chatId`、`threadId` 只允许作为 UI 状态、函数参数、runtime protocol 字段或 metadata 中的兼容信息,不允许作为持久 RDF link 字段。
56
+ - 新增 shared model 代码优先使用 `chatResource`、`threadResource`、`messageResource`、`sessionResource` 等 Solid resource 命名;`*Table` 只作为兼容 alias 逐步退出。
57
+
58
+ ---
59
+
43
60
  ## 标准词汇表
44
61
 
45
62
  LinX 遵循 Solid 生态的最佳实践,优先使用标准 RDF 词汇表:
@@ -575,4 +592,3 @@ MIT License
575
592
 
576
593
 
577
594
 
578
-
@@ -3,18 +3,39 @@ export interface ChatMetadata {
3
3
  memberRoles?: Record<string, ChatMemberRole>;
4
4
  }
5
5
  /**
6
- * Chat schema (channel/place).
6
+ * Chat resource.
7
7
  *
8
- * CP0 baseline (alignment):
9
- * - Chat is a container for messages/widgets regardless of counterpart type.
10
- * - Do not encode counterpart-specific behavior in Chat (no chatType/subtype).
11
- * - Participants use Solid chat-aligned flow vocabulary (wf/flow).
8
+ * Product semantics:
9
+ * - Chat means "who/what the user is talking with": a person, group, AI agent, or
10
+ * default AI secretary. It is the counterpart/conversation object, not the place
11
+ * where a runtime executes.
12
+ * - Runtime/workspace/place/session context belongs on Thread.
13
+ * - Direct LinX CLI entry should use a chat representing the AI secretary.
14
+ * - Watch entry should use a chat representing the watched agent/tool, such as
15
+ * Codex, Claude Code, or a concrete AI identity when available.
12
16
  *
13
17
  * Storage structure (aligned with xpod):
14
18
  * - Chat metadata stored as #this in index.ttl
15
19
  * - Location: /.data/chat/{id}/index.ttl#this
16
20
  * - Threads stored as fragments in same file: /.data/chat/{id}/index.ttl#{threadId}
17
21
  */
22
+ export declare const chatResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
23
+ id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
24
+ title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
25
+ description: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
26
+ avatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
27
+ starred: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
28
+ muted: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"boolean", null, false, true>;
29
+ unreadCount: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"integer", null, false, true>;
30
+ contact: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
31
+ participants: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", false, false>;
32
+ metadata: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"object", null, false, false>;
33
+ lastActiveAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
34
+ lastMessageId: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
35
+ lastMessagePreview: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
36
+ createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
37
+ updatedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
38
+ }>>;
18
39
  export declare const chatTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
19
40
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
20
41
  title: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
@@ -32,6 +53,6 @@ export declare const chatTable: import("@undefineds.co/drizzle-solid/dist/core/s
32
53
  createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
33
54
  updatedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
34
55
  }>>;
35
- export type ChatRow = typeof chatTable.$inferSelect;
36
- export type ChatInsert = typeof chatTable.$inferInsert;
37
- export type ChatUpdate = typeof chatTable.$inferUpdate;
56
+ export type ChatRow = typeof chatResource.$inferSelect;
57
+ export type ChatInsert = typeof chatResource.$inferInsert;
58
+ export type ChatUpdate = typeof chatResource.$inferUpdate;
@@ -1,19 +1,23 @@
1
1
  import { boolean, object, podTable, string, text, timestamp, uri, id, integer } from '@undefineds.co/drizzle-solid';
2
2
  import { UDFS, DCTerms, SCHEMA, MEETING, WF } from './namespaces.js';
3
3
  /**
4
- * Chat schema (channel/place).
4
+ * Chat resource.
5
5
  *
6
- * CP0 baseline (alignment):
7
- * - Chat is a container for messages/widgets regardless of counterpart type.
8
- * - Do not encode counterpart-specific behavior in Chat (no chatType/subtype).
9
- * - Participants use Solid chat-aligned flow vocabulary (wf/flow).
6
+ * Product semantics:
7
+ * - Chat means "who/what the user is talking with": a person, group, AI agent, or
8
+ * default AI secretary. It is the counterpart/conversation object, not the place
9
+ * where a runtime executes.
10
+ * - Runtime/workspace/place/session context belongs on Thread.
11
+ * - Direct LinX CLI entry should use a chat representing the AI secretary.
12
+ * - Watch entry should use a chat representing the watched agent/tool, such as
13
+ * Codex, Claude Code, or a concrete AI identity when available.
10
14
  *
11
15
  * Storage structure (aligned with xpod):
12
16
  * - Chat metadata stored as #this in index.ttl
13
17
  * - Location: /.data/chat/{id}/index.ttl#this
14
18
  * - Threads stored as fragments in same file: /.data/chat/{id}/index.ttl#{threadId}
15
19
  */
16
- export const chatTable = podTable('chats', {
20
+ export const chatResource = podTable('chats', {
17
21
  id: id('id'),
18
22
  // Display
19
23
  title: string('title').predicate(DCTerms.title).notNull(),
@@ -33,7 +37,9 @@ export const chatTable = podTable('chats', {
33
37
  metadata: object('metadata').predicate(UDFS.metadata),
34
38
  // Last activity
35
39
  lastActiveAt: timestamp('lastActiveAt').predicate(UDFS.lastActiveAt),
36
- lastMessageId: uri('lastMessageId').predicate(WF.message),
40
+ // Latest-message pointer. Do not reuse WF.message here: WF.message is the
41
+ // Solid Chat containment relation used by message.chat inverse links.
42
+ lastMessageId: uri('lastMessageId').predicate(UDFS.lastMessage),
37
43
  lastMessagePreview: text('lastMessagePreview').predicate(SCHEMA.text),
38
44
  // Timestamps
39
45
  createdAt: timestamp('createdAt').predicate(DCTerms.created).notNull().defaultNow(),
@@ -45,3 +51,5 @@ export const chatTable = podTable('chats', {
45
51
  namespace: UDFS,
46
52
  subjectTemplate: '{id}/index.ttl#this',
47
53
  });
54
+ // Compatibility alias. New model code should prefer `chatResource`.
55
+ export const chatTable = chatResource;
@@ -126,6 +126,12 @@ export function parseLinxClientSecrets(raw) {
126
126
  clientSecret: raw.clientSecret,
127
127
  };
128
128
  }
129
+ if (typeof raw.secret_id === 'string' && typeof raw.secret_key === 'string') {
130
+ return {
131
+ clientId: raw.secret_id,
132
+ clientSecret: raw.secret_key,
133
+ };
134
+ }
129
135
  if (typeof raw.oidcRefreshToken === 'string'
130
136
  && typeof raw.oidcAccessToken === 'string'
131
137
  && typeof raw.oidcExpiresAt === 'string') {
@@ -0,0 +1,3 @@
1
+ type NodeRequire = (id: string) => unknown;
2
+ export declare function applySolidComunicaPatches(requireModule?: NodeRequire): boolean;
3
+ export {};
@@ -0,0 +1,49 @@
1
+ const COMUNICA_OBSERVER_MODULES = [
2
+ '@comunica/actor-query-result-serialize-sparql-json',
3
+ '@comunica/actor-query-result-serialize-stats',
4
+ '@comunica/query-sparql-solid/node_modules/@comunica/actor-query-result-serialize-sparql-json',
5
+ '@comunica/query-sparql-solid/node_modules/@comunica/actor-query-result-serialize-stats',
6
+ ];
7
+ export function applySolidComunicaPatches(requireModule) {
8
+ const resolvedRequire = requireModule ?? createNodeRequire();
9
+ if (!resolvedRequire) {
10
+ return false;
11
+ }
12
+ return COMUNICA_OBSERVER_MODULES
13
+ .map((moduleName) => patchActionObserverHttp(resolvedRequire, moduleName))
14
+ .some(Boolean);
15
+ }
16
+ function createNodeRequire() {
17
+ const nodeProcess = typeof globalThis.process === 'object'
18
+ ? globalThis.process
19
+ : undefined;
20
+ const createRequire = nodeProcess?.getBuiltinModule?.('module')?.createRequire;
21
+ if (typeof createRequire !== 'function') {
22
+ return null;
23
+ }
24
+ return createRequire(import.meta.url);
25
+ }
26
+ function patchActionObserverHttp(requireModule, moduleName) {
27
+ try {
28
+ const module = requireModule(moduleName);
29
+ const prototype = module.ActionObserverHttp?.prototype;
30
+ const originalOnRun = prototype?.onRun;
31
+ if (!prototype || typeof originalOnRun !== 'function') {
32
+ return false;
33
+ }
34
+ if (prototype.__linxObservedActorsPatchApplied) {
35
+ return true;
36
+ }
37
+ prototype.onRun = function patchedActionObserverOnRun(actor, action, output) {
38
+ if (!Array.isArray(this.observedActors)) {
39
+ this.observedActors = [];
40
+ }
41
+ return originalOnRun.call(this, actor, action, output);
42
+ };
43
+ prototype.__linxObservedActorsPatchApplied = true;
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
@@ -1,6 +1,6 @@
1
1
  export declare const grantTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
2
2
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
3
- rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, true>;
3
+ rdfType: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", true, true>;
4
4
  target: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
5
5
  action: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
6
6
  effect: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
@@ -4,9 +4,9 @@ import { RDF, ODRL, UDFS, DCTerms } from './namespaces.js';
4
4
  // This is the durable "delegation" layer (distinct from one-off approvals and append-only audit entries).
5
5
  export const grantTable = podTable('grant', {
6
6
  id: id('id'),
7
- // Also tag the instance with our company-level class for easy discovery.
8
- // Primary rdf:type is ODRL.Policy (standard).
9
- rdfType: uri('rdfType').predicate(RDF.type).notNull().default(UDFS.AutonomyGrant),
7
+ // Table-level type writes odrl:Policy. Keep the project-specific class as
8
+ // an additional rdf:type, so readback treats RDF class membership as multi-valued.
9
+ rdfType: uri('rdfType').array().predicate(RDF.type).notNull().default([UDFS.AutonomyGrant]),
10
10
  // Minimal ODRL surface (CP0): allow/deny action on target.
11
11
  target: uri('target').predicate(ODRL.target).notNull(),
12
12
  action: uri('action').predicate(ODRL.action).notNull(),
package/dist/index.d.ts CHANGED
@@ -5,11 +5,11 @@ export * from './profile.repository';
5
5
  export * from './profile.schema';
6
6
  export { contactTable, ContactClass, ContactType, isAgentContact, isGroupContact, type ContactRow, type ContactInsert, type ContactUpdate, type ContactClassValue, type ContactTypeValue, } from './contact.schema';
7
7
  export { contactRepository } from './contact.repository';
8
- export { chatTable, type ChatMetadata, type ChatMemberRole, type ChatRow, type ChatInsert, type ChatUpdate, } from './chat.schema';
8
+ export { chatResource, chatTable, type ChatMetadata, type ChatMemberRole, type ChatRow, type ChatInsert, type ChatUpdate, } from './chat.schema';
9
9
  export { chatRepository } from './chat.repository';
10
- export { threadTable, type ThreadRow, type ThreadInsert, type ThreadUpdate, } from './thread.schema';
10
+ export { threadResource, threadTable, type ThreadRow, type ThreadInsert, type ThreadUpdate, } from './thread.schema';
11
11
  export { threadRepository } from './thread.repository';
12
- export { messageTable, type MessageRow, type MessageInsert, type MessageUpdate, } from './message.schema';
12
+ export { messageResource, messageTable, type MessageRow, type MessageInsert, type MessageUpdate, } from './message.schema';
13
13
  export { messageRepository } from './message.repository';
14
14
  export { MessageBlockType, MessageBlockStatus, type BaseMessageBlock, type PlaceholderMessageBlock, type MainTextMessageBlock, type ThinkingMessageBlock, type ImageMessageBlock, type CodeMessageBlock, type ToolMessageBlock, type FileMessageBlock, type ErrorMessageBlock, type CitationMessageBlock, type MessageBlock, type MessageRichContent, createMessageBlock, isBlockType, parseMessageBlocks, serializeMessageBlocks, } from './types/message-block';
15
15
  export { type ToolApprovalBlock, type ToolCallBlock, type TaskProgressBlock, type CollaborationRichBlock, type ToolRisk, type ToolApprovalStatus, type ToolCallStatus, type TaskProgressStepStatus, } from "./types/collaboration-blocks";
@@ -20,7 +20,7 @@ export { settingsTable, SETTING_KEYS, type SettingKey, type SettingsRow, type Se
20
20
  export { agentTable, type AgentRow, type AgentInsert, type AgentUpdate, } from './agent.schema';
21
21
  export { agentRepository } from './agent.repository';
22
22
  export { DEFAULT_AGENT_PROVIDERS, type AgentProviderMetadata, type AgentModelOption, } from './agent.providers';
23
- export { sessionTable, type SessionType, type SessionStatus, type SessionRow, type SessionInsert, type SessionUpdate, } from './session';
23
+ export { sessionResource, sessionTable, type SessionType, type SessionStatus, type SessionRow, type SessionInsert, type SessionUpdate, } from './session';
24
24
  export { sessionRepository } from './session.repository';
25
25
  export { approvalTable, type ApprovalRow, type ApprovalInsert, type ApprovalUpdate, } from './approval.schema';
26
26
  export { auditTable, type AuditRow, type AuditInsert, type AuditUpdate, } from './audit.schema';
@@ -36,8 +36,9 @@ export { aiProviderTable, type AIProviderRow, type AIProviderInsert, type AIProv
36
36
  export { aiModelTable, type AIModelRow, type AIModelInsert, type AIModelUpdate, } from "./ai-model.schema";
37
37
  export { aiConfigModelUri, aiConfigProviderUri, buildAIConfigMutationPlan, buildAIConfigProviderStateMap, getAIConfigDefaultBaseUrl, getAIConfigProviderCatalog, getAIConfigProviderFamilyIds, getAIConfigProviderMetadata, getDefaultAIConfigCredentialId, normalizeAIConfigProviderId, normalizeAIConfigResourceId, sameAIConfigProviderFamily, type AIConfigModel, type AIConfigMutationPlan, type AIConfigProviderCatalogEntry, type AIConfigProviderState, type AIConfigUpdate, type BuildAIConfigProviderStateMapOptions, } from './ai-config';
38
38
  export { buildAcpPermissionResponse, buildWatchThreadMetadata, buildWatchTranscriptMessages, buildWatchUserInputResponse, createWatchSessionId, detectWatchAuthFailure, formatWatchAutoFallbackMessage, formatWatchBackendAuthMessage, extractWatchSessionIdFromJsonLine, getWatchArchiveRelativePaths, getWatchAuthLoginCommand, looksLikeWatchAuthFailureText, normalizeAcpInteractionRequest, normalizeAcpRequest, normalizeAcpSessionNotification, normalizeCodexAppServerNotification, normalizeCodexAppServerRequest, normalizeWatchCredentialSource, parseWatchClaudeAuthStatus, parseWatchJsonLine, parseWatchJsonProtocolLine, resolveWatchAutoApprovalDecision, resolveWatchCredentialSourceResolution, resolveWatchInteractionAutoResponse, resolveWatchQuestionAnswer, shouldAttemptCloudCredentialProbe, WATCH_EVENTS_FILE_NAME, WATCH_HOME_DIRNAME, WATCH_SESSIONS_DIRNAME, WATCH_SESSION_FILE_NAME, type WatchApprovalDecision, type WatchApprovalRequest, type CreateWatchSessionIdOptions, type WatchAuthFailure, type WatchAuthState, type WatchAuthStatus, type WatchArchiveRelativePaths, type WatchBackend, type WatchCloudCredentialProbe, type WatchCloudCredentialProbeStatus, type WatchCredentialSource, type WatchCredentialSourceResolution, type WatchEventLogEntry, type WatchMode, type WatchNormalizedEvent, type WatchOutputStream, type WatchResolvedCredentialSource, type WatchRuntime, type WatchSessionRecord, type WatchSessionStatus, type WatchThreadMetadata, type WatchTranscriptMessage, type WatchTranscriptMessageRole, } from './watch';
39
+ export { applySolidComunicaPatches, } from './comunica-patches';
39
40
  export { createRepositoryDescriptor, definePodRepository, findPodRowByStorageId, initSolidTables, resolveRowId, resolvePodUri, whereByPodStorageId, type AnyPodTable, type PodRepositoryDescriptor, type RepositoryCacheOptions, type RepositoryInvalidations, type RepositoryScope, type SolidDatabase, } from './repository';
40
41
  export { importJobSchema } from './import';
41
42
  export { eq, ne, and, or, drizzle } from '@undefineds.co/drizzle-solid';
42
- export { solidSchema } from './schema';
43
+ export { solidResources, solidSchema } from './schema';
43
44
  export * from './discovery';
package/dist/index.js CHANGED
@@ -23,11 +23,11 @@ export * from './profile.schema.js';
23
23
  export { contactTable, ContactClass, ContactType, isAgentContact, isGroupContact, } from './contact.schema.js';
24
24
  export { contactRepository } from './contact.repository.js';
25
25
  // Chat & Message - 聊天和消息
26
- export { chatTable, } from './chat.schema.js';
26
+ export { chatResource, chatTable, } from './chat.schema.js';
27
27
  export { chatRepository } from './chat.repository.js';
28
- export { threadTable, } from './thread.schema.js';
28
+ export { threadResource, threadTable, } from './thread.schema.js';
29
29
  export { threadRepository } from './thread.repository.js';
30
- export { messageTable, } from './message.schema.js';
30
+ export { messageResource, messageTable, } from './message.schema.js';
31
31
  export { messageRepository } from './message.repository.js';
32
32
  // Message Block - 消息块类型系统 (Block-based Message System)
33
33
  export { MessageBlockType, MessageBlockStatus, createMessageBlock, isBlockType, parseMessageBlocks, serializeMessageBlocks, } from './types/message-block.js';
@@ -49,7 +49,7 @@ export { DEFAULT_AGENT_PROVIDERS, } from './agent.providers.js';
49
49
  // 其他模型
50
50
  // ============================================
51
51
  // Session - 会话管理
52
- export { sessionTable, } from './session/index.js';
52
+ export { sessionResource, sessionTable, } from './session/index.js';
53
53
  export { sessionRepository } from './session.repository.js';
54
54
  // Approval / Audit / Grant / Inbox Notification
55
55
  export { approvalTable, } from './approval.schema.js';
@@ -70,6 +70,7 @@ export { aiProviderTable, } from "./ai-provider.schema.js";
70
70
  export { aiModelTable, } from "./ai-model.schema.js";
71
71
  export { aiConfigModelUri, aiConfigProviderUri, buildAIConfigMutationPlan, buildAIConfigProviderStateMap, getAIConfigDefaultBaseUrl, getAIConfigProviderCatalog, getAIConfigProviderFamilyIds, getAIConfigProviderMetadata, getDefaultAIConfigCredentialId, normalizeAIConfigProviderId, normalizeAIConfigResourceId, sameAIConfigProviderFamily, } from './ai-config/index.js';
72
72
  export { buildAcpPermissionResponse, buildWatchThreadMetadata, buildWatchTranscriptMessages, buildWatchUserInputResponse, createWatchSessionId, detectWatchAuthFailure, formatWatchAutoFallbackMessage, formatWatchBackendAuthMessage, extractWatchSessionIdFromJsonLine, getWatchArchiveRelativePaths, getWatchAuthLoginCommand, looksLikeWatchAuthFailureText, normalizeAcpInteractionRequest, normalizeAcpRequest, normalizeAcpSessionNotification, normalizeCodexAppServerNotification, normalizeCodexAppServerRequest, normalizeWatchCredentialSource, parseWatchClaudeAuthStatus, parseWatchJsonLine, parseWatchJsonProtocolLine, resolveWatchAutoApprovalDecision, resolveWatchCredentialSourceResolution, resolveWatchInteractionAutoResponse, resolveWatchQuestionAnswer, shouldAttemptCloudCredentialProbe, WATCH_EVENTS_FILE_NAME, WATCH_HOME_DIRNAME, WATCH_SESSIONS_DIRNAME, WATCH_SESSION_FILE_NAME, } from './watch/index.js';
73
+ export { applySolidComunicaPatches, } from './comunica-patches.js';
73
74
  export { createRepositoryDescriptor, definePodRepository, findPodRowByStorageId, initSolidTables, resolveRowId, resolvePodUri, whereByPodStorageId, } from './repository.js';
74
75
  // Import Job - 导入任务
75
76
  export { importJobSchema } from './import/index.js';
@@ -80,7 +81,7 @@ export { eq, ne, and, or, drizzle } from '@undefineds.co/drizzle-solid';
80
81
  // ============================================
81
82
  // Schema registry
82
83
  // ============================================
83
- export { solidSchema } from './schema.js';
84
+ export { solidResources, solidSchema } from './schema.js';
84
85
  // ============================================
85
86
  // Discovery Service (发现服务)
86
87
  // ============================================
@@ -1,11 +1,37 @@
1
1
  /**
2
- * Message schema (aligned with xpod).
2
+ * Message resource (aligned with xpod).
3
+ *
4
+ * Product semantics:
5
+ * - Message belongs to both a Chat counterpart and a concrete Thread timeline.
6
+ * - Chat answers "who/what is this conversation with".
7
+ * - Thread answers "which run/timeline/place does this message belong to".
3
8
  *
4
9
  * Storage structure:
5
- * - Location: /.data/chat/{chat}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
10
+ * - Location: /.data/chat/{chat|id}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
6
11
  * - Date-based path for efficient time-range queries
7
12
  * - chat/thread are RDF URI relations. Short ids remain accepted at API/query call sites via ORM URI template resolution.
8
13
  */
14
+ export declare const messageResource: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
15
+ id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
16
+ chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
17
+ thread: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
18
+ maker: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
19
+ role: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
20
+ content: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
21
+ richContent: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
22
+ status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, true>;
23
+ replacedBy: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
24
+ deletedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
25
+ senderName: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
26
+ senderAvatarUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
27
+ mentions: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"array", "uri", false, false>;
28
+ replyTo: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
29
+ routedBy: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
30
+ routeTargetAgentId: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
31
+ coordinationId: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
32
+ createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
33
+ updatedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
34
+ }>>;
9
35
  export declare const messageTable: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
10
36
  id: import("@undefineds.co/drizzle-solid/dist/core/schema").PodStringColumn<false, false>;
11
37
  chat: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, true, false>;
@@ -27,6 +53,6 @@ export declare const messageTable: import("@undefineds.co/drizzle-solid/dist/cor
27
53
  createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, true, true>;
28
54
  updatedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
29
55
  }>>;
30
- export type MessageRow = typeof messageTable.$inferSelect;
31
- export type MessageInsert = typeof messageTable.$inferInsert;
32
- export type MessageUpdate = typeof messageTable.$inferUpdate;
56
+ export type MessageRow = typeof messageResource.$inferSelect;
57
+ export type MessageInsert = typeof messageResource.$inferInsert;
58
+ export type MessageUpdate = typeof messageResource.$inferUpdate;
@@ -1,20 +1,26 @@
1
1
  import { podTable, uri, string, text, timestamp, id } from '@undefineds.co/drizzle-solid';
2
2
  import { UDFS, DCTerms, FOAF, LINX_MSG, MEETING, SCHEMA, SIOC, WF } from './namespaces.js';
3
- import { threadTable } from './thread.schema.js';
3
+ import { chatResource } from './chat.schema.js';
4
+ import { threadResource } from './thread.schema.js';
4
5
  /**
5
- * Message schema (aligned with xpod).
6
+ * Message resource (aligned with xpod).
7
+ *
8
+ * Product semantics:
9
+ * - Message belongs to both a Chat counterpart and a concrete Thread timeline.
10
+ * - Chat answers "who/what is this conversation with".
11
+ * - Thread answers "which run/timeline/place does this message belong to".
6
12
  *
7
13
  * Storage structure:
8
- * - Location: /.data/chat/{chat}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
14
+ * - Location: /.data/chat/{chat|id}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
9
15
  * - Date-based path for efficient time-range queries
10
16
  * - chat/thread are RDF URI relations. Short ids remain accepted at API/query call sites via ORM URI template resolution.
11
17
  */
12
- export const messageTable = podTable('chat_message', {
18
+ export const messageResource = podTable('chat_message', {
13
19
  id: id('id'),
14
20
  // Chat relation. In RDF this is an inverse Solid Chat link: <chat> wf:message <message>.
15
- chat: uri('chat').predicate(WF.message).inverse().notNull().link('chats'),
21
+ chat: uri('chat').predicate(WF.message).inverse().notNull().link(chatResource),
16
22
  // Thread relation. In RDF this is an inverse Solid Chat/SIOC link: <thread> sioc:has_member <message>.
17
- thread: uri('thread').predicate(SIOC.has_member).inverse().notNull().link(threadTable),
23
+ thread: uri('thread').predicate(SIOC.has_member).inverse().notNull().link(threadResource),
18
24
  // maker is the entity URI of the message author:
19
25
  // - User: their WebID (https://user.pod/profile/card#me)
20
26
  // - AI: Agent URI (/.data/agents/{id}.ttl#this)
@@ -43,5 +49,7 @@ export const messageTable = podTable('chat_message', {
43
49
  sparqlEndpoint: '/.data/chat/-/sparql',
44
50
  type: MEETING.Message,
45
51
  namespace: UDFS,
46
- subjectTemplate: '{chat}/{yyyy}/{MM}/{dd}/messages.ttl#{id}',
52
+ subjectTemplate: '{chat|id}/{yyyy}/{MM}/{dd}/messages.ttl#{id}',
47
53
  });
54
+ // Compatibility alias. New model code should prefer `messageResource`.
55
+ export const messageTable = messageResource;
package/dist/profile.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { SolidProfileRow } from "./profile.schema.js";
2
2
  import { type SolidProfileIdentity } from "./profile.repository.js";
3
3
  export { pickSolidProfileDisplayName, profileRepository, type SolidProfileIdentity, } from "./profile.repository.js";
4
- type NodeRequire = (id: string) => unknown;
5
4
  export interface SolidProfileSessionLike {
6
5
  info?: {
7
6
  webId?: string;
@@ -12,11 +11,19 @@ export interface SolidProfileReader<TTable = unknown> {
12
11
  findByIri(table: TTable, iri: string): Promise<unknown | null>;
13
12
  }
14
13
  export declare function createSolidProfileDatabase(session: unknown): Promise<SolidProfileReader>;
15
- export declare function applySolidProfileComunicaPatches(requireModule?: NodeRequire): Promise<boolean>;
14
+ export declare function applySolidProfileComunicaPatches(): boolean;
16
15
  export declare function resolveSolidProfile(db: SolidProfileReader, webId: string): Promise<SolidProfileRow | null>;
17
16
  export declare function resolveSolidProfileWithTable<TTable>(db: SolidProfileReader<TTable>, webId: string, table: TTable): Promise<SolidProfileRow | null>;
18
17
  export declare function resolveSolidProfileDisplayName(db: SolidProfileReader, webId: string): Promise<string | null>;
19
18
  export declare function resolveSolidProfileIdentityWithReader(db: SolidProfileReader, webId: string): Promise<SolidProfileIdentity | null>;
19
+ export declare function resolveSolidProfileIdentityFromWebIdDocument(session: SolidProfileSessionLike, options?: {
20
+ webId?: string;
21
+ }): Promise<SolidProfileIdentity | null>;
20
22
  export declare function resolveSolidProfileIdentity(session: SolidProfileSessionLike, options?: {
21
23
  webId?: string;
22
24
  }): Promise<SolidProfileIdentity | null>;
25
+ export declare function parseSolidProfileDocument(source: string, options: {
26
+ contentType?: string;
27
+ profileDocumentUrl: string;
28
+ webId: string;
29
+ }): Promise<SolidProfileRow | null>;