docz-cli 0.9.0 → 0.10.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts","../src/collab/text.ts","../src/collab/types.ts","../src/collab/room.ts","../src/collab/roomName.ts","../src/config.ts","../src/commands.ts","../src/collab/bridge.ts"],"sourcesContent":["/**\n * DocSync API Client\n *\n * DocSync 底层是 Git 仓库,每个 Space = 一个 Git repo。\n * 认证:Authorization: Bearer {token}(支持 JWT 和永久 API Token)。\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface Space {\n id: string;\n name: string;\n slug?: string;\n owner_id: string;\n is_private: boolean;\n created_at: string;\n member_count: number;\n}\n\nexport interface TreeEntry {\n name: string;\n type: 'blob' | 'tree';\n size: number;\n}\n\nexport interface LogEntry {\n hash: string;\n author: string;\n message: string;\n date: string;\n num_files: number;\n}\n\nexport interface TrashEntry {\n path: string;\n deleted_by: string;\n deleted_at: string;\n commit: string;\n}\n\nexport interface User {\n id: string;\n email: string;\n name: string;\n is_admin: boolean;\n is_active: boolean;\n created_at: string;\n}\n\nexport interface ShareLink {\n id: string;\n token: string;\n space_id: string;\n file_path: string;\n created_by: string;\n created_by_name?: string;\n created_by_email?: string;\n expires_at: string | null;\n created_at: string;\n user_ids?: string[];\n group_ids?: string[];\n}\n\nexport interface ShareFileInfo {\n file_path: string;\n file_name: string;\n space_name: string;\n created_by_name: string;\n expires_at: string | null;\n}\n\nexport interface DiffResponse {\n from: string;\n to: string;\n path: string;\n diff: string;\n old_body: string;\n new_body: string;\n}\n\nexport interface DiffFileEntry {\n path: string;\n status: string;\n}\n\nexport interface DiffSummary {\n from: string;\n to: string;\n files: DiffFileEntry[];\n}\n\nexport interface FileRef {\n id: string;\n space_id: string;\n path: string;\n}\n\nexport interface CatResult {\n content: string;\n ref: string;\n}\n\nexport interface UploadImageResult {\n url: string;\n object_key: string;\n content_type: string;\n size: number;\n}\n\nexport interface SaveResult {\n path: string;\n ref: string;\n}\n\nexport interface SaveConflict {\n error: 'conflict';\n current_ref: string;\n path: string;\n}\n\nexport interface Comment {\n id: number;\n space_id: string;\n file_path: string;\n comment_type: string;\n target_type: string;\n target_selector: string;\n target_content: string;\n content: string;\n user_id: string;\n user_name: string;\n user_email: string;\n is_closed: boolean;\n created_at: string;\n updated_at: string;\n replies: CommentReply[];\n}\n\nexport interface CommentReply {\n id: number;\n comment_id: number;\n content: string;\n user_id: string;\n user_name: string;\n user_email: string;\n created_at: string;\n updated_at: string;\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\nexport class ConflictError extends Error {\n constructor(public readonly detail: SaveConflict) {\n super(\n 'Conflict: file has been modified by others. Please re-read the latest content and re-apply your changes.'\n );\n this.name = 'ConflictError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\nexport class DocSyncClient {\n constructor(\n private baseUrl: string,\n private token: string\n ) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${this.token}`,\n ...init?.headers,\n },\n });\n\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw new Error(`${res.status} ${res.statusText}: ${body}`.trim());\n }\n\n const ct = res.headers.get('content-type') ?? '';\n if (ct.includes('application/json')) return res.json() as Promise<T>;\n return res.text() as unknown as T;\n }\n\n private async requestText(path: string, init?: RequestInit): Promise<string> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n ...init,\n headers: {\n Authorization: `Bearer ${this.token}`,\n ...init?.headers,\n },\n });\n\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw new Error(`${res.status} ${res.statusText}: ${body}`.trim());\n }\n\n return res.text();\n }\n\n // --- Auth ---\n async me(): Promise<User> {\n return this.request('/api/auth/me');\n }\n\n // --- Spaces ---\n async listSpaces(): Promise<Space[]> {\n return this.request('/api/spaces');\n }\n\n async resolveSpace(nameOrId: string): Promise<Space> {\n const spaces = await this.listSpaces();\n const input = nameOrId.toLowerCase();\n\n // 1-3: exact id / exact name / case-insensitive name\n const exact = spaces.find(\n (s) =>\n s.id === nameOrId ||\n s.name === nameOrId ||\n s.name.toLowerCase() === input\n );\n if (exact) return exact;\n\n // 4: slug exact match\n const bySlug = spaces.find((s) => s.slug === nameOrId);\n if (bySlug) return bySlug;\n\n // 5: name suffix match (e.g. \"研发\" matches \"G160-研发\")\n const suffixMatches = spaces.filter(\n (s) =>\n s.name.length > nameOrId.length && s.name.toLowerCase().endsWith(input)\n );\n if (suffixMatches.length === 1) return suffixMatches[0];\n if (suffixMatches.length > 1) {\n const candidates = suffixMatches.map((s) => s.name).join(', ');\n throw new Error(\n `Space \"${nameOrId}\" is ambiguous, matches: ${candidates}. Use the full name or UUID.`\n );\n }\n\n const available = spaces\n .map((s) => (s.slug ? `${s.name} (${s.slug})` : s.name))\n .join(', ');\n throw new Error(`Space \"${nameOrId}\" not found. Available: ${available}`);\n }\n\n // --- Tree ---\n async ls(spaceId: string, path = ''): Promise<TreeEntry[]> {\n return this.request(\n `/api/spaces/${spaceId}/tree?path=${encodeURIComponent(path)}`\n );\n }\n\n async treeFull(spaceId: string): Promise<TreeEntry[]> {\n return this.request(`/api/spaces/${spaceId}/tree/full`);\n }\n\n // --- Blob ---\n async cat(spaceId: string, filepath: string): Promise<string> {\n return this.requestText(\n `/api/spaces/${spaceId}/blob/${encodeURIComponent(filepath)}`\n );\n }\n\n async catWithRef(spaceId: string, filepath: string): Promise<CatResult> {\n const res = await fetch(\n `${this.baseUrl}/api/spaces/${spaceId}/blob/${encodeURIComponent(filepath)}`,\n { headers: { Authorization: `Bearer ${this.token}` } }\n );\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw new Error(`${res.status} ${res.statusText}: ${body}`.trim());\n }\n const content = await res.text();\n const ref = res.headers.get('X-Git-Ref') ?? '';\n return { content, ref };\n }\n\n // --- Write ---\n async upload(\n spaceId: string,\n dir: string,\n filename: string,\n content: string | Buffer\n ): Promise<{ path: string }> {\n const blob =\n typeof content === 'string'\n ? new Blob([content], { type: 'application/octet-stream' })\n : new Blob([content], { type: 'application/octet-stream' });\n const form = new FormData();\n form.append('file', blob, filename);\n form.append('path', dir);\n return this.request(`/api/spaces/${spaceId}/files/upload`, {\n method: 'POST',\n body: form,\n });\n }\n\n /**\n * Upload an image to the server's OSS asset storage.\n * Returns a permanent public URL that can be embedded in Markdown.\n * Server limits: png/jpg/webp only, max 5MB.\n */\n async uploadImage(\n content: Buffer,\n filename: string\n ): Promise<UploadImageResult> {\n const blob = new Blob([content], { type: 'application/octet-stream' });\n const form = new FormData();\n form.append('file', blob, filename);\n return this.request('/api/assets/images', {\n method: 'POST',\n body: form,\n });\n }\n\n async save(\n spaceId: string,\n path: string,\n content: string,\n opts?: { baseRef?: string; message?: string }\n ): Promise<SaveResult> {\n const body: Record<string, string> = { path, content };\n if (opts?.baseRef) body.base_ref = opts.baseRef;\n if (opts?.message) body.message = opts.message;\n\n const res = await fetch(\n `${this.baseUrl}/api/spaces/${spaceId}/files/save`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n }\n );\n\n if (res.status === 409) {\n const data = (await res.json()) as SaveConflict;\n throw new ConflictError(data);\n }\n\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`${res.status} ${res.statusText}: ${text}`.trim());\n }\n\n return res.json() as Promise<SaveResult>;\n }\n\n async mkdir(spaceId: string, path: string): Promise<void> {\n await this.request(`/api/spaces/${spaceId}/files/mkdir`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path }),\n });\n }\n\n async rm(spaceId: string, path: string): Promise<void> {\n await this.request(`/api/spaces/${spaceId}/files/delete`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path }),\n });\n }\n\n async mv(spaceId: string, from: string, to: string): Promise<void> {\n await this.request(`/api/spaces/${spaceId}/files/rename`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ old_path: from, new_path: to }),\n });\n }\n\n async rollback(\n spaceId: string,\n filePath: string,\n commitHash: string\n ): Promise<void> {\n await this.request(`/api/spaces/${spaceId}/files/rollback`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ file_path: filePath, commit_hash: commitHash }),\n });\n }\n\n // --- History ---\n async log(spaceId: string, filepath?: string): Promise<LogEntry[]> {\n const path = filepath\n ? `/api/spaces/${spaceId}/log/${encodeURIComponent(filepath)}`\n : `/api/spaces/${spaceId}/log/`;\n return this.request(path);\n }\n\n // --- Trash ---\n async trash(spaceId: string): Promise<TrashEntry[]> {\n return this.request(`/api/spaces/${spaceId}/trash`);\n }\n\n async restore(spaceId: string, path: string, commit: string): Promise<void> {\n await this.request(`/api/spaces/${spaceId}/trash/restore`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, commit }),\n });\n }\n\n // --- Comments ---\n async listComments(spaceId: string, filePath: string): Promise<Comment[]> {\n return this.request(\n `/api/spaces/${spaceId}/comments?path=${encodeURIComponent(filePath)}`\n );\n }\n\n async createComment(\n spaceId: string,\n filePath: string,\n content: string,\n opts?: { quote?: string }\n ): Promise<Comment> {\n const body: Record<string, string> = { file_path: filePath, content };\n if (opts?.quote) {\n body.comment_type = 'text';\n body.target_type = 'selection';\n body.target_content = opts.quote;\n body.target_selector = JSON.stringify({\n startOffset: 0,\n endOffset: 0,\n text: opts.quote,\n prefix: '',\n suffix: '',\n });\n }\n return this.request(`/api/spaces/${spaceId}/comments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n }\n\n async replyComment(\n spaceId: string,\n commentId: number,\n content: string\n ): Promise<CommentReply> {\n return this.request(\n `/api/spaces/${spaceId}/comments/${commentId}/replies`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ content }),\n }\n );\n }\n\n async closeComment(spaceId: string, commentId: number): Promise<Comment> {\n return this.request(`/api/spaces/${spaceId}/comments/${commentId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ is_closed: true }),\n });\n }\n\n async deleteComment(spaceId: string, commentId: number): Promise<void> {\n await this.request(`/api/spaces/${spaceId}/comments/${commentId}`, {\n method: 'DELETE',\n });\n }\n\n // --- Share Links ---\n async createShareLink(\n spaceId: string,\n filePath: string,\n opts?: { expiresAt?: string; userIds?: string[]; groupIds?: string[] }\n ): Promise<ShareLink> {\n const body: Record<string, unknown> = { file_path: filePath };\n if (opts?.expiresAt) body.expires_at = opts.expiresAt;\n if (opts?.userIds?.length) body.user_ids = opts.userIds;\n if (opts?.groupIds?.length) body.group_ids = opts.groupIds;\n return this.request(`/api/spaces/${spaceId}/share-links`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n }\n\n async listShareLinks(\n spaceId: string,\n filePath?: string\n ): Promise<ShareLink[]> {\n const q = filePath ? `?file_path=${encodeURIComponent(filePath)}` : '';\n return this.request(`/api/spaces/${spaceId}/share-links${q}`);\n }\n\n async updateShareLink(\n spaceId: string,\n linkId: string,\n opts: { expiresAt?: string; userIds?: string[]; groupIds?: string[] }\n ): Promise<ShareLink> {\n const body: Record<string, unknown> = {};\n if (opts.expiresAt !== undefined) body.expires_at = opts.expiresAt;\n if (opts.userIds) body.user_ids = opts.userIds;\n if (opts.groupIds) body.group_ids = opts.groupIds;\n return this.request(`/api/spaces/${spaceId}/share-links/${linkId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n }\n\n async deleteShareLink(spaceId: string, linkId: string): Promise<void> {\n await this.request(`/api/spaces/${spaceId}/share-links/${linkId}`, {\n method: 'DELETE',\n });\n }\n\n async getSharedFile(token: string): Promise<string> {\n return this.requestText(`/api/share/${token}`);\n }\n\n async getSharedFileInfo(token: string): Promise<ShareFileInfo> {\n return this.request(`/api/share/${token}/info`);\n }\n\n // --- Diff ---\n async diffFile(\n spaceId: string,\n filePath: string,\n to: string,\n from?: string\n ): Promise<DiffResponse> {\n const params = new URLSearchParams({ to });\n if (from) params.set('from', from);\n return this.request(\n `/api/spaces/${spaceId}/diff/${encodeURIComponent(filePath)}?${params}`\n );\n }\n\n async diffSummary(\n spaceId: string,\n to: string,\n from?: string\n ): Promise<DiffSummary> {\n const params = new URLSearchParams({ to });\n if (from) params.set('from', from);\n return this.request(`/api/spaces/${spaceId}/diff?${params}`);\n }\n\n // --- File Ref ---\n async getFileRef(\n spaceId: string,\n path: string\n ): Promise<{\n id: string;\n space_id: string;\n slug: string;\n path: string;\n is_dir: boolean;\n url: string;\n }> {\n return this.request(\n `/api/spaces/${spaceId}/file-ref?path=${encodeURIComponent(path)}`\n );\n }\n\n // --- Resolve short URLs ---\n async resolveBySlug(slug: string): Promise<Space> {\n return this.request(`/api/spaces/by-slug/${encodeURIComponent(slug)}`);\n }\n\n async resolveFileRef(fileId: string): Promise<FileRef> {\n return this.request(`/api/file-refs/${encodeURIComponent(fileId)}`);\n }\n}\n","import { createHash } from 'node:crypto';\nimport type * as Y from 'yjs';\n\nexport function collabHash(content: string): string {\n return `sha256:${createHash('sha256').update(content, 'utf8').digest('hex')}`;\n}\n\nexport class CollabConflictError extends Error {\n constructor(\n public readonly currentHash: string,\n public readonly baseHash: string\n ) {\n super(\n `collaborative document changed since base_collab_hash (current: ${currentHash}, base: ${baseHash})`\n );\n this.name = 'CollabConflictError';\n }\n}\n\nexport class CollabBaseHashRequiredError extends Error {\n constructor(public readonly currentHash: string) {\n super(\n `base_collab_hash is required unless force is explicitly enabled (current: ${currentHash})`\n );\n this.name = 'CollabBaseHashRequiredError';\n }\n}\n\nexport function getYText(doc: Y.Doc): Y.Text {\n return doc.getText('content');\n}\n\nexport function readText(doc: Y.Doc): string {\n return getYText(doc).toString();\n}\n\nexport function replaceText(\n doc: Y.Doc,\n nextContent: string,\n opts: { baseHash?: string; force?: boolean; origin?: unknown } = {}\n): { previousHash: string; hash: string } {\n const ytext = getYText(doc);\n const previous = ytext.toString();\n const previousHash = collabHash(previous);\n const baseHash = opts.baseHash;\n if (!opts.force) {\n if (!baseHash) {\n throw new CollabBaseHashRequiredError(previousHash);\n }\n if (previousHash !== baseHash) {\n throw new CollabConflictError(previousHash, baseHash);\n }\n }\n\n doc.transact(() => {\n ytext.delete(0, ytext.length);\n if (nextContent) ytext.insert(0, nextContent);\n }, opts.origin ?? 'docz-cli');\n\n return { previousHash, hash: collabHash(nextContent) };\n}\n","export interface CollabTarget {\n spaceId: string;\n path: string;\n}\n\nexport interface CollabOpenOptions extends CollabTarget {\n baseUrl: string;\n token: string;\n client: string;\n clientVersion: string;\n timeoutMs?: number;\n}\n\nexport interface CollabReadResult extends CollabTarget {\n content: string;\n collabHash: string;\n connected: boolean;\n readOnly: boolean;\n}\n\nexport interface CollabWriteResult extends CollabTarget {\n previousHash: string;\n collabHash: string;\n}\n\nexport interface CollabPublishResult extends CollabTarget {\n ref: string;\n contentRef: string;\n externalBackup: string;\n}\n\nexport class CollabUnknownError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CollabUnknownError';\n }\n}\n\nexport class CollabPublishError extends Error {\n constructor(\n message: string,\n public readonly code?: string\n ) {\n super(message);\n this.name = 'CollabPublishError';\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n HocuspocusProvider,\n HocuspocusProviderWebsocket,\n} from '@hocuspocus/provider';\nimport WebSocket from 'ws';\nimport * as Y from 'yjs';\nimport {\n buildCollabDocumentName,\n normalizeCollabFilePath,\n} from './roomName.js';\nimport { collabHash, readText, replaceText } from './text.js';\nimport {\n type CollabOpenOptions,\n CollabPublishError,\n type CollabPublishResult,\n type CollabReadResult,\n CollabUnknownError,\n type CollabWriteResult,\n} from './types.js';\n\ntype PublishAck = {\n type?: string;\n reqId?: string;\n ref?: string;\n content_ref?: string;\n external_backup?: string;\n code?: string;\n};\n\ntype PendingPublish = {\n resolve: (value: CollabPublishResult) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n};\n\ntype OpenedCollabOptions = CollabOpenOptions & {\n timeoutMs: number;\n};\n\nfunction wsUrl(baseUrl: string): string {\n const u = new URL(baseUrl);\n u.protocol = u.protocol === 'https:' ? 'wss:' : 'ws:';\n u.pathname = '/collab';\n u.search = '';\n u.hash = '';\n return u.toString();\n}\n\nfunction withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n label: string\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<T>((_, reject) => {\n timer = setTimeout(\n () => reject(new CollabUnknownError(`${label} timed out after ${ms}ms`)),\n ms\n );\n });\n return Promise.race([promise, timeout]).finally(() => {\n if (timer) clearTimeout(timer);\n });\n}\n\nexport class CollabRoomClient {\n readonly doc = new Y.Doc();\n private provider: HocuspocusProvider | null = null;\n private websocketProvider: HocuspocusProviderWebsocket | null = null;\n private openOptions: OpenedCollabOptions | null = null;\n private pending = new Map<string, PendingPublish>();\n private connected = false;\n private synced = false;\n private readOnly = false;\n\n async open(options: CollabOpenOptions): Promise<CollabReadResult> {\n const openOptions = {\n ...options,\n path: normalizeCollabFilePath(options.path),\n timeoutMs: options.timeoutMs ?? 30000,\n };\n this.openOptions = openOptions;\n\n const opened = new Promise<void>((resolve, reject) => {\n const websocketProvider = new HocuspocusProviderWebsocket({\n url: wsUrl(openOptions.baseUrl),\n WebSocketPolyfill: WebSocket,\n parameters: {\n space_id: openOptions.spaceId,\n file_path: openOptions.path,\n client: openOptions.client,\n client_version: openOptions.clientVersion,\n },\n });\n this.websocketProvider = websocketProvider;\n const provider = new HocuspocusProvider({\n websocketProvider,\n name: buildCollabDocumentName(openOptions.spaceId, openOptions.path),\n document: this.doc,\n token: () => openOptions.token,\n onAuthenticated: () => {},\n onAuthenticationFailed: (data) => {\n reject(\n new CollabPublishError(\n `collab authentication failed: ${data.reason}`,\n 'auth_failed'\n )\n );\n },\n onStatus: ({ status }) => {\n this.connected = status === 'connected';\n },\n onSynced: ({ state }) => {\n this.synced = state;\n if (state) resolve();\n },\n onStateless: ({ payload }) => {\n this.handleStateless(payload);\n },\n onDisconnect: () => {\n this.connected = false;\n },\n });\n this.provider = provider;\n });\n\n await withTimeout(opened, openOptions.timeoutMs, 'collab open');\n return this.read();\n }\n\n read(): CollabReadResult {\n if (!this.openOptions) throw new Error('collab room is not open');\n const content = readText(this.doc);\n return {\n spaceId: this.openOptions.spaceId,\n path: this.openOptions.path,\n content,\n collabHash: collabHash(content),\n connected: this.connected && this.synced,\n readOnly: this.readOnly,\n };\n }\n\n write(\n content: string,\n opts: { baseHash?: string; force?: boolean } = {}\n ): CollabWriteResult {\n if (!this.openOptions) throw new Error('collab room is not open');\n if (this.readOnly)\n throw new CollabPublishError('collab room is read-only', 'read_only');\n const result = replaceText(this.doc, content, {\n baseHash: opts.baseHash,\n force: opts.force,\n origin: this.openOptions.client,\n });\n return {\n spaceId: this.openOptions.spaceId,\n path: this.openOptions.path,\n previousHash: result.previousHash,\n collabHash: result.hash,\n };\n }\n\n async publish(timeoutMs?: number): Promise<CollabPublishResult> {\n if (!this.provider || !this.openOptions)\n throw new Error('collab room is not open');\n const reqId = randomUUID();\n const ms = timeoutMs ?? this.openOptions.timeoutMs ?? 30000;\n\n const result = new Promise<CollabPublishResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(reqId);\n reject(\n new CollabUnknownError(`collab publish ack timed out after ${ms}ms`)\n );\n }, ms);\n this.pending.set(reqId, { resolve, reject, timer });\n });\n\n this.provider.sendStateless(\n JSON.stringify({\n type: 'publish',\n reqId,\n client: this.openOptions.client,\n client_version: this.openOptions.clientVersion,\n })\n );\n return result;\n }\n\n close(): void {\n for (const [reqId, pending] of this.pending) {\n clearTimeout(pending.timer);\n pending.reject(\n new CollabUnknownError('collab room closed before publish ack')\n );\n this.pending.delete(reqId);\n }\n this.provider?.destroy();\n this.websocketProvider?.destroy();\n this.provider = null;\n this.websocketProvider = null;\n this.doc.destroy();\n }\n\n private handleStateless(payload: string): void {\n let msg: PublishAck;\n try {\n msg = JSON.parse(payload) as PublishAck;\n } catch {\n return;\n }\n if (!msg.reqId) return;\n const pending = this.pending.get(msg.reqId);\n if (!pending) return;\n this.pending.delete(msg.reqId);\n clearTimeout(pending.timer);\n\n if (\n msg.type === 'publish_ack' ||\n msg.type === 'recreate_after_delete_ack'\n ) {\n if (!this.openOptions) {\n pending.reject(\n new CollabUnknownError('collab room closed before publish ack')\n );\n return;\n }\n pending.resolve({\n spaceId: this.openOptions.spaceId,\n path: this.openOptions.path,\n ref: msg.ref || '',\n contentRef: msg.content_ref || '',\n externalBackup: msg.external_backup || '',\n });\n return;\n }\n\n pending.reject(\n new CollabPublishError(\n `collab publish failed${msg.code ? `: ${msg.code}` : ''}`,\n msg.code\n )\n );\n }\n}\n\nexport async function withCollabRoom<T>(\n options: CollabOpenOptions,\n fn: (room: CollabRoomClient) => Promise<T>\n): Promise<T> {\n const room = new CollabRoomClient();\n try {\n await room.open(options);\n return await fn(room);\n } finally {\n room.close();\n }\n}\n","function decodePath(path: string): string {\n try {\n return decodeURIComponent(path);\n } catch {\n return path;\n }\n}\n\nexport function normalizeCollabFilePath(path: string): string {\n const decoded = decodePath(path.trim()).replace(/\\\\/g, '/');\n const parts: string[] = [];\n\n for (const part of decoded.split('/')) {\n if (!part || part === '.') continue;\n if (part === '..') throw new Error('invalid collab file path');\n parts.push(part);\n }\n\n return parts.join('/');\n}\n\nexport function buildCollabDocumentName(\n spaceId: string,\n filePath: string\n): string {\n const sid = spaceId.trim();\n const normalizedPath = normalizeCollabFilePath(filePath);\n if (!sid || !normalizedPath)\n throw new Error('space id and file path are required');\n return `${sid}:${normalizedPath}`;\n}\n","/**\n * 配置管理\n *\n * 优先级:环境变量 > ~/.docz/config.json\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst CONFIG_DIR = join(homedir(), '.docz');\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.json');\n\ninterface Config {\n base_url?: string;\n token?: string;\n}\n\nfunction readConfig(): Config {\n if (!existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));\n } catch {\n return {};\n }\n}\n\nfunction writeConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n writeFileSync(CONFIG_FILE, `${JSON.stringify(config, null, 2)}\\n`);\n}\n\nexport function getBaseUrl(): string {\n return (\n process.env.DOCSYNC_BASE_URL ??\n readConfig().base_url ??\n 'https://docz.zhenguanyu.com'\n );\n}\n\nexport function getToken(): string | undefined {\n return process.env.DOCSYNC_API_TOKEN ?? readConfig().token;\n}\n\nexport function saveConfig(baseUrl: string, token: string): void {\n writeConfig({ base_url: baseUrl, token });\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","/**\n * CLI Commands\n */\n\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { basename } from 'node:path';\nimport type { Command } from 'commander';\nimport { ConflictError, DocSyncClient } from './client.js';\nimport { startCollabBridge } from './collab/bridge.js';\nimport { CollabRoomClient, withCollabRoom } from './collab/room.js';\nimport {\n CollabBaseHashRequiredError,\n CollabConflictError,\n} from './collab/text.js';\nimport { type CollabOpenOptions, CollabUnknownError } from './collab/types.js';\nimport { getBaseUrl, getConfigPath, getToken, saveConfig } from './config.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ndeclare const __VERSION__: string;\n\nfunction getClient(): DocSyncClient {\n const token = getToken();\n if (!token) {\n console.error(\n 'Error: No token configured.\\n' +\n 'Run `docz login` or set DOCSYNC_API_TOKEN environment variable.'\n );\n process.exit(1);\n }\n return new DocSyncClient(getBaseUrl(), token);\n}\n\nfunction getRequiredToken(): string {\n const token = getToken();\n if (!token) {\n console.error(\n 'Error: No token configured.\\n' +\n 'Run `docz login` or set DOCSYNC_API_TOKEN environment variable.'\n );\n process.exit(1);\n }\n return token;\n}\n\nasync function buildCollabOpenOptions(\n target: string,\n opts: { client?: string; clientVersion?: string; timeout?: number } = {}\n): Promise<CollabOpenOptions> {\n const api = getClient();\n const { spaceId, path } = await resolveTarget(api, [target]);\n if (!path) {\n throw new Error('file path is required for collaborative editing');\n }\n return {\n baseUrl: getBaseUrl(),\n token: getRequiredToken(),\n spaceId,\n path,\n client: opts.client ?? 'docz-cli',\n clientVersion: opts.clientVersion ?? __VERSION__,\n timeoutMs: opts.timeout,\n };\n}\n\n/** Parse \"space:path\" or \"space path\" format */\nexport function parseTarget(args: string[]): { space: string; path: string } {\n if (args.length === 0) {\n console.error(\n 'Error: space is required. Usage: docz <cmd> <space>[:<path>]'\n );\n process.exit(1);\n }\n const first = args[0];\n if (first.includes(':')) {\n const [space, ...rest] = first.split(':');\n return { space, path: rest.join(':') };\n }\n return { space: first, path: args.slice(1).join(' ') };\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n// Share URL: /share/{token}\nconst SHARE_URL_RE = /\\/share\\/([^/?\\s]+)/;\n\n/** Resolve slug: try local spaces cache first, then API */\nasync function resolveSlug(\n client: DocSyncClient,\n slug: string\n): Promise<{ id: string }> {\n try {\n const spaces = await client.listSpaces();\n const found = spaces.find((s) => s.slug === slug);\n if (found) return found;\n } catch {\n // fall through to by-slug API\n }\n return client.resolveBySlug(slug);\n}\n\n/**\n * Detect if input is a URL and resolve it to { spaceId, path }.\n * Supports:\n * /s/{slug}/f/{fileId} — short URL with fileId\n * /s/{slug}[/path/to/file] — slug URL with optional path\n * /spaces/{spaceId}[/path/...] — legacy URL\n * Returns null if not a recognized DocSync URL.\n */\nasync function resolveUrl(\n client: DocSyncClient,\n input: string\n): Promise<{ spaceId: string; path: string } | null> {\n let pathname: string;\n try {\n pathname = new URL(input).pathname;\n } catch {\n return null;\n }\n\n // /s/{slug}/f/{fileId}\n const fileMatch = pathname.match(/^\\/s\\/([^/]+)\\/f\\/([^/]+)$/);\n if (fileMatch) {\n const [, slug, fileId] = fileMatch;\n const space = await resolveSlug(client, slug);\n const ref = await client.resolveFileRef(fileId);\n return { spaceId: space.id, path: ref.path };\n }\n\n // /s/{slug}[/path/to/file]\n const slugMatch = pathname.match(/^\\/s\\/([^/]+)(\\/.*)?$/);\n if (slugMatch) {\n const [, slug, rest] = slugMatch;\n const space = await resolveSlug(client, slug);\n const filePath = rest ? decodeURIComponent(rest.slice(1)) : '';\n return { spaceId: space.id, path: filePath };\n }\n\n // /spaces/{spaceId}[/path/to/file] (legacy)\n const legacyMatch = pathname.match(/^\\/spaces\\/([^/]+)(\\/.*)?$/);\n if (legacyMatch) {\n const [, spaceId, rest] = legacyMatch;\n const filePath = rest ? decodeURIComponent(rest.slice(1)) : '';\n return { spaceId, path: filePath };\n }\n\n return null;\n}\n\n/**\n * Resolve target: if it's a URL, resolve it; otherwise use parseTarget + resolveSpace.\n */\nexport async function resolveTarget(\n client: DocSyncClient,\n args: string[]\n): Promise<{ spaceId: string; path: string }> {\n const first = args[0];\n if (first && (first.startsWith('http://') || first.startsWith('https://'))) {\n const result = await resolveUrl(client, first);\n if (result) return result;\n throw new Error(\n `Unrecognized DocSync URL: ${first}\\nExpected: /s/{slug}[/f/{fileId}], /s/{slug}[/path], or /spaces/{id}[/path]`\n );\n }\n const { space, path } = parseTarget(args);\n const s = await client.resolveSpace(space);\n return { spaceId: s.id, path };\n}\n\n/**\n * Resolve a space argument that may be a name, UUID, or URL.\n * For URLs, delegates to resolveUrl and extracts the spaceId.\n */\nexport async function resolveSpaceArg(\n client: DocSyncClient,\n input: string\n): Promise<{ id: string }> {\n if (input.startsWith('http://') || input.startsWith('https://')) {\n const result = await resolveUrl(client, input);\n if (result) return { id: result.spaceId };\n throw new Error(\n `Unrecognized DocSync URL: ${input}\\nExpected: /s/{slug}[/f/{fileId}], /s/{slug}[/path], or /spaces/{id}[/path]`\n );\n }\n return client.resolveSpace(input);\n}\n\n/** Parse relative duration (7d, 24h, 30d) to RFC3339 */\nexport function parseExpires(value: string): string {\n const match = value.match(/^(\\d+)([dh])$/);\n if (!match)\n throw new Error(\n `Invalid expires format: \"${value}\". Use e.g. 7d, 24h, 30d`\n );\n const [, num, unit] = match;\n const ms = unit === 'd' ? Number(num) * 86400000 : Number(num) * 3600000;\n return new Date(Date.now() + ms).toISOString();\n}\n\n/** Extract share token from URL or return as-is */\nfunction extractShareToken(input: string): string {\n const m = input.match(SHARE_URL_RE);\n if (m) return m[1];\n return input;\n}\n\n/** Read all of stdin into a string */\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nconst MAX_SAVE_SIZE = 2 * 1024 * 1024; // 2MB\n\n// --- Image upload (shared by CLI command and MCP tool) ---\n\nexport const IMAGE_EXTS = ['png', 'jpg', 'jpeg', 'webp'];\nexport const IMAGE_MAX_SIZE = 5 * 1024 * 1024; // 5MB, same as server limit\n\n/**\n * Validate and read a local image file for upload.\n * Returns { content, filename } on success, or { error } describing\n * why the file was rejected (no request is sent in that case).\n */\nexport function readImageFile(\n filePath: string\n): { content: Buffer; filename: string } | { error: string } {\n if (!existsSync(filePath)) {\n return { error: `File not found: ${filePath}` };\n }\n const filename = basename(filePath);\n const ext = filename.split('.').pop()?.toLowerCase() ?? '';\n if (!IMAGE_EXTS.includes(ext)) {\n return {\n error: `Unsupported image type \".${ext}\". Supported: ${IMAGE_EXTS.join(', ')}`,\n };\n }\n const size = statSync(filePath).size;\n if (size > IMAGE_MAX_SIZE) {\n return {\n error: `Image too large (${formatSize(size)}). Max size: 5 MB`,\n };\n }\n return { content: readFileSync(filePath), filename };\n}\n\n/** Markdown image reference with the filename (minus extension) as alt text */\nexport function markdownImageRef(filename: string, url: string): string {\n const alt = filename.replace(/\\.[^.]+$/, '');\n return `![${alt}](${url})`;\n}\n\n// ---------------------------------------------------------------------------\n// Commands\n// ---------------------------------------------------------------------------\n\nexport function registerCommands(program: Command): void {\n // --- login ---\n program\n .command('login')\n .description('Configure DocSync credentials')\n .option('-u, --url <url>', 'DocSync server URL')\n .option('-t, --token <token>', 'API token')\n .action(async (opts) => {\n const url = opts.url ?? getBaseUrl();\n const token = opts.token;\n if (!token) {\n console.error(\n 'Error: --token is required.\\n' +\n 'Get one at: ' +\n url +\n ' → Settings → API Tokens'\n );\n process.exit(1);\n }\n const client = new DocSyncClient(url, token);\n try {\n const user = await client.me();\n saveConfig(url, token);\n console.log(`Logged in as ${user.name} (${user.email})`);\n console.log(`Config saved to ${getConfigPath()}`);\n } catch (err) {\n console.error(\n `Error: ${err instanceof Error ? err.message : String(err)}`\n );\n process.exit(1);\n }\n });\n\n // --- whoami ---\n program\n .command('whoami')\n .description('Show current user')\n .action(async () => {\n const client = getClient();\n const user = await client.me();\n console.log(`${user.name} (${user.email})`);\n });\n\n // --- spaces ---\n program\n .command('spaces')\n .description('List all accessible spaces')\n .action(async () => {\n const client = getClient();\n const spaces = await client.listSpaces();\n for (const s of spaces) {\n const tag = s.is_private ? 'private' : 'team';\n console.log(\n `${s.name}\\t${tag}\\t${s.member_count} members\\t${s.id}\\t${s.slug ?? ''}`\n );\n }\n });\n\n // --- ls ---\n program\n .command('ls')\n .description('List files — docz ls <space>[:<path>] or <url>')\n .argument('<target...>')\n .option('-R, --recursive', 'Recursively list all files')\n .action(async (args: string[], opts: { recursive?: boolean }) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, args);\n const entries = opts.recursive\n ? await client.treeFull(spaceId)\n : await client.ls(spaceId, path);\n if (entries.length === 0) {\n console.log('(empty)');\n return;\n }\n for (const e of entries) {\n if (e.type === 'tree') {\n console.log(`${e.name}/`);\n } else {\n console.log(`${e.name}\\t${formatSize(e.size)}`);\n }\n }\n });\n\n // --- cat ---\n program\n .command('cat')\n .description('Read file content — docz cat <space>:<path> or <url>')\n .argument('<target...>')\n .option('--ref', 'Also output Git ref to stderr')\n .action(async (args: string[], opts: { ref?: boolean }) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, args);\n if (!path) {\n console.error(\n 'Error: file path is required. Usage: docz cat <space>:<path>'\n );\n process.exit(1);\n }\n if (opts.ref) {\n const result = await client.catWithRef(spaceId, path);\n console.error(`ref: ${result.ref}`);\n process.stdout.write(result.content);\n } else {\n const content = await client.cat(spaceId, path);\n process.stdout.write(content);\n }\n });\n\n // --- upload ---\n program\n .command('upload')\n .description(\n 'Upload file — docz upload <local-file> <space>[:<dir>] or <url>'\n )\n .argument('<file>', 'Local file to upload')\n .argument('<target...>')\n .action(async (file: string, args: string[]) => {\n const client = getClient();\n const { spaceId, path: dir } = await resolveTarget(client, args);\n const content = readFileSync(file);\n const filename = basename(file);\n const targetDir = dir || '';\n const result = await client.upload(spaceId, targetDir, filename, content);\n console.log(`Uploaded: ${result.path}`);\n });\n\n // --- image ---\n const image = program.command('image').description('Image asset operations');\n\n image\n .command('upload')\n .description(\n 'Upload image to OSS, returns a permanent public URL for Markdown embedding'\n )\n .argument('<file>', 'Local image file (png/jpg/webp, max 5MB)')\n .action(async (file: string) => {\n const read = readImageFile(file);\n if ('error' in read) {\n console.error(`Error: ${read.error}`);\n process.exit(1);\n }\n const client = getClient();\n const result = await client.uploadImage(read.content, read.filename);\n console.log(`URL: ${result.url}`);\n console.log(`Markdown: ${markdownImageRef(read.filename, result.url)}`);\n });\n\n // --- write ---\n program\n .command('write')\n .description(\n 'Write content to file — docz write <space>:<path> <content> or <url> <content>'\n )\n .argument('<target>', 'space:dir/filename.md or short URL')\n .argument('<content>', 'File content (or - for stdin)')\n .option('--force', 'Skip conflict detection')\n .option('-m, --message <msg>', 'Custom commit message')\n .action(\n async (\n target: string,\n content: string,\n opts: { force?: boolean; message?: string }\n ) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, [target]);\n if (!path) {\n console.error(\n 'Error: path is required. Usage: docz write <space>:<dir/filename> <content>'\n );\n process.exit(1);\n }\n const body = content === '-' ? await readStdin() : content;\n\n if (Buffer.byteLength(body, 'utf-8') > MAX_SAVE_SIZE) {\n console.error(\n 'Error: content exceeds 2MB limit. Use `docz upload` for large files.'\n );\n process.exit(1);\n }\n\n let baseRef: string | undefined;\n if (!opts.force) {\n try {\n const existing = await client.catWithRef(spaceId, path);\n baseRef = existing.ref;\n } catch (err) {\n const msg = err instanceof Error ? err.message : '';\n if (!msg.includes('404')) throw err;\n }\n }\n\n try {\n const result = await client.save(spaceId, path, body, {\n baseRef,\n message: opts.message,\n });\n console.log(`Written: ${result.path} (ref: ${result.ref})`);\n } catch (err) {\n if (err instanceof ConflictError) {\n console.error(\n 'Error: file was modified by someone else. Please re-read the latest content and try again.'\n );\n process.exit(1);\n }\n throw err;\n }\n }\n );\n\n // --- mkdir ---\n program\n .command('mkdir')\n .description('Create folder — docz mkdir <space>:<path> or <url>')\n .argument('<target...>')\n .action(async (args: string[]) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, args);\n if (!path) {\n console.error('Error: path is required.');\n process.exit(1);\n }\n await client.mkdir(spaceId, path);\n console.log(`Created: ${path}`);\n });\n\n // --- rm ---\n program\n .command('rm')\n .description('Delete file/folder — docz rm <space>:<path> or <url>')\n .argument('<target...>')\n .action(async (args: string[]) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, args);\n if (!path) {\n console.error('Error: path is required.');\n process.exit(1);\n }\n await client.rm(spaceId, path);\n console.log(`Deleted: ${path} (recoverable from trash for 30 days)`);\n });\n\n // --- mv ---\n program\n .command('mv')\n .description('Rename/move — docz mv <space>:<from> <to> or <url> <to>')\n .argument('<target>', 'space:old-path or short URL')\n .argument('<to>', 'new-path')\n .action(async (target: string, to: string) => {\n const client = getClient();\n const { spaceId, path: from } = await resolveTarget(client, [target]);\n if (!from) {\n console.error('Error: source path is required.');\n process.exit(1);\n }\n await client.mv(spaceId, from, to);\n console.log(`Moved: ${from} → ${to}`);\n });\n\n // --- log ---\n program\n .command('log')\n .description('Show change history — docz log <space>[:<path>] or <url>')\n .argument('<target...>')\n .action(async (args: string[]) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, args);\n const logs = await client.log(spaceId, path || undefined);\n if (logs.length === 0) {\n console.log('No history.');\n return;\n }\n for (const l of logs) {\n console.log(`${l.hash} ${l.date} ${l.message}`);\n }\n });\n\n // --- rollback ---\n program\n .command('rollback')\n .description(\n 'Rollback file to a previous version — docz rollback <space>:<path> <commit> or <url> <commit>'\n )\n .argument('<target>', 'space:path or short URL')\n .argument('<commit>', 'Commit hash to rollback to')\n .action(async (target: string, commit: string) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, [target]);\n if (!path) {\n console.error('Error: file path is required.');\n process.exit(1);\n }\n await client.rollback(spaceId, path, commit);\n console.log(`Rolled back: ${path} → ${commit.substring(0, 7)}`);\n });\n\n // --- trash ---\n program\n .command('trash')\n .description('Show deleted files — docz trash <space>')\n .argument('<space>')\n .action(async (spaceName: string) => {\n const client = getClient();\n const s = await resolveSpaceArg(client, spaceName);\n const items = await client.trash(s.id);\n if (items.length === 0) {\n console.log('Trash is empty.');\n return;\n }\n for (const t of items) {\n console.log(\n `${t.path}\\tdeleted ${t.deleted_at}\\t${t.commit.substring(0, 7)}`\n );\n }\n });\n\n // --- restore ---\n program\n .command('restore')\n .description(\n 'Restore file from trash — docz restore <space>:<path> <commit> or <url> <commit>'\n )\n .argument('<target>', 'space:path or short URL')\n .argument('<commit>', 'Commit hash from trash listing')\n .action(async (target: string, commit: string) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, [target]);\n if (!path) {\n console.error('Error: path is required.');\n process.exit(1);\n }\n await client.restore(spaceId, path, commit);\n console.log(`Restored: ${path}`);\n });\n\n // --- comment ---\n const comment = program\n .command('comment')\n .description('Manage file comments');\n\n comment\n .command('list')\n .description('List comments — docz comment list <space>:<path>')\n .argument('<target...>')\n .action(async (args: string[]) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, args);\n if (!path) {\n console.error('Error: file path is required.');\n process.exit(1);\n }\n const comments = await client.listComments(spaceId, path);\n if (comments.length === 0) {\n console.log('No comments.');\n return;\n }\n for (const c of comments) {\n const status = c.is_closed ? ' [closed]' : '';\n console.log(`#${c.id} ${c.user_name} (${c.created_at})${status}`);\n if (c.target_content) {\n console.log(` > ${c.target_content}`);\n }\n console.log(` ${c.content}`);\n for (const r of c.replies) {\n console.log(` → ${r.user_name}: ${r.content}`);\n }\n }\n });\n\n comment\n .command('add')\n .description(\n 'Add comment — docz comment add <space>:<path> <content> or <url> <content>'\n )\n .argument('<target>', 'space:path or short URL')\n .argument('<content>', 'Comment text (or - for stdin)')\n .option(\n '--quote <text>',\n 'Quote text from the file (selection comment). The quoted text will be highlighted in Web UI'\n )\n .action(\n async (target: string, content: string, opts: { quote?: string }) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, [target]);\n if (!path) {\n console.error('Error: file path is required.');\n process.exit(1);\n }\n const body = content === '-' ? await readStdin() : content;\n const c = await client.createComment(spaceId, path, body, {\n quote: opts.quote,\n });\n console.log(`Comment #${c.id} created.`);\n }\n );\n\n comment\n .command('reply')\n .description(\n 'Reply to comment — docz comment reply <space> <commentId> <content>'\n )\n .argument('<space>')\n .argument('<commentId>')\n .argument('<content>', 'Reply text (or - for stdin)')\n .action(async (spaceName: string, commentId: string, content: string) => {\n const client = getClient();\n const s = await resolveSpaceArg(client, spaceName);\n const body = content === '-' ? await readStdin() : content;\n const r = await client.replyComment(s.id, Number(commentId), body);\n console.log(`Reply #${r.id} created.`);\n });\n\n comment\n .command('close')\n .description('Close comment — docz comment close <space> <commentId>')\n .argument('<space>')\n .argument('<commentId>')\n .action(async (spaceName: string, commentId: string) => {\n const client = getClient();\n const s = await resolveSpaceArg(client, spaceName);\n await client.closeComment(s.id, Number(commentId));\n console.log(`Comment #${commentId} closed.`);\n });\n\n comment\n .command('rm')\n .description('Delete comment — docz comment rm <space> <commentId>')\n .argument('<space>')\n .argument('<commentId>')\n .action(async (spaceName: string, commentId: string) => {\n const client = getClient();\n const s = await resolveSpaceArg(client, spaceName);\n await client.deleteComment(s.id, Number(commentId));\n console.log(`Comment #${commentId} deleted.`);\n });\n\n // --- share ---\n const share = program.command('share').description('Manage share links');\n\n share\n .command('create')\n .description(\n 'Create share link — docz share create <space>:<path> or <url>'\n )\n .argument('<target>', 'space:path or short URL')\n .option('--expires <duration>', 'Expiry duration (e.g. 7d, 24h)')\n .option('--users <emails>', 'Comma-separated user emails or IDs')\n .option('--groups <ids>', 'Comma-separated group IDs')\n .action(\n async (\n target: string,\n opts: { expires?: string; users?: string; groups?: string }\n ) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, [target]);\n if (!path) {\n console.error(\n 'Error: file path is required. Usage: docz share create <space>:<path>'\n );\n process.exit(1);\n }\n const apiOpts: {\n expiresAt?: string;\n userIds?: string[];\n groupIds?: string[];\n } = {};\n if (opts.expires) apiOpts.expiresAt = parseExpires(opts.expires);\n if (opts.users)\n apiOpts.userIds = opts.users.split(',').map((s) => s.trim());\n if (opts.groups)\n apiOpts.groupIds = opts.groups.split(',').map((s) => s.trim());\n const link = await client.createShareLink(spaceId, path, apiOpts);\n const baseUrl = getBaseUrl();\n console.log('Created share link:');\n console.log(` id: ${link.id}`);\n console.log(` token: ${link.token}`);\n console.log(` url: ${baseUrl}/share/${link.token}`);\n console.log(` expires: ${link.expires_at ?? 'never'}`);\n if (link.user_ids?.length)\n console.log(` users: ${link.user_ids.join(', ')}`);\n if (link.group_ids?.length)\n console.log(` groups: ${link.group_ids.length}`);\n }\n );\n\n share\n .command('list')\n .description('List share links — docz share list <space>')\n .argument('<space>')\n .option('--file <path>', 'Filter by file path')\n .action(async (spaceName: string, opts: { file?: string }) => {\n const client = getClient();\n const s = await resolveSpaceArg(client, spaceName);\n const links = await client.listShareLinks(s.id, opts.file);\n if (links.length === 0) {\n console.log('No share links.');\n return;\n }\n for (const l of links) {\n const expires = l.expires_at ?? 'never';\n const creator = l.created_by_name ?? l.created_by_email ?? l.created_by;\n console.log(\n `${l.id}\\t${l.token}\\t${l.file_path}\\t${expires}\\t${creator}`\n );\n }\n });\n\n share\n .command('update')\n .description('Update share link — docz share update <space> <link-id>')\n .argument('<space>')\n .argument('<linkId>')\n .option('--expires <duration>', 'New expiry duration (e.g. 30d)')\n .option('--users <emails>', 'Comma-separated user emails or IDs')\n .option('--groups <ids>', 'Comma-separated group IDs')\n .action(\n async (\n spaceName: string,\n linkId: string,\n opts: { expires?: string; users?: string; groups?: string }\n ) => {\n const client = getClient();\n const s = await resolveSpaceArg(client, spaceName);\n const apiOpts: {\n expiresAt?: string;\n userIds?: string[];\n groupIds?: string[];\n } = {};\n if (opts.expires) apiOpts.expiresAt = parseExpires(opts.expires);\n if (opts.users)\n apiOpts.userIds = opts.users.split(',').map((s) => s.trim());\n if (opts.groups)\n apiOpts.groupIds = opts.groups.split(',').map((s) => s.trim());\n await client.updateShareLink(s.id, linkId, apiOpts);\n console.log(`Updated share link: ${linkId}`);\n }\n );\n\n share\n .command('cat')\n .description('Read shared file — docz share cat <token-or-url>')\n .argument('<token>', 'Share token or full URL')\n .option('--raw', 'Output raw content only')\n .action(async (tokenArg: string, opts: { raw?: boolean }) => {\n const client = getClient();\n const token = extractShareToken(tokenArg);\n if (!opts.raw) {\n try {\n const info = await client.getSharedFileInfo(token);\n console.log(`File: ${info.file_path} (${info.space_name})`);\n console.log(\n `Shared by: ${info.created_by_name} | Expires: ${info.expires_at ?? 'never'}`\n );\n console.log('---');\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (!msg.includes('404')) {\n console.error(`Warning: failed to fetch share info: ${msg}`);\n }\n }\n }\n const content = await client.getSharedFile(token);\n process.stdout.write(content);\n });\n\n share\n .command('info')\n .description('Show share link info — docz share info <token-or-url>')\n .argument('<token>', 'Share token or full URL')\n .action(async (tokenArg: string) => {\n const client = getClient();\n const token = extractShareToken(tokenArg);\n const info = await client.getSharedFileInfo(token);\n console.log(`File: ${info.file_path}`);\n console.log(`Space: ${info.space_name}`);\n console.log(`Shared by: ${info.created_by_name}`);\n console.log(`Expires: ${info.expires_at ?? 'never'}`);\n });\n\n share\n .command('rm')\n .description('Delete share link — docz share rm <space> <link-id>')\n .argument('<space>')\n .argument('<linkId>')\n .action(async (spaceName: string, linkId: string) => {\n const client = getClient();\n const s = await resolveSpaceArg(client, spaceName);\n await client.deleteShareLink(s.id, linkId);\n console.log(`Deleted share link: ${linkId}`);\n });\n\n // --- shortlink ---\n program\n .command('shortlink')\n .description('Get short URL — docz shortlink <space>:<path> or <url>')\n .argument('<target...>')\n .action(async (args: string[]) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, args);\n if (!path) {\n console.error(\n 'Error: file path is required. Usage: docz shortlink <space>:<path>'\n );\n process.exit(1);\n }\n const ref = await client.getFileRef(spaceId, path);\n console.log(ref.url);\n });\n\n // --- collaborative editing ---\n const collab = program\n .command('collab')\n .description('Collaborative editing via Docz realtime rooms');\n\n collab\n .command('cat')\n .description(\n 'Read collaborative document — docz collab cat <space>:<path> or <url>'\n )\n .argument('<target>', 'space:path or short URL')\n .option('--raw', 'Output raw content only')\n .option('--timeout <ms>', 'Open timeout in milliseconds', Number)\n .action(\n async (target: string, opts: { raw?: boolean; timeout?: number }) => {\n const open = await buildCollabOpenOptions(target, {\n timeout: opts.timeout,\n });\n await withCollabRoom(open, async (room) => {\n const result = room.read();\n if (!opts.raw) {\n console.error(`collab_hash: ${result.collabHash}`);\n console.error(`read_only: ${result.readOnly ? 'true' : 'false'}`);\n console.error('---');\n }\n process.stdout.write(result.content);\n });\n }\n );\n\n collab\n .command('write')\n .description(\n 'Write collaborative document — docz collab write <space>:<path> <content>'\n )\n .argument('<target>', 'space:path or short URL')\n .argument('<content>', 'File content (or - for stdin)')\n .option('--base-collab-hash <hash>', 'Hash returned by docz collab cat')\n .option('--force', 'Skip collaborative hash conflict detection')\n .option('--no-publish', 'Only update realtime room, do not flush to repo')\n .option('--timeout <ms>', 'Open/publish timeout in milliseconds', Number)\n .action(\n async (\n target: string,\n content: string,\n opts: {\n baseCollabHash?: string;\n force?: boolean;\n publish?: boolean;\n timeout?: number;\n }\n ) => {\n const open = await buildCollabOpenOptions(target, {\n timeout: opts.timeout,\n });\n const body = content === '-' ? await readStdin() : content;\n if (Buffer.byteLength(body, 'utf-8') > MAX_SAVE_SIZE) {\n console.error(\n 'Error: content exceeds 2MB limit. Use `docz upload` for large files.'\n );\n process.exit(1);\n }\n\n try {\n await withCollabRoom(open, async (room) => {\n const write = room.write(body, {\n baseHash: opts.baseCollabHash,\n force: opts.force,\n });\n if (opts.publish === false) {\n console.log(\n `Updated collaborative room (collab_hash: ${write.collabHash})`\n );\n return;\n }\n const published = await room.publish(opts.timeout);\n console.log(\n `Published: ${published.path} (ref: ${published.ref}, collab_hash: ${write.collabHash})`\n );\n if (published.externalBackup) {\n console.log(`External backup: ${published.externalBackup}`);\n }\n });\n } catch (err) {\n if (err instanceof CollabConflictError) {\n console.error(\n `Error: collaborative document changed. Re-read and retry. current=${err.currentHash} base=${err.baseHash}`\n );\n process.exit(1);\n }\n if (err instanceof CollabBaseHashRequiredError) {\n console.error(\n `Error: --base-collab-hash is required unless --force is set. Re-read first to get the latest hash. current=${err.currentHash}`\n );\n process.exit(1);\n }\n if (err instanceof CollabUnknownError) {\n console.error(\n `Unknown state: ${err.message}. The server may have processed the publish; please re-read before retrying.`\n );\n process.exit(75);\n }\n throw err;\n }\n }\n );\n\n collab\n .command('publish')\n .description(\n 'Flush collaborative document to repo — docz collab publish <space>:<path>'\n )\n .argument('<target>', 'space:path or short URL')\n .option('--timeout <ms>', 'Open/publish timeout in milliseconds', Number)\n .action(async (target: string, opts: { timeout?: number }) => {\n const open = await buildCollabOpenOptions(target, {\n timeout: opts.timeout,\n });\n try {\n await withCollabRoom(open, async (room) => {\n const result = await room.publish(opts.timeout);\n console.log(`Published: ${result.path} (ref: ${result.ref})`);\n if (result.externalBackup) {\n console.log(`External backup: ${result.externalBackup}`);\n }\n });\n } catch (err) {\n if (err instanceof CollabUnknownError) {\n console.error(\n `Unknown state: ${err.message}. The server may have processed the publish; please re-read before retrying.`\n );\n process.exit(75);\n }\n throw err;\n }\n });\n\n collab\n .command('bridge')\n .description('Start local JSONL bridge for terminal editors')\n .option('--client <name>', 'Client name sent to Docz', 'docz.nvim')\n .option(\n '--client-version <version>',\n 'Client version sent to Docz',\n __VERSION__\n )\n .option('--timeout <ms>', 'Open/publish timeout in milliseconds', Number)\n .action(\n async (opts: {\n client: string;\n clientVersion: string;\n timeout?: number;\n }) => {\n await startCollabBridge(async (target: string) => {\n const open = await buildCollabOpenOptions(target, {\n client: opts.client,\n clientVersion: opts.clientVersion,\n timeout: opts.timeout,\n });\n const room = new CollabRoomClient();\n await room.open(open);\n return room;\n });\n }\n );\n\n // --- diff ---\n program\n .command('diff')\n .description(\n 'Show changes — docz diff <space>[:<path>] <commit> [<from>] or <url> <commit> [<from>]'\n )\n .argument('<target>', 'space or space:path or short URL')\n .argument('<to>', 'Commit hash')\n .argument('[from]', 'From commit hash (default: to^)')\n .action(async (target: string, to: string, from?: string) => {\n const client = getClient();\n const { spaceId, path } = await resolveTarget(client, [target]);\n if (path) {\n const result = await client.diffFile(spaceId, path, to, from);\n if (result.diff) {\n process.stdout.write(result.diff);\n } else {\n console.log('No changes.');\n }\n } else {\n const result = await client.diffSummary(spaceId, to, from);\n if (result.files.length === 0) {\n console.log('No changes.');\n return;\n }\n for (const f of result.files) {\n console.log(`${f.status} ${f.path}`);\n }\n }\n });\n}\n","import readline from 'node:readline';\nimport type { CollabRoomClient } from './room.js';\nimport { collabHash } from './text.js';\n\ntype BridgeRequest = {\n id?: number | string;\n method?: string;\n params?: Record<string, unknown>;\n};\n\nfunction send(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value)}\\n`);\n}\n\nexport async function startCollabBridge(\n openRoom: (target: string) => Promise<CollabRoomClient>\n): Promise<void> {\n let room: CollabRoomClient | null = null;\n let cleanupObserver: (() => void) | null = null;\n const rl = readline.createInterface({\n input: process.stdin,\n crlfDelay: Number.POSITIVE_INFINITY,\n });\n\n function attachObserver(nextRoom: CollabRoomClient): void {\n cleanupObserver?.();\n const ytext = nextRoom.doc.getText('content');\n const observer = () => {\n const content = ytext.toString();\n send({ event: 'document_change', content, hash: collabHash(content) });\n };\n ytext.observe(observer);\n cleanupObserver = () => ytext.unobserve(observer);\n }\n\n function closeRoom(): void {\n cleanupObserver?.();\n cleanupObserver = null;\n room?.close();\n room = null;\n }\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n let req: BridgeRequest;\n try {\n req = JSON.parse(line) as BridgeRequest;\n } catch (err) {\n send({ event: 'error', code: 'bad_json', message: String(err) });\n continue;\n }\n\n try {\n if (req.method === 'open') {\n const target = String(req.params?.target ?? '');\n closeRoom();\n room = await openRoom(target);\n attachObserver(room);\n const current = room.read();\n send({\n id: req.id,\n result: {\n content: current.content,\n hash: current.collabHash,\n read_only: current.readOnly,\n },\n });\n send({\n event: 'opened',\n content: current.content,\n hash: current.collabHash,\n });\n } else if (req.method === 'local_change') {\n if (!room) throw new Error('room is not open');\n const content = String(req.params?.content ?? '');\n const baseHash = req.params?.base_hash\n ? String(req.params.base_hash)\n : undefined;\n const result = room.write(content, {\n baseHash,\n force: req.params?.force === true,\n });\n send({ id: req.id, result: { hash: result.collabHash } });\n } else if (req.method === 'publish') {\n if (!room) throw new Error('room is not open');\n send({ id: req.id, result: await room.publish() });\n } else if (req.method === 'status') {\n send({ id: req.id, result: room ? room.read() : { connected: false } });\n } else if (req.method === 'close') {\n closeRoom();\n send({ id: req.id, result: { ok: true } });\n } else {\n throw new Error(`unknown method: ${req.method}`);\n }\n } catch (err) {\n send({\n id: req.id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n closeRoom();\n}\n"],"mappings":"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","names":["existsSync","readFileSync","existsSync","readFileSync","s"]}
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  registerCommands
4
- } from "./chunk-K3JRXIEV.js";
4
+ } from "./chunk-26LVQHYL.js";
5
5
 
6
6
  // src/index.ts
7
7
  import { Command } from "commander";
8
8
  var program = new Command();
9
- program.name("docz").description("DocSync CLI \u2014 read and write company documents").version("0.9.0");
9
+ program.name("docz").description("DocSync CLI \u2014 read and write company documents").version("0.10.0");
10
10
  registerCommands(program);
11
11
  program.command("mcp").description("Start MCP stdio server for AI agent integration").action(async () => {
12
- const { startMcpServer } = await import("./mcp-HXAB75DP.js");
12
+ const { startMcpServer } = await import("./mcp-X6AF2C32.js");
13
13
  await startMcpServer();
14
14
  });
15
15
  program.parse();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerCommands } from './commands.js';\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('docz')\n .description('DocSync CLI — read and write company documents')\n .version(__VERSION__);\n\nregisterCommands(program);\n\nprogram\n .command('mcp')\n .description('Start MCP stdio server for AI agent integration')\n .action(async () => {\n const { startMcpServer } = await import('./mcp.js');\n await startMcpServer();\n });\n\nprogram.parse();\n"],"mappings":";;;;;;AAAA,SAAS,eAAe;AAKxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,MAAM,EACX,YAAY,qDAAgD,EAC5D,QAAQ,OAAW;AAEtB,iBAAiB,OAAO;AAExB,QACG,QAAQ,KAAK,EACb,YAAY,iDAAiD,EAC7D,OAAO,YAAY;AAClB,QAAM,EAAE,eAAe,IAAI,MAAM,OAAO,mBAAU;AAClD,QAAM,eAAe;AACvB,CAAC;AAEH,QAAQ,MAAM;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerCommands } from './commands.js';\n\ndeclare const __VERSION__: string;\n\nconst program = new Command();\n\nprogram\n .name('docz')\n .description('DocSync CLI — read and write company documents')\n .version(__VERSION__);\n\nregisterCommands(program);\n\nprogram\n .command('mcp')\n .description('Start MCP stdio server for AI agent integration')\n .action(async () => {\n const { startMcpServer } = await import('./mcp.js');\n await startMcpServer();\n });\n\nprogram.parse();\n"],"mappings":";;;;;;AAAA,SAAS,eAAe;AAKxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,MAAM,EACX,YAAY,qDAAgD,EAC5D,QAAQ,QAAW;AAEtB,iBAAiB,OAAO;AAExB,QACG,QAAQ,KAAK,EACb,YAAY,iDAAiD,EAC7D,OAAO,YAAY;AAClB,QAAM,EAAE,eAAe,IAAI,MAAM,OAAO,mBAAU;AAClD,QAAM,eAAe;AACvB,CAAC;AAEH,QAAQ,MAAM;","names":[]}
@@ -1,13 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ CollabBaseHashRequiredError,
4
+ CollabConflictError,
5
+ CollabUnknownError,
3
6
  ConflictError,
4
7
  DocSyncClient,
5
8
  getBaseUrl,
6
9
  getToken,
7
10
  markdownImageRef,
8
11
  parseExpires,
9
- readImageFile
10
- } from "./chunk-K3JRXIEV.js";
12
+ readImageFile,
13
+ withCollabRoom
14
+ } from "./chunk-26LVQHYL.js";
11
15
 
12
16
  // src/mcp.ts
13
17
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -25,6 +29,15 @@ function getClient() {
25
29
  }
26
30
  return new DocSyncClient(getBaseUrl(), token);
27
31
  }
32
+ function getRequiredToken() {
33
+ const token = getToken();
34
+ if (!token) {
35
+ throw new Error(
36
+ "DOCSYNC_API_TOKEN not set. Run `docz login --token <token>` or set the env var."
37
+ );
38
+ }
39
+ return token;
40
+ }
28
41
  async function resolveSpaceId(client, nameOrId) {
29
42
  const space = await client.resolveSpace(nameOrId);
30
43
  return space.id;
@@ -123,6 +136,78 @@ async function startMcpServer() {
123
136
  required: ["space", "path", "content"]
124
137
  }
125
138
  },
139
+ {
140
+ name: "docz_collab_read_file",
141
+ description: "\u901A\u8FC7\u5B9E\u65F6\u534F\u540C\u623F\u95F4\u8BFB\u53D6 Docz \u6587\u6863\u5185\u5BB9\u3002\u8FD4\u56DE\u7B2C\u4E00\u884C [collab_hash: <hash>]\uFF0C\u4FDD\u5B58\u65F6\u8BF7\u628A\u8BE5\u503C\u4F5C\u4E3A base_collab_hash \u4F20\u5165 docz_collab_save_file\uFF0C\u4EE5\u907F\u514D\u8986\u76D6\u4ED6\u4EBA\u5B9E\u65F6\u7F16\u8F91",
142
+ inputSchema: {
143
+ type: "object",
144
+ properties: {
145
+ space: {
146
+ type: "string",
147
+ description: "Space \u540D\u79F0\u6216 ID"
148
+ },
149
+ path: { type: "string", description: "\u6587\u4EF6\u8DEF\u5F84" },
150
+ timeout_ms: {
151
+ type: "number",
152
+ description: "\u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\uFF0C\u9ED8\u8BA4 30000ms"
153
+ }
154
+ },
155
+ required: ["space", "path"]
156
+ }
157
+ },
158
+ {
159
+ name: "docz_collab_save_file",
160
+ description: "\u901A\u8FC7\u5B9E\u65F6\u534F\u540C\u623F\u95F4\u4FDD\u5B58\u6587\u6863\u5185\u5BB9\uFF0C\u5E76\u9ED8\u8BA4 publish \u5230\u4ED3\u5E93\u3002\u5FC5\u987B\u4F20\u5165 docz_collab_read_file \u8FD4\u56DE\u7684 base_collab_hash\uFF1B\u5982\u68C0\u6D4B\u5230\u5185\u5BB9\u5DF2\u53D8\u66F4\u4F1A\u8FD4\u56DE\u51B2\u7A81\uFF0C\u9700\u8981\u91CD\u65B0\u8BFB\u53D6\u540E\u91CD\u8BD5",
161
+ inputSchema: {
162
+ type: "object",
163
+ properties: {
164
+ space: {
165
+ type: "string",
166
+ description: "Space \u540D\u79F0\u6216 ID"
167
+ },
168
+ path: { type: "string", description: "\u6587\u4EF6\u8DEF\u5F84" },
169
+ content: { type: "string", description: "\u6587\u4EF6\u5185\u5BB9" },
170
+ base_collab_hash: {
171
+ type: "string",
172
+ description: "\u8BFB\u53D6\u65F6\u83B7\u5F97\u7684 collab_hash"
173
+ },
174
+ force: {
175
+ type: "boolean",
176
+ description: "\u8DF3\u8FC7 collab_hash \u51B2\u7A81\u68C0\u6D4B",
177
+ default: false
178
+ },
179
+ publish: {
180
+ type: "boolean",
181
+ description: "\u662F\u5426 flush \u5230\u4ED3\u5E93\uFF0C\u9ED8\u8BA4 true",
182
+ default: true
183
+ },
184
+ timeout_ms: {
185
+ type: "number",
186
+ description: "\u8FDE\u63A5/\u53D1\u5E03\u8D85\u65F6\u65F6\u95F4\uFF0C\u9ED8\u8BA4 30000ms"
187
+ }
188
+ },
189
+ required: ["space", "path", "content", "base_collab_hash"]
190
+ }
191
+ },
192
+ {
193
+ name: "docz_collab_publish",
194
+ description: "\u5C06\u5B9E\u65F6\u534F\u540C\u623F\u95F4\u91CC\u7684\u6700\u65B0\u5185\u5BB9 flush \u5230\u4ED3\u5E93\u3002\u82E5\u8D85\u65F6\u8FD4\u56DE\u672A\u77E5\u6001\uFF0C\u8C03\u7528\u65B9\u5E94\u91CD\u65B0\u8BFB\u53D6\u786E\u8BA4\u72B6\u6001\u540E\u518D\u51B3\u5B9A\u662F\u5426\u91CD\u8BD5",
195
+ inputSchema: {
196
+ type: "object",
197
+ properties: {
198
+ space: {
199
+ type: "string",
200
+ description: "Space \u540D\u79F0\u6216 ID"
201
+ },
202
+ path: { type: "string", description: "\u6587\u4EF6\u8DEF\u5F84" },
203
+ timeout_ms: {
204
+ type: "number",
205
+ description: "\u8FDE\u63A5/\u53D1\u5E03\u8D85\u65F6\u65F6\u95F4\uFF0C\u9ED8\u8BA4 30000ms"
206
+ }
207
+ },
208
+ required: ["space", "path"]
209
+ }
210
+ },
126
211
  {
127
212
  name: "docz_upload_image",
128
213
  description: "\u4E3A Docz \u6587\u6863\u914D\u56FE\uFF1A\u4E0A\u4F20\u672C\u5730\u56FE\u7247\u5230\u56FE\u5E8A\uFF08OSS\uFF09\uFF0C\u8FD4\u56DE\u6C38\u4E45\u516C\u7F51 URL\u3002\u5178\u578B\u5DE5\u4F5C\u6D41\uFF1A\u5148\u7528\u672C\u5DE5\u5177\u4E0A\u4F20\u56FE\u7247\u62FF\u5230 URL\uFF0C\u518D\u628A\u8FD4\u56DE\u7684 ![alt](url) \u5199\u5165\u6587\u6863\u5185\u5BB9\uFF0C\u901A\u8FC7 docz_save_file / docz_upload_file \u4FDD\u5B58\u3002\u56FE\u7247\u5B58 OSS \u800C\u975E Space\uFF08\u4E0D\u5360\u914D\u989D\uFF09\uFF0CURL \u65E0\u9700\u767B\u5F55\u5373\u53EF\u8BBF\u95EE\uFF0C\u5206\u4EAB\u94FE\u63A5/\u535A\u5BA2\u4E2D\u5747\u53EF\u663E\u793A\u3002\u6CE8\u610F\uFF1A\u6587\u6863\u914D\u56FE\u8BF7\u7528\u672C\u5DE5\u5177\uFF0C\u4E0D\u8981\u7528 docz_upload_file \u628A\u56FE\u7247\u4F20\u8FDB Space\u3002\u652F\u6301 png/jpg/webp\uFF0C\u6700\u5927 5MB",
@@ -531,6 +616,120 @@ async function startMcpServer() {
531
616
  throw err;
532
617
  }
533
618
  }
619
+ case "docz_collab_read_file": {
620
+ const sid = await resolveSpaceId(client, String(args.space));
621
+ const timeoutMs = args.timeout_ms ? Number(args.timeout_ms) : void 0;
622
+ return withCollabRoom(
623
+ {
624
+ baseUrl: getBaseUrl(),
625
+ token: getRequiredToken(),
626
+ spaceId: sid,
627
+ path: String(args.path),
628
+ client: "docz-mcp",
629
+ clientVersion: "0.10.0",
630
+ timeoutMs
631
+ },
632
+ async (room) => {
633
+ const result = room.read();
634
+ return ok(
635
+ `[collab_hash: ${result.collabHash}]
636
+ [read_only: ${result.readOnly ? "true" : "false"}]
637
+
638
+ ${result.content}`
639
+ );
640
+ }
641
+ );
642
+ }
643
+ case "docz_collab_save_file": {
644
+ const sid = await resolveSpaceId(client, String(args.space));
645
+ const saveContent = String(args.content);
646
+ if (Buffer.byteLength(saveContent, "utf-8") > 2 * 1024 * 1024) {
647
+ return fail("\u5185\u5BB9\u8D85\u8FC7 2MB \u9650\u5236\uFF0C\u8BF7\u4F7F\u7528 docz_upload_file \u4E0A\u4F20");
648
+ }
649
+ const timeoutMs = args.timeout_ms ? Number(args.timeout_ms) : void 0;
650
+ try {
651
+ return await withCollabRoom(
652
+ {
653
+ baseUrl: getBaseUrl(),
654
+ token: getRequiredToken(),
655
+ spaceId: sid,
656
+ path: String(args.path),
657
+ client: "docz-mcp",
658
+ clientVersion: "0.10.0",
659
+ timeoutMs
660
+ },
661
+ async (room) => {
662
+ const write = room.write(saveContent, {
663
+ baseHash: args.base_collab_hash ? String(args.base_collab_hash) : void 0,
664
+ force: Boolean(args.force)
665
+ });
666
+ if (args.publish === false) {
667
+ return ok(
668
+ `\u5DF2\u66F4\u65B0\u534F\u540C\u623F\u95F4: ${args.path} (collab_hash: ${write.collabHash})`
669
+ );
670
+ }
671
+ const published = await room.publish(timeoutMs);
672
+ const backup = published.externalBackup ? `
673
+ external_backup: ${published.externalBackup}` : "";
674
+ return ok(
675
+ `\u5DF2\u534F\u540C\u4FDD\u5B58: ${published.path}
676
+ ref: ${published.ref}
677
+ collab_hash: ${write.collabHash}${backup}`
678
+ );
679
+ }
680
+ );
681
+ } catch (err) {
682
+ if (err instanceof CollabConflictError) {
683
+ return fail(
684
+ `\u534F\u540C\u51B2\u7A81\uFF1A\u5185\u5BB9\u5DF2\u53D8\u5316\u3002current=${err.currentHash} base=${err.baseHash}\u3002\u8BF7\u5148\u7528 docz_collab_read_file \u91CD\u65B0\u8BFB\u53D6\uFF0C\u518D\u5408\u5E76\u4FEE\u6539\u540E\u4FDD\u5B58\u3002`
685
+ );
686
+ }
687
+ if (err instanceof CollabBaseHashRequiredError) {
688
+ return fail(
689
+ `\u7F3A\u5C11 base_collab_hash\uFF1A\u8BF7\u5148\u7528 docz_collab_read_file \u8BFB\u53D6\u6700\u65B0\u5185\u5BB9\u548C hash\uFF0C\u518D\u4FDD\u5B58\uFF1B\u53EA\u6709\u660E\u786E\u9700\u8981\u8986\u76D6\u65F6\u624D\u4F20 force=true\u3002current=${err.currentHash}`
690
+ );
691
+ }
692
+ if (err instanceof CollabUnknownError) {
693
+ return fail(
694
+ `\u672A\u77E5\u6001\uFF1A${err.message}\u3002\u670D\u52A1\u7AEF\u53EF\u80FD\u5DF2\u7ECF\u5904\u7406 publish\uFF0C\u8BF7\u5148\u91CD\u65B0\u8BFB\u53D6\u786E\u8BA4\u72B6\u6001\u540E\u518D\u91CD\u8BD5\u3002`
695
+ );
696
+ }
697
+ throw err;
698
+ }
699
+ }
700
+ case "docz_collab_publish": {
701
+ const sid = await resolveSpaceId(client, String(args.space));
702
+ const timeoutMs = args.timeout_ms ? Number(args.timeout_ms) : void 0;
703
+ try {
704
+ return await withCollabRoom(
705
+ {
706
+ baseUrl: getBaseUrl(),
707
+ token: getRequiredToken(),
708
+ spaceId: sid,
709
+ path: String(args.path),
710
+ client: "docz-mcp",
711
+ clientVersion: "0.10.0",
712
+ timeoutMs
713
+ },
714
+ async (room) => {
715
+ const result = await room.publish(timeoutMs);
716
+ const backup = result.externalBackup ? `
717
+ external_backup: ${result.externalBackup}` : "";
718
+ return ok(
719
+ `\u5DF2\u53D1\u5E03: ${result.path}
720
+ ref: ${result.ref}${backup}`
721
+ );
722
+ }
723
+ );
724
+ } catch (err) {
725
+ if (err instanceof CollabUnknownError) {
726
+ return fail(
727
+ `\u672A\u77E5\u6001\uFF1A${err.message}\u3002\u670D\u52A1\u7AEF\u53EF\u80FD\u5DF2\u7ECF\u5904\u7406 publish\uFF0C\u8BF7\u5148\u91CD\u65B0\u8BFB\u53D6\u786E\u8BA4\u72B6\u6001\u540E\u518D\u91CD\u8BD5\u3002`
728
+ );
729
+ }
730
+ throw err;
731
+ }
732
+ }
534
733
  case "docz_upload_image": {
535
734
  const read = readImageFile(String(args.file_path));
536
735
  if ("error" in read) {
@@ -718,4 +917,4 @@ Space: ${info.space_name}
718
917
  export {
719
918
  startMcpServer
720
919
  };
721
- //# sourceMappingURL=mcp-HXAB75DP.js.map
920
+ //# sourceMappingURL=mcp-X6AF2C32.js.map