@oscardvs/zoteus
Advanced tools
| import { RateLimitedFetcher } from './http.js'; | ||
| import type { Logger } from '../lib/logger.js'; | ||
| export interface ConnectorWriteClientOptions { | ||
| port?: number; | ||
| fetcher?: RateLimitedFetcher; | ||
| logger?: Logger; | ||
| } | ||
| export interface SaveTarget { | ||
| id: string; | ||
| name: string; | ||
| level?: number; | ||
| } | ||
| /** | ||
| * Write client for the Zotero desktop connector API (available on Zotero 7+ while | ||
| * the app is running, including versions whose local API is still read-only). | ||
| * | ||
| * This is the same protocol the browser connectors use: | ||
| * - `POST /connector/saveItems` saves items through Zotero's ItemSaver. Items may | ||
| * carry a client-chosen `id` ("connector key") that later calls use to reference | ||
| * them. | ||
| * - `POST /connector/saveAttachment` streams file bytes (X-Metadata header with | ||
| * sessionID/parentItemID/url/title) into a stored attachment under a session item. | ||
| * - `POST /connector/updateSession` re-targets a session: moves already-saved items | ||
| * to another collection (treeViewID), applies tags, and can attach a note. | ||
| * | ||
| * Limitations vs the cloud Web API: no updates/deletes, no response payload (created | ||
| * keys must be recovered by querying the local API afterwards), and saves land in the | ||
| * personal library only. | ||
| */ | ||
| export declare class ConnectorWriteClient { | ||
| private readonly base; | ||
| private readonly fetcher; | ||
| private readonly logger?; | ||
| constructor(opts?: ConnectorWriteClientOptions); | ||
| private jsonHeaders; | ||
| private newSessionId; | ||
| ping(): Promise<boolean>; | ||
| /** | ||
| * Save items (metadata, notes, or annotations with `parentItem`) and open a session | ||
| * for follow-up calls. Each item gets a connector `id` (returned alongside) that | ||
| * `saveAttachment` uses as `parentItemID`. | ||
| */ | ||
| saveItems(items: Record<string, unknown>[], opts?: { | ||
| uri?: string; | ||
| sessionID?: string; | ||
| }): Promise<{ | ||
| sessionID: string; | ||
| connectorIds: string[]; | ||
| }>; | ||
| /** | ||
| * Re-target a session: moves its saved items to `target` (a treeViewID like "L1" or | ||
| * "C20"), applies `tags`, and optionally attaches `note` to each item. | ||
| */ | ||
| updateSession(sessionID: string, opts?: { | ||
| target?: string; | ||
| tags?: string[]; | ||
| note?: string; | ||
| }): Promise<void>; | ||
| /** | ||
| * Stream file bytes into a stored attachment under an item saved in this session. | ||
| * `url` is recorded as the attachment's source URL (it is NOT fetched by Zotero). | ||
| */ | ||
| saveAttachment(opts: { | ||
| sessionID: string; | ||
| parentConnectorId: string; | ||
| url: string; | ||
| title?: string; | ||
| bytes: Uint8Array; | ||
| contentType: string; | ||
| }): Promise<void>; | ||
| /** Current save target + full list of selectable targets (library and collections). */ | ||
| getSelectedCollection(): Promise<{ | ||
| current: string; | ||
| targets: SaveTarget[]; | ||
| }>; | ||
| } |
| import { randomBytes } from 'node:crypto'; | ||
| import { RateLimitedFetcher } from './http.js'; | ||
| /** | ||
| * Write client for the Zotero desktop connector API (available on Zotero 7+ while | ||
| * the app is running, including versions whose local API is still read-only). | ||
| * | ||
| * This is the same protocol the browser connectors use: | ||
| * - `POST /connector/saveItems` saves items through Zotero's ItemSaver. Items may | ||
| * carry a client-chosen `id` ("connector key") that later calls use to reference | ||
| * them. | ||
| * - `POST /connector/saveAttachment` streams file bytes (X-Metadata header with | ||
| * sessionID/parentItemID/url/title) into a stored attachment under a session item. | ||
| * - `POST /connector/updateSession` re-targets a session: moves already-saved items | ||
| * to another collection (treeViewID), applies tags, and can attach a note. | ||
| * | ||
| * Limitations vs the cloud Web API: no updates/deletes, no response payload (created | ||
| * keys must be recovered by querying the local API afterwards), and saves land in the | ||
| * personal library only. | ||
| */ | ||
| export class ConnectorWriteClient { | ||
| base; | ||
| fetcher; | ||
| logger; | ||
| constructor(opts = {}) { | ||
| this.base = `http://127.0.0.1:${opts.port ?? 23119}`; | ||
| this.fetcher = opts.fetcher ?? new RateLimitedFetcher(); | ||
| this.logger = opts.logger; | ||
| } | ||
| jsonHeaders() { | ||
| return { | ||
| 'Content-Type': 'application/json', | ||
| 'x-zotero-connector-api-version': '3', | ||
| 'x-zotero-connector-version': '5.0.125', | ||
| }; | ||
| } | ||
| newSessionId() { | ||
| return `zoteus-${Date.now().toString(36)}-${randomBytes(4).toString('hex')}`; | ||
| } | ||
| async ping() { | ||
| try { | ||
| const res = await this.fetcher.fetch(`${this.base}/connector/ping`, { method: 'GET' }, { maxRetries: 0 }); | ||
| const text = await res.text().catch(() => ''); | ||
| return res.ok && /zotero is running/i.test(text); | ||
| } | ||
| catch { | ||
| return false; | ||
| } | ||
| } | ||
| /** | ||
| * Save items (metadata, notes, or annotations with `parentItem`) and open a session | ||
| * for follow-up calls. Each item gets a connector `id` (returned alongside) that | ||
| * `saveAttachment` uses as `parentItemID`. | ||
| */ | ||
| async saveItems(items, opts = {}) { | ||
| const sessionID = opts.sessionID ?? this.newSessionId(); | ||
| const connectorIds = items.map((_, i) => `${sessionID}-${i}`); | ||
| const payload = { | ||
| uri: opts.uri ?? 'zotero://zoteus/session/' + sessionID, | ||
| sessionID, | ||
| items: items.map((it, i) => ({ id: connectorIds[i], ...it })), | ||
| }; | ||
| const res = await this.fetcher.fetch(`${this.base}/connector/saveItems`, { method: 'POST', headers: this.jsonHeaders(), body: JSON.stringify(payload) }, { maxRetries: 0, deadlineMs: 120_000 }); | ||
| const text = await res.text().catch(() => ''); | ||
| if (res.status === 409) { | ||
| // Session id collision — retry once with a fresh id. | ||
| if (!opts.sessionID) | ||
| return this.saveItems(items, { ...opts, sessionID: this.newSessionId() }); | ||
| throw new Error(`Connector save session exists: ${text}`); | ||
| } | ||
| if (!res.ok && res.status !== 201) { | ||
| throw new Error(`Connector saveItems failed (HTTP ${res.status}): ${text.slice(0, 300)}`); | ||
| } | ||
| this.logger?.info(`Connector session ${sessionID}: saved ${items.length} item(s).`); | ||
| return { sessionID, connectorIds }; | ||
| } | ||
| /** | ||
| * Re-target a session: moves its saved items to `target` (a treeViewID like "L1" or | ||
| * "C20"), applies `tags`, and optionally attaches `note` to each item. | ||
| */ | ||
| async updateSession(sessionID, opts = {}) { | ||
| const body = { sessionID }; | ||
| if (opts.target) | ||
| body.target = opts.target; | ||
| if (opts.tags) | ||
| body.tags = opts.tags; | ||
| if (opts.note !== undefined) | ||
| body.note = opts.note; | ||
| const res = await this.fetcher.fetch(`${this.base}/connector/updateSession`, { method: 'POST', headers: this.jsonHeaders(), body: JSON.stringify(body) }, { maxRetries: 0, deadlineMs: 60_000 }); | ||
| const text = await res.text().catch(() => ''); | ||
| if (!res.ok) | ||
| throw new Error(`Connector updateSession failed (HTTP ${res.status}): ${text.slice(0, 300)}`); | ||
| if (/COLLECTION_NOT_FOUND|SESSION_NOT_FOUND/.test(text)) { | ||
| throw new Error(`Connector updateSession rejected: ${text}`); | ||
| } | ||
| } | ||
| /** | ||
| * Stream file bytes into a stored attachment under an item saved in this session. | ||
| * `url` is recorded as the attachment's source URL (it is NOT fetched by Zotero). | ||
| */ | ||
| async saveAttachment(opts) { | ||
| const metadata = { | ||
| sessionID: opts.sessionID, | ||
| parentItemID: opts.parentConnectorId, | ||
| url: opts.url, | ||
| title: opts.title ?? 'Full Text PDF', | ||
| }; | ||
| const bodyInit = opts.bytes; | ||
| const res = await this.fetcher.fetch(`${this.base}/connector/saveAttachment`, { | ||
| method: 'POST', | ||
| headers: { | ||
| ...this.jsonHeaders(), | ||
| 'Content-Type': opts.contentType, | ||
| 'X-Metadata': JSON.stringify(metadata), | ||
| }, | ||
| body: bodyInit, | ||
| }, { maxRetries: 0, deadlineMs: 300_000 }); | ||
| const text = await res.text().catch(() => ''); | ||
| if (!res.ok && res.status !== 201) { | ||
| throw new Error(`Connector saveAttachment failed (HTTP ${res.status}): ${text.slice(0, 300)}`); | ||
| } | ||
| if (/not editable/i.test(text)) | ||
| throw new Error(`Zotero refused the file: ${text}`); | ||
| this.logger?.info(`Connector session ${opts.sessionID}: attached ${opts.bytes.length} bytes (${opts.contentType}).`); | ||
| } | ||
| /** Current save target + full list of selectable targets (library and collections). */ | ||
| async getSelectedCollection() { | ||
| const res = await this.fetcher.fetch(`${this.base}/connector/getSelectedCollection`, { method: 'POST', headers: this.jsonHeaders(), body: '{}' }, { maxRetries: 0 }); | ||
| const json = (await res.json().catch(() => ({}))); | ||
| return { | ||
| current: typeof json.id === 'string' ? json.id : String(json.id ?? ''), | ||
| targets: Array.isArray(json.targets) ? json.targets : [], | ||
| }; | ||
| } | ||
| } | ||
| //# sourceMappingURL=connector-writes.js.map |
| {"version":3,"file":"connector-writes.js","sourceRoot":"","sources":["../../src/api/connector-writes.ts"],"names":[],"mappings":"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"} |
| import { RateLimitedFetcher } from './http.js'; | ||
| import type { WriteResult } from './web-client.js'; | ||
| import type { Logger } from '../lib/logger.js'; | ||
| export interface LocalWriteClientOptions { | ||
| /** Zotero desktop local-API port (default 23119). */ | ||
| port?: number; | ||
| fetcher?: RateLimitedFetcher; | ||
| logger?: Logger; | ||
| /** Where the granted local-API key is cached (default: <dataDir>/local-api-key.json). */ | ||
| keyStorePath?: string; | ||
| /** Pre-provisioned local API key (ZOTEUS_LOCAL_API_KEY); skips the authorize prompt. */ | ||
| key?: string; | ||
| /** App name shown in Zotero's grant dialog. */ | ||
| appName?: string; | ||
| } | ||
| /** | ||
| * Write client for the Zotero 9+ desktop local API. | ||
| * | ||
| * Zotero >= 9 accepts writes (POST/PATCH/DELETE) on the same local API the reads use | ||
| * (http://127.0.0.1:23119/api/users/0/...), gated by a *local* API key that the user | ||
| * grants through a one-time in-Zotero dialog: | ||
| * | ||
| * 1. Every response carries a `Zotero-Server-ID` header; writes must echo it back | ||
| * (428 when missing, 412 when it no longer matches the running instance). | ||
| * 2. `POST /api/local/authorize` with `{"appName": "..."}` shows a dialog in Zotero | ||
| * ("Allow" / "Always Allow" / "Deny") and returns `{key, remember}`. | ||
| * 3. Writes then carry `Zotero-API-Key: <key>`. A single-use key is consumed by the | ||
| * first successful write, so a 401 means: re-authorize. | ||
| * | ||
| * Keys are unrelated to zotero.org cloud keys. Grants are cached on disk so the user | ||
| * is prompted once ("Always Allow"); single-use "Allow" grants degrade gracefully by | ||
| * re-prompting on the next write. | ||
| */ | ||
| export declare class LocalWriteClient { | ||
| private readonly base; | ||
| private readonly fetcher; | ||
| private readonly logger?; | ||
| private readonly keyStorePath?; | ||
| private readonly appName; | ||
| private key?; | ||
| private serverId?; | ||
| constructor(opts?: LocalWriteClientOptions); | ||
| /** | ||
| * True when a local-API key is already available (env-provided or cached from a | ||
| * previous "Always Allow" grant) — i.e. writes can proceed without prompting. | ||
| */ | ||
| hasStoredKey(): boolean; | ||
| /** Stable ID of the running Zotero instance (required on every write). */ | ||
| getServerId(): Promise<string>; | ||
| /** | ||
| * Ask Zotero to grant this app a local API key. Blocks until the user answers the | ||
| * dialog in Zotero ("Always Allow" recommended). Returns the key, or throws with a | ||
| * human-readable reason on denial/error. | ||
| */ | ||
| authorize(): Promise<string>; | ||
| private readHeaders; | ||
| private writeHeaders; | ||
| private loadGrant; | ||
| private storeGrant; | ||
| private ensureKey; | ||
| /** | ||
| * Run a write request against the local API, transparently handling the two | ||
| * re-auth/re-probe cases: 401 (key consumed/unknown -> authorize again) and | ||
| * 412/428 (server-id stale/missing -> refresh it). | ||
| */ | ||
| private request; | ||
| /** Multi-write (create/update) up to 50 items, mirroring the Web API semantics. */ | ||
| writeItems(items: Record<string, unknown>[]): Promise<WriteResult>; | ||
| /** Partial single-item update. */ | ||
| patchItem(key: string, patch: Record<string, unknown>): Promise<number>; | ||
| /** Trash items by key (permanent=false, the default) or delete permanently. */ | ||
| deleteItems(keys: string[], permanent?: boolean): Promise<void>; | ||
| /** | ||
| * Store a file on a (child) attachment item using the Web-API 3-phase upload flow, | ||
| * which the local API re-implements: authorize -> POST bytes to the returned URL -> | ||
| * register the uploadKey. | ||
| */ | ||
| uploadFile(attachmentKey: string, file: { | ||
| bytes: Uint8Array; | ||
| filename: string; | ||
| contentType: string; | ||
| mtimeMs?: number; | ||
| }): Promise<void>; | ||
| private parseWriteResult; | ||
| private throwApi; | ||
| } |
| import { createHash } from 'node:crypto'; | ||
| import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'; | ||
| import { dirname } from 'node:path'; | ||
| import { RateLimitedFetcher } from './http.js'; | ||
| import { ZoteroApiError } from './errors.js'; | ||
| /** | ||
| * Write client for the Zotero 9+ desktop local API. | ||
| * | ||
| * Zotero >= 9 accepts writes (POST/PATCH/DELETE) on the same local API the reads use | ||
| * (http://127.0.0.1:23119/api/users/0/...), gated by a *local* API key that the user | ||
| * grants through a one-time in-Zotero dialog: | ||
| * | ||
| * 1. Every response carries a `Zotero-Server-ID` header; writes must echo it back | ||
| * (428 when missing, 412 when it no longer matches the running instance). | ||
| * 2. `POST /api/local/authorize` with `{"appName": "..."}` shows a dialog in Zotero | ||
| * ("Allow" / "Always Allow" / "Deny") and returns `{key, remember}`. | ||
| * 3. Writes then carry `Zotero-API-Key: <key>`. A single-use key is consumed by the | ||
| * first successful write, so a 401 means: re-authorize. | ||
| * | ||
| * Keys are unrelated to zotero.org cloud keys. Grants are cached on disk so the user | ||
| * is prompted once ("Always Allow"); single-use "Allow" grants degrade gracefully by | ||
| * re-prompting on the next write. | ||
| */ | ||
| export class LocalWriteClient { | ||
| base; | ||
| fetcher; | ||
| logger; | ||
| keyStorePath; | ||
| appName; | ||
| key; | ||
| serverId; | ||
| constructor(opts = {}) { | ||
| this.base = `http://127.0.0.1:${opts.port ?? 23119}/api`; | ||
| this.fetcher = opts.fetcher ?? new RateLimitedFetcher(); | ||
| this.logger = opts.logger; | ||
| this.keyStorePath = opts.keyStorePath; | ||
| this.appName = opts.appName ?? 'Zoteus MCP'; | ||
| this.key = opts.key; | ||
| } | ||
| /** | ||
| * True when a local-API key is already available (env-provided or cached from a | ||
| * previous "Always Allow" grant) — i.e. writes can proceed without prompting. | ||
| */ | ||
| hasStoredKey() { | ||
| if (this.key) | ||
| return true; | ||
| return Boolean(this.loadGrant()?.key); | ||
| } | ||
| /** Stable ID of the running Zotero instance (required on every write). */ | ||
| async getServerId() { | ||
| if (this.serverId) | ||
| return this.serverId; | ||
| const res = await this.fetcher.fetch(`${this.base}/users/0/items?limit=1`, { method: 'GET', headers: this.readHeaders() }, { maxRetries: 0 }); | ||
| if (!res.ok) | ||
| throw new Error(`Local API unreachable (HTTP ${res.status}) — is Zotero running?`); | ||
| const id = res.headers.get('zotero-server-id'); | ||
| await res.body?.cancel().catch(() => { }); | ||
| if (!id) | ||
| throw new Error('Local API did not return a Zotero-Server-ID header (Zotero >= 9 required for writes).'); | ||
| this.serverId = id; | ||
| return id; | ||
| } | ||
| /** | ||
| * Ask Zotero to grant this app a local API key. Blocks until the user answers the | ||
| * dialog in Zotero ("Always Allow" recommended). Returns the key, or throws with a | ||
| * human-readable reason on denial/error. | ||
| */ | ||
| async authorize() { | ||
| this.logger?.info(`Requesting local API write access from Zotero (appName="${this.appName}")…`); | ||
| const res = await this.fetcher.fetch(`${this.base}/local/authorize`, { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json', 'Zotero-API-Version': '3' }, | ||
| body: JSON.stringify({ appName: this.appName }), | ||
| }, { maxRetries: 0, deadlineMs: 300_000 }); | ||
| const text = await res.text().catch(() => ''); | ||
| if (res.status === 403) { | ||
| throw new Error('Zotero local write access was denied. Re-run when you can accept the dialog in Zotero.'); | ||
| } | ||
| if (res.status === 429) { | ||
| throw new Error('Too many local-API authorization prompts; wait a minute and try again.'); | ||
| } | ||
| if (!res.ok) { | ||
| throw new Error(`Local API authorize failed (HTTP ${res.status}): ${text || res.statusText}. ` + | ||
| 'Writes need Zotero 9+ with the local API enabled.'); | ||
| } | ||
| const { key, remember } = JSON.parse(text); | ||
| this.key = key; | ||
| this.storeGrant({ key, appName: this.appName, serverId: this.serverId, remember, grantedAt: new Date().toISOString() }); | ||
| this.logger?.info(`Local API write access granted (remember=${!!remember}).`); | ||
| return key; | ||
| } | ||
| readHeaders() { | ||
| return { 'Zotero-API-Version': '3', 'x-zotero-connector-api-version': '3' }; | ||
| } | ||
| async writeHeaders() { | ||
| return { | ||
| ...this.readHeaders(), | ||
| 'Zotero-API-Key': this.key ?? (await this.authorize()), | ||
| 'Zotero-Server-ID': await this.getServerId(), | ||
| }; | ||
| } | ||
| loadGrant() { | ||
| if (!this.keyStorePath) | ||
| return null; | ||
| try { | ||
| return JSON.parse(readFileSync(this.keyStorePath, 'utf8')); | ||
| } | ||
| catch { | ||
| return null; | ||
| } | ||
| } | ||
| storeGrant(grant) { | ||
| if (!this.keyStorePath) | ||
| return; | ||
| try { | ||
| mkdirSync(dirname(this.keyStorePath), { recursive: true }); | ||
| writeFileSync(this.keyStorePath, JSON.stringify(grant, null, 2)); | ||
| } | ||
| catch (e) { | ||
| this.logger?.warn(`Could not persist local API grant: ${e}`); | ||
| } | ||
| } | ||
| async ensureKey() { | ||
| if (this.key) | ||
| return; | ||
| const grant = this.loadGrant(); | ||
| if (grant?.key) { | ||
| this.key = grant.key; | ||
| this.serverId = this.serverId ?? grant.serverId; | ||
| } | ||
| } | ||
| /** | ||
| * Run a write request against the local API, transparently handling the two | ||
| * re-auth/re-probe cases: 401 (key consumed/unknown -> authorize again) and | ||
| * 412/428 (server-id stale/missing -> refresh it). | ||
| */ | ||
| async request(method, path, init = {}, retried = false) { | ||
| await this.ensureKey(); | ||
| if (!this.key) | ||
| await this.authorize(); | ||
| const headers = await this.writeHeaders(); | ||
| if (init.json !== undefined) { | ||
| headers['Content-Type'] = 'application/json'; | ||
| } | ||
| else if (init.form) { | ||
| headers['Content-Type'] = 'application/x-www-form-urlencoded'; | ||
| } | ||
| const res = await this.fetcher.fetch(`${this.base}${path}`, { | ||
| method, | ||
| headers: { ...headers, ...init.headers }, | ||
| body: init.json !== undefined ? JSON.stringify(init.json) : init.form?.toString(), | ||
| }, { maxRetries: 0, deadlineMs: 120_000 }); | ||
| if (res.status === 401 && !retried) { | ||
| this.logger?.info('Local API key rejected (401); requesting a fresh grant from Zotero…'); | ||
| this.key = undefined; | ||
| await this.authorize(); | ||
| return this.request(method, path, init, true); | ||
| } | ||
| if ((res.status === 412 || res.status === 428) && !retried) { | ||
| this.serverId = undefined; | ||
| await res.body?.cancel().catch(() => { }); | ||
| return this.request(method, path, init, true); | ||
| } | ||
| return res; | ||
| } | ||
| /** Multi-write (create/update) up to 50 items, mirroring the Web API semantics. */ | ||
| async writeItems(items) { | ||
| const res = await this.request('POST', '/users/0/items', { json: items }); | ||
| return this.parseWriteResult(res); | ||
| } | ||
| /** Partial single-item update. */ | ||
| async patchItem(key, patch) { | ||
| const res = await this.request('PATCH', `/users/0/items/${key}`, { json: patch }); | ||
| if (!res.ok) | ||
| await this.throwApi(res, `PATCH /items/${key}`); | ||
| const v = Number(res.headers.get('last-modified-version')); | ||
| await res.body?.cancel().catch(() => { }); | ||
| return Number.isFinite(v) ? v : 0; | ||
| } | ||
| /** Trash items by key (permanent=false, the default) or delete permanently. */ | ||
| async deleteItems(keys, permanent = false) { | ||
| const path = `/users/0/items${permanent ? '/deleted' : ''}?itemKey=${keys.join(',')}`; | ||
| const res = await this.request('DELETE', path); | ||
| if (!res.ok && res.status !== 204) | ||
| await this.throwApi(res, `DELETE ${path}`); | ||
| await res.body?.cancel().catch(() => { }); | ||
| } | ||
| /** | ||
| * Store a file on a (child) attachment item using the Web-API 3-phase upload flow, | ||
| * which the local API re-implements: authorize -> POST bytes to the returned URL -> | ||
| * register the uploadKey. | ||
| */ | ||
| async uploadFile(attachmentKey, file) { | ||
| const md5 = createHash('md5').update(file.bytes).digest('hex'); | ||
| const mtime = file.mtimeMs ?? Date.now(); | ||
| const authorize = await this.request('POST', `/users/0/items/${attachmentKey}/file`, { | ||
| form: new URLSearchParams({ | ||
| md5, | ||
| filename: file.filename, | ||
| filesize: String(file.bytes.length), | ||
| mtime: String(mtime), | ||
| contentType: file.contentType, | ||
| }), | ||
| headers: { 'If-None-Match': '*' }, | ||
| }); | ||
| if (!authorize.ok) | ||
| await this.throwApi(authorize, `authorize upload for ${attachmentKey}`); | ||
| const auth = (await authorize.json()); | ||
| if (auth.exists) | ||
| return; // identical file already stored | ||
| if (!auth.url || !auth.uploadKey) | ||
| throw new Error('Local API did not return an upload URL.'); | ||
| const bodyInit = file.bytes; | ||
| const up = await this.fetcher.fetch(auth.url, { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/octet-stream' }, | ||
| body: bodyInit, | ||
| }, { maxRetries: 0, deadlineMs: 300_000 }); | ||
| if (!up.ok) | ||
| await this.throwApi(up, 'file-bytes upload'); | ||
| await up.body?.cancel().catch(() => { }); | ||
| const register = await this.request('POST', `/users/0/items/${attachmentKey}/file`, { | ||
| form: new URLSearchParams({ upload: auth.uploadKey }), | ||
| headers: { 'If-None-Match': '*' }, | ||
| }); | ||
| if (!register.ok && register.status !== 204) | ||
| await this.throwApi(register, 'register upload'); | ||
| await register.body?.cancel().catch(() => { }); | ||
| } | ||
| async parseWriteResult(res) { | ||
| if (!res.ok) | ||
| await this.throwApi(res, 'local write'); | ||
| const json = (await res.json().catch(() => ({}))); | ||
| const successful = []; | ||
| for (const [idx, obj] of Object.entries(json.successful ?? {})) { | ||
| successful.push({ index: Number(idx), key: obj.key, version: obj.version }); | ||
| } | ||
| const failed = []; | ||
| for (const [idx, obj] of Object.entries(json.failed ?? {})) { | ||
| failed.push({ index: Number(idx), code: obj.code ?? 0, message: obj.message ?? 'write failed', key: obj.key }); | ||
| } | ||
| return { | ||
| successful, | ||
| unchanged: Object.keys(json.unchanged ?? {}), | ||
| failed, | ||
| newLibraryVersion: Number(res.headers.get('last-modified-version')) || 0, | ||
| }; | ||
| } | ||
| async throwApi(res, what) { | ||
| const body = await res.text().catch(() => ''); | ||
| throw new ZoteroApiError({ status: res.status, message: `Local API ${what} failed (${res.status}): ${body.slice(0, 400)}`, body }); | ||
| } | ||
| } | ||
| //# sourceMappingURL=local-writes.js.map |
| {"version":3,"file":"local-writes.js","sourceRoot":"","sources":["../../src/api/local-writes.ts"],"names":[],"mappings":"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"} |
| import type { ToolContext } from '../../registry/registry.js'; | ||
| import type { LibraryRef } from '../../api/web-client.js'; | ||
| import type { IndexBuildStatus } from './index-manager.js'; | ||
| /** Hard cap on items per build — keeps very large libraries bounded. */ | ||
| export declare const MAX_ITEMS = 5000; | ||
| /** The Zotero Web API pages items 100-at-a-time. */ | ||
| export declare const PAGE_SIZE = 100; | ||
| /** One-line progress summary used in tool messages and status output. */ | ||
| export declare function progressLine(s: IndexBuildStatus): string; | ||
| /** Human summary of a build/status snapshot. */ | ||
| export declare function statusSummary(s: IndexBuildStatus): string; | ||
| /** | ||
| * Kick off the incremental background index build used by zotero_index and by | ||
| * zotero_semantic_search's auto-build. Fire-and-forget: the build runs on the | ||
| * server event loop; callers poll `ctx.search.buildStatus()` for progress. | ||
| * Throws if a build is already running. | ||
| */ | ||
| export declare function startIndexBuild(ctx: ToolContext, lib?: LibraryRef, maxItems?: number): IndexBuildStatus; |
| import { saveIndex } from './persistence.js'; | ||
| /** Hard cap on items per build — keeps very large libraries bounded. */ | ||
| export const MAX_ITEMS = 5000; | ||
| /** The Zotero Web API pages items 100-at-a-time. */ | ||
| export const PAGE_SIZE = 100; | ||
| /** One-line progress summary used in tool messages and status output. */ | ||
| export function progressLine(s) { | ||
| const total = s.itemsTotal > 0 ? String(s.itemsTotal) : '?'; | ||
| return `${s.itemsFetched}/${total} items, ${s.passages} passages, ${s.vectors} vectors (embedder=${s.embedder})`; | ||
| } | ||
| /** Human summary of a build/status snapshot. */ | ||
| export function statusSummary(s) { | ||
| switch (s.state) { | ||
| case 'building': | ||
| return `Index build in progress — ${progressLine(s)}. Poll zotero_index action:"status" again shortly.`; | ||
| case 'error': | ||
| return `Index build failed: ${s.lastError ?? 'unknown error'}. Partial data kept — ${progressLine(s)}.`; | ||
| case 'done': | ||
| return `Index ready — ${s.documents} passages over ${s.items} items (embedder=${s.embedder}). Run zotero_semantic_search to search by meaning.`; | ||
| default: | ||
| return `Index: ${s.documents} passages over ${s.items} items; embedder=${s.embedder}.`; | ||
| } | ||
| } | ||
| /** | ||
| * Kick off the incremental background index build used by zotero_index and by | ||
| * zotero_semantic_search's auto-build. Fire-and-forget: the build runs on the | ||
| * server event loop; callers poll `ctx.search.buildStatus()` for progress. | ||
| * Throws if a build is already running. | ||
| */ | ||
| export function startIndexBuild(ctx, lib, maxItems = MAX_ITEMS) { | ||
| const library = lib ?? ctx.router.defaultLibrary(); | ||
| const cap = Math.min(maxItems, MAX_ITEMS); | ||
| const fetchPage = async (start) => { | ||
| const page = await ctx.web.listItems(library, { limit: PAGE_SIZE, start, top: true }); | ||
| return { items: page.data, totalResults: page.totalResults }; | ||
| }; | ||
| const persist = ctx.searchIndexPath | ||
| ? () => saveIndex(ctx.search, ctx.searchIndexPath).catch((e) => ctx.logger.warn(`Could not persist index: ${e instanceof Error ? e.message : String(e)}`)) | ||
| : undefined; | ||
| const job = ctx.search.buildIncremental(fetchPage, { maxItems: cap, persist }); | ||
| job.catch((e) => ctx.logger.error(`Index build crashed: ${e instanceof Error ? e.message : String(e)}`)); | ||
| return ctx.search.buildStatus(); | ||
| } | ||
| //# sourceMappingURL=build.js.map |
| {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/features/search/build.ts"],"names":[],"mappings":"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"} |
| import type { ToolDefinition } from '../registry/registry.js'; | ||
| /** | ||
| * Normalize a caller-supplied position into Zotero's stored form: | ||
| * {"pageIndex": <0-based page>, "rects": [[x1, y1, x2, y2], ...]} | ||
| * Points, origin at the BOTTOM-LEFT of the page (native PDF coordinate space, y | ||
| * increasing upward). Accepts | ||
| * either that object directly (or its JSON string) or the shorthand | ||
| * [pageIndex, [x1, y1, x2, y2]]. | ||
| */ | ||
| export declare function normalizePosition(position: unknown, page?: number): { | ||
| pageIndex: number; | ||
| rects: number[][]; | ||
| } | null; | ||
| /** | ||
| * Replicates the PDF reader's sort-index scheme so annotations order correctly in | ||
| * the sidebar: `PPPPP|OOOOOO|TTTTT` (5-digit page | 6-digit char offset | 5-digit | ||
| * distance of the topmost rect from the page bottom). Callers that extracted the | ||
| * highlight from the PDF itself can pass the exact offset; otherwise offset 0 with | ||
| * the rect-derived `top` still keeps same-page highlights in reading order. | ||
| */ | ||
| export declare function buildSortIndex(pageIndex: number, rects: number[][], opts?: { | ||
| offset?: number; | ||
| pageHeight?: number; | ||
| }): string; | ||
| declare const annotateTool: ToolDefinition; | ||
| export default annotateTool; |
| import { z } from 'zod'; | ||
| import { ok, requireCloudLibrary, isLocalWritesUnavailable, ensureLocalApi } from '../registry/registry.js'; | ||
| /** | ||
| * Normalize a caller-supplied position into Zotero's stored form: | ||
| * {"pageIndex": <0-based page>, "rects": [[x1, y1, x2, y2], ...]} | ||
| * Points, origin at the BOTTOM-LEFT of the page (native PDF coordinate space, y | ||
| * increasing upward). Accepts | ||
| * either that object directly (or its JSON string) or the shorthand | ||
| * [pageIndex, [x1, y1, x2, y2]]. | ||
| */ | ||
| export function normalizePosition(position, page) { | ||
| if (position == null) { | ||
| return page != null ? { pageIndex: page, rects: [] } : null; | ||
| } | ||
| if (typeof position === 'string') { | ||
| try { | ||
| return normalizePosition(JSON.parse(position), page); | ||
| } | ||
| catch { | ||
| return null; | ||
| } | ||
| } | ||
| if (Array.isArray(position) && position.length === 2 && typeof position[0] === 'number') { | ||
| const rect = position[1]; | ||
| if (Array.isArray(rect) && rect.length === 4 && rect.every((n) => typeof n === 'number')) { | ||
| return { pageIndex: position[0], rects: [rect] }; | ||
| } | ||
| return null; | ||
| } | ||
| const p = position; | ||
| if (typeof p.pageIndex === 'number' && Array.isArray(p.rects)) { | ||
| const rects = p.rects.filter((r) => Array.isArray(r) && r.length === 4 && r.every((n) => typeof n === 'number')); | ||
| return { pageIndex: p.pageIndex, rects }; | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Replicates the PDF reader's sort-index scheme so annotations order correctly in | ||
| * the sidebar: `PPPPP|OOOOOO|TTTTT` (5-digit page | 6-digit char offset | 5-digit | ||
| * distance of the topmost rect from the page bottom). Callers that extracted the | ||
| * highlight from the PDF itself can pass the exact offset; otherwise offset 0 with | ||
| * the rect-derived `top` still keeps same-page highlights in reading order. | ||
| */ | ||
| export function buildSortIndex(pageIndex, rects, opts = {}) { | ||
| const pad = (n, w) => String(Math.max(0, Math.floor(n))).slice(0, w).padStart(w, '0'); | ||
| let top = 0; | ||
| if (rects.length && opts.pageHeight) { | ||
| // Topmost rect: the reader sorts rects by their third coordinate descending | ||
| // and takes the first; mirror that exactly. | ||
| const topRect = rects.slice().sort((a, b) => (b[2] ?? 0) - (a[2] ?? 0))[0] ?? [0, 0, 0, 0]; | ||
| top = Math.max(0, opts.pageHeight - (topRect[3] ?? 0)); | ||
| } | ||
| return `${pad(pageIndex, 5)}|${pad(opts.offset ?? 0, 6)}|${pad(Math.floor(top), 5)}`; | ||
| } | ||
| const annotationSchema = z.object({ | ||
| type: z.enum(['highlight', 'note', 'underline', 'image']).optional() | ||
| .describe('Annotation type; default "highlight".'), | ||
| text: z.string().optional() | ||
| .describe('The highlighted/underlined passage itself (required for highlight/underline). For notes, goes in annotationText of an extracted-text style note or leave to `comment`.'), | ||
| comment: z.string().optional().describe('Comment attached to the annotation (markdown-ish plain text).'), | ||
| color: z.string().optional().describe('Hex color, e.g. "#ffd400" (highlight default) or "#26a69a".'), | ||
| page: z.number().int().optional().describe('0-based PDF page index (annotationPageLabel uses page+1 when unset).'), | ||
| page_label: z.string().optional().describe('Explicit page label (overrides page+1).'), | ||
| position: z.union([z.string(), z.any()]).optional() | ||
| .describe('Zotero position: {"pageIndex": N, "rects": [[x1,y1,x2,y2],...]} (points, bottom-left origin), its JSON string, or shorthand [N, [x1,y1,x2,y2]]. Required for highlights/underlines to render in place.'), | ||
| sort_index: z.string().optional().describe('Explicit annotationSortIndex; computed from position when omitted.'), | ||
| char_offset: z.number().int().optional().describe('Reading-order character offset of the passage start on the page (refines sort_index).'), | ||
| page_height: z.number().optional().describe('Page height in points (refines sort_index, e.g. 841.89 for A4).'), | ||
| tags: z.array(z.string()).optional().describe('Tags to attach to the annotation.'), | ||
| }); | ||
| const annotateTool = { | ||
| name: 'zotero_annotate', | ||
| title: 'Annotate a PDF (highlights, notes)', | ||
| description: 'Add or delete Zotero PDF annotations (highlights, underlines, notes) — the same objects you create in the Zotero PDF reader. `action:"add"` needs `parent` (a regular item key OR a PDF attachment key) and `annotations`: each with `type` (highlight|note|underline, default highlight), `text` (the exact highlighted passage), optional `comment`, `color`, `page` (0-based page index), and `position` ({"pageIndex":N,"rects":[[x1,y1,x2,y2],...]} in PDF points with bottom-left origin — without a position a highlight cannot render in place). `action:"delete"` trashes the annotations in `annotation_keys`. Writes go to the running Zotero desktop app for your personal library (via its connector protocol, or its local-API writes where available), otherwise to the cloud Web API.', | ||
| inputSchema: { | ||
| action: z.enum(['add', 'delete']).optional().describe('Default "add".'), | ||
| parent: z.string().optional().describe('Item key or PDF attachment key to annotate.'), | ||
| annotations: z.array(annotationSchema).optional().describe('Annotations to add.'), | ||
| annotation_keys: z.array(z.string()).optional().describe('Annotation keys to trash (action:"delete").'), | ||
| library_type: z.enum(['user', 'group']).optional(), | ||
| library_id: z.number().int().optional(), | ||
| }, | ||
| annotations: { readOnlyHint: false, openWorldHint: true }, | ||
| handler: async (args, ctx) => { | ||
| const action = args.action ?? 'add'; | ||
| if (action === 'delete') { | ||
| const keys = args.annotation_keys ?? []; | ||
| if (!keys.length) { | ||
| return { content: [{ type: 'text', text: '`annotation_keys` is required for action:"delete".' }], isError: true }; | ||
| } | ||
| if (!args.library_id && (await ensureLocalApi(ctx)) && ctx.localWrites) { | ||
| try { | ||
| await ctx.localWrites.deleteItems(keys, false); | ||
| return ok({ trashed: keys, target: 'local' }, `Trashed ${keys.length} annotation(s) via the Zotero desktop app.`); | ||
| } | ||
| catch (e) { | ||
| if (!isLocalWritesUnavailable(e)) | ||
| throw e; | ||
| // Running Zotero has no local-API writes; fall through to cloud/guidance. | ||
| } | ||
| } | ||
| if (ctx.capabilities.cloud) { | ||
| const lib = requireCloudLibrary(ctx, args); | ||
| const objects = []; | ||
| for (const key of keys) { | ||
| const item = await ctx.web.getItem(lib, key); | ||
| objects.push({ key, version: item?.version ?? item?.data?.version, deleted: 1 }); | ||
| } | ||
| const result = await ctx.web.writeItems(lib, objects); | ||
| return ok({ trashed: result.successful.map((s) => s.key), failed: result.failed, target: 'cloud' }, `Trashed ${result.successful.length} annotation(s) via the cloud Web API.`); | ||
| } | ||
| return { | ||
| content: [{ | ||
| type: 'text', | ||
| text: 'Deleting annotations needs write access this Zotero cannot grant yet: the running app\u2019s local API is read-only (Zotero < 9.1) and the connector protocol cannot delete. Set ZOTERO_API_KEY for cloud writes, upgrade Zotero when local writes ship, or delete the annotations manually in Zotero\u2019s PDF reader.', | ||
| }], | ||
| isError: true, | ||
| }; | ||
| } | ||
| // --- add --- | ||
| if (!args.parent) { | ||
| return { content: [{ type: 'text', text: '`parent` (item key or PDF attachment key) is required for action:"add".' }], isError: true }; | ||
| } | ||
| const parentKey = args.parent; | ||
| const anns = args.annotations ?? []; | ||
| if (!anns.length) { | ||
| return { content: [{ type: 'text', text: '`annotations` must contain at least one entry.' }], isError: true }; | ||
| } | ||
| // Resolve the PDF attachment: the parent may be the attachment itself or any | ||
| // regular item whose children include a stored/linked PDF. | ||
| const parentItem = await ctx.router.getItem(parentKey); | ||
| const parentData = parentItem?.data ?? parentItem; | ||
| let attachmentKey; | ||
| if (parentData?.itemType === 'attachment') { | ||
| attachmentKey = parentData.key ?? parentKey; | ||
| } | ||
| else { | ||
| const children = await ctx.router.getItemChildren(parentKey); | ||
| const pdf = children.data | ||
| .map((c) => c?.data ?? c) | ||
| .filter((c) => c?.itemType === 'attachment') | ||
| .sort((a, b) => scorePdf(b) - scorePdf(a))[0]; | ||
| attachmentKey = pdf?.key; | ||
| if (!attachmentKey) { | ||
| return { | ||
| content: [{ type: 'text', text: `No PDF attachment found under item ${parentKey}. Add the PDF first (or pass the attachment key directly).` }], | ||
| isError: true, | ||
| }; | ||
| } | ||
| } | ||
| if (!attachmentKey) { | ||
| return { content: [{ type: 'text', text: 'Could not resolve a PDF attachment.' }], isError: true }; | ||
| } | ||
| const targetAttachment = attachmentKey; | ||
| // Build annotation items in Zotero's data model. | ||
| const items = []; | ||
| const problems = []; | ||
| anns.forEach((a, i) => { | ||
| const type = a.type ?? 'highlight'; | ||
| if ((type === 'highlight' || type === 'underline') && !a.text) { | ||
| problems.push(`annotations[${i}]: ${type} requires \`text\` (the exact passage).`); | ||
| return; | ||
| } | ||
| const pos = normalizePosition(a.position, a.page); | ||
| if ((type === 'highlight' || type === 'underline') && !pos?.rects?.length) { | ||
| problems.push(`annotations[${i}]: ${type} needs \`position\` ({"pageIndex":N,"rects":[[x1,y1,x2,y2],...]}) to render in place.`); | ||
| return; | ||
| } | ||
| const pageIndex = pos?.pageIndex ?? a.page ?? 0; | ||
| const item = { | ||
| itemType: 'annotation', | ||
| parentItem: targetAttachment, | ||
| annotationType: type, | ||
| annotationColor: a.color ?? (type === 'note' ? '#26a69a' : '#ffd400'), | ||
| annotationSortIndex: a.sort_index ?? buildSortIndex(pageIndex, pos?.rects ?? [], { offset: a.char_offset, pageHeight: a.page_height }), | ||
| annotationPosition: JSON.stringify(pos ?? { pageIndex, rects: [] }), | ||
| tags: (a.tags ?? []).map((t) => ({ tag: t })), | ||
| }; | ||
| if (a.text) | ||
| item.annotationText = a.text; | ||
| if (a.comment) | ||
| item.annotationComment = a.comment; | ||
| const label = a.page_label ?? String(pageIndex + 1); | ||
| if (label) | ||
| item.annotationPageLabel = label; | ||
| items.push(item); | ||
| }); | ||
| if (problems.length) { | ||
| return { content: [{ type: 'text', text: `Nothing was written:\n- ${problems.join('\n- ')}` }], isError: true }; | ||
| } | ||
| // Prefer the desktop app for the personal library; fall back to the cloud. | ||
| // (a) Zotero with local-API write support (upcoming; needs a stored/provided key — | ||
| // we never trigger the grant dialog unexpectedly), or (b) the connector protocol | ||
| // that every recent Zotero exposes while running. | ||
| if (!args.library_id && (await ensureLocalApi(ctx)) && ctx.localWrites) { | ||
| try { | ||
| const result = await ctx.localWrites.writeItems(items); | ||
| if (result.failed.length) { | ||
| return { content: [{ type: 'text', text: `Local write failed: ${JSON.stringify(result.failed)}` }], isError: true }; | ||
| } | ||
| return ok({ | ||
| target: 'local', | ||
| attachment: targetAttachment, | ||
| created: result.successful.map((s, i) => ({ key: s.key, type: items[i]?.annotationType, text: items[i]?.annotationText ?? '', comment: items[i]?.annotationComment ?? '' })), | ||
| }, `Added ${result.successful.length} annotation(s) to PDF ${targetAttachment} via the Zotero desktop app.`); | ||
| } | ||
| catch (e) { | ||
| if (!isLocalWritesUnavailable(e)) | ||
| throw e; | ||
| ctx.logger.info(`Local-API writes unavailable (${e instanceof Error ? e.message : e}); using the connector protocol.`); | ||
| } | ||
| } | ||
| if (!args.library_id && ctx.connectorWrites && (await ensureLocalApi(ctx))) { | ||
| const { sessionID } = await ctx.connectorWrites.saveItems(items, { uri: 'zotero://zoteus/annotate' }); | ||
| // The connector returns no keys; recover them by querying the local API. | ||
| const created = await pollCreatedAnnotations(ctx, targetAttachment, items); | ||
| return ok({ | ||
| target: 'desktop', | ||
| sessionID, | ||
| attachment: targetAttachment, | ||
| created, | ||
| note: created.length < items.length | ||
| ? 'Some annotations could not be matched back yet; they may still appear in Zotero (check the PDF sidebar).' | ||
| : undefined, | ||
| }, `Added ${created.length}/${items.length} annotation(s) to PDF ${targetAttachment} via the running Zotero desktop app.`); | ||
| } | ||
| const lib = requireCloudLibrary(ctx, args); | ||
| const result = await ctx.web.writeItems(lib, items); | ||
| return ok({ | ||
| target: 'cloud', | ||
| attachment: targetAttachment, | ||
| created: result.successful.map((s, i) => ({ key: s.key, type: items[i]?.annotationType })), | ||
| failed: result.failed, | ||
| }, `Added ${result.successful.length} annotation(s) to PDF ${targetAttachment} via the cloud Web API.`); | ||
| }, | ||
| }; | ||
| /** Rank attachment children: stored PDFs first, then linked PDFs, then anything else. */ | ||
| function scorePdf(att) { | ||
| if (att?.contentType !== 'application/pdf') | ||
| return 0; | ||
| const lm = att?.linkMode; | ||
| if (lm === 'imported_file') | ||
| return 3; | ||
| if (lm === 'imported_url') | ||
| return 2; | ||
| if (lm === 'linked_file' || lm === 'linked_url') | ||
| return 1; | ||
| return 1; | ||
| } | ||
| export default annotateTool; | ||
| /** | ||
| * Recover the item keys of annotations just created through the connector protocol | ||
| * (which returns no payload) by querying the desktop local API for the attachment's | ||
| * annotation children and matching them against what we sent. | ||
| */ | ||
| async function pollCreatedAnnotations(ctx, attachmentKey, sent) { | ||
| const wanted = new Map(); | ||
| for (const it of sent) { | ||
| const fingerprint = `${it.annotationType ?? ''}::${(it.annotationText ?? '')}`; | ||
| wanted.set(fingerprint, it); | ||
| } | ||
| const found = []; | ||
| const deadline = Date.now() + 15_000; | ||
| while (wanted.size && Date.now() < deadline) { | ||
| try { | ||
| // Must be the /children endpoint: the local API ignores a `parentItem` filter | ||
| // on /items and would hand back the entire library instead. | ||
| const res = await ctx.local.getItemChildren(attachmentKey, { itemType: 'annotation', limit: 100 }); | ||
| for (const child of res.data) { | ||
| const d = child?.data ?? child; | ||
| if (d?.itemType && d.itemType !== 'annotation') | ||
| continue; | ||
| const fingerprint = `${d?.annotationType ?? ''}::${d?.annotationText ?? ''}`; | ||
| if (wanted.has(fingerprint)) { | ||
| wanted.delete(fingerprint); | ||
| found.push({ | ||
| key: d.key, | ||
| type: d.annotationType, | ||
| text: d.annotationText ?? '', | ||
| comment: d.annotationComment ?? '', | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| catch { | ||
| // Local API hiccup; keep polling until the deadline. | ||
| } | ||
| if (wanted.size) | ||
| await new Promise((r) => setTimeout(r, 750)); | ||
| } | ||
| return found; | ||
| } | ||
| //# sourceMappingURL=annotate.js.map |
| {"version":3,"file":"annotate.js","sourceRoot":"","sources":["../../src/tools/annotate.ts"],"names":[],"mappings":"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"} |
| import type { ToolDefinition } from '../registry/registry.js'; | ||
| /** | ||
| * Attach a file (local path or URL) to an item as a stored (imported_file) | ||
| * attachment. Requires the Zotero desktop app (Zotero 9+ local API writes), since | ||
| * the cloud client here does not implement the storage upload flow. | ||
| */ | ||
| declare const attachFile: ToolDefinition; | ||
| export default attachFile; |
| import { z } from 'zod'; | ||
| import { readFile } from 'node:fs/promises'; | ||
| import { ok, ensureLocalApi } from '../registry/registry.js'; | ||
| /** | ||
| * Attach a file (local path or URL) to an item as a stored (imported_file) | ||
| * attachment. Requires the Zotero desktop app (Zotero 9+ local API writes), since | ||
| * the cloud client here does not implement the storage upload flow. | ||
| */ | ||
| const attachFile = { | ||
| name: 'zotero_attach_file', | ||
| title: 'Attach a file (PDF, snapshot) to an item', | ||
| description: 'Add a stored file attachment (e.g. a PDF full text) under an existing item. Give `parent` (the item key) and either `path` (a local file the Zoteus process can read) or `url` (downloaded first). `filename` and `content_type` are inferred when omitted. Runs against the Zotero desktop app\u2019s local API (Zotero 9+; you may be asked once to allow Zoteus write access — choose "Always Allow"). Returns the new attachment key.', | ||
| inputSchema: { | ||
| parent: z.string().describe('Key of the parent item to attach the file to.'), | ||
| path: z.string().optional().describe('Local filesystem path to the file.'), | ||
| url: z.string().url().optional().describe('URL to download the file from.'), | ||
| filename: z.string().optional().describe('File name to store; inferred from path/url if omitted.'), | ||
| content_type: z.string().optional().describe('MIME type; inferred from the extension if omitted (pdf -> application/pdf).'), | ||
| title: z.string().optional().describe('Attachment title, e.g. "Full Text PDF".'), | ||
| }, | ||
| annotations: { readOnlyHint: false, openWorldHint: true }, | ||
| handler: async (args, ctx) => { | ||
| if (!ctx.localWrites || !(await ensureLocalApi(ctx))) { | ||
| return { | ||
| content: [{ type: 'text', text: 'Storing files needs Zotero desktop write access. If your Zotero has the upcoming local-API writes, provide a key via ZOTEUS_LOCAL_API_KEY (or grant it once); on current Zotero versions, attach files DURING import instead — zotero_import supports `attach_url`, which streams the file into the same save session. Otherwise set ZOTERO_API_KEY and use the cloud flow.' }], | ||
| isError: true, | ||
| }; | ||
| } | ||
| if (!args.path && !args.url) { | ||
| return { content: [{ type: 'text', text: 'Provide `path` or `url`.' }], isError: true }; | ||
| } | ||
| let bytes; | ||
| let inferredName; | ||
| if (args.path) { | ||
| bytes = new Uint8Array(await readFile(args.path)); | ||
| inferredName = args.path.split(/[\\/]/).pop() ?? 'attachment'; | ||
| } | ||
| else { | ||
| const res = await ctx.fetcher.fetch(args.url, { method: 'GET' }, { maxRetries: 2, deadlineMs: 300_000 }); | ||
| if (!res.ok) { | ||
| return { content: [{ type: 'text', text: `Download failed (${res.status}) for ${args.url}` }], isError: true }; | ||
| } | ||
| bytes = new Uint8Array(await res.arrayBuffer()); | ||
| const noQuery = args.url.split('?')[0] ?? args.url; | ||
| inferredName = decodeURIComponent(noQuery.split('/').pop() ?? 'attachment'); | ||
| } | ||
| const filename = args.filename ?? inferredName; | ||
| const ext = filename.split('.').pop()?.toLowerCase() ?? ''; | ||
| const contentType = args.content_type ?? | ||
| (ext === 'pdf' ? 'application/pdf' : ext === 'html' || ext === 'htm' ? 'text/html' : 'application/octet-stream'); | ||
| // 1) Create the attachment item, 2) upload + register the file bytes. | ||
| const result = await ctx.localWrites.writeItems([ | ||
| { | ||
| itemType: 'attachment', | ||
| parentItem: args.parent, | ||
| linkMode: 'imported_file', | ||
| title: args.title ?? filename, | ||
| contentType, | ||
| tags: [], | ||
| }, | ||
| ]); | ||
| if (result.failed.length || !result.successful.length) { | ||
| return { content: [{ type: 'text', text: `Could not create attachment item: ${JSON.stringify(result.failed)}` }], isError: true }; | ||
| } | ||
| const attachmentKey = result.successful[0]?.key; | ||
| if (!attachmentKey) { | ||
| return { content: [{ type: 'text', text: 'Local write returned no attachment key.' }], isError: true }; | ||
| } | ||
| await ctx.localWrites.uploadFile(attachmentKey, { bytes, filename, contentType }); | ||
| return ok({ attachment: attachmentKey, parent: args.parent, filename, bytes: bytes.length, contentType, target: 'local' }, `Attached ${filename} (${bytes.length} bytes) to item ${args.parent} as ${attachmentKey}.`); | ||
| }, | ||
| }; | ||
| export default attachFile; | ||
| //# sourceMappingURL=attach-file.js.map |
| {"version":3,"file":"attach-file.js","sourceRoot":"","sources":["../../src/tools/attach-file.ts"],"names":[],"mappings":"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"} |
@@ -27,2 +27,8 @@ import { RateLimitedFetcher } from './http.js'; | ||
| }): Promise<any>; | ||
| /** | ||
| * Children (attachments, notes, annotations) of an item. The desktop local API | ||
| * silently ignores a `parentItem` query param on /items and answers with the whole | ||
| * library, so the dedicated /children endpoint is the only correct way to ask. | ||
| */ | ||
| getItemChildren(key: string, query?: ItemQuery): Promise<ListResult>; | ||
| listCollections(query?: { | ||
@@ -29,0 +35,0 @@ top?: boolean; |
@@ -66,2 +66,12 @@ import { RateLimitedFetcher } from './http.js'; | ||
| } | ||
| /** | ||
| * Children (attachments, notes, annotations) of an item. The desktop local API | ||
| * silently ignores a `parentItem` query param on /items and answers with the whole | ||
| * library, so the dedicated /children endpoint is the only correct way to ask. | ||
| */ | ||
| async getItemChildren(key, query = {}) { | ||
| const { top: _t, collectionKey: _c, ...rest } = query; | ||
| const { json, headers } = await this.getJson(`/users/0/items/${key}/children`, this.buildQuery(rest)); | ||
| return this.toListResult(json, headers); | ||
| } | ||
| async listCollections(query = {}) { | ||
@@ -68,0 +78,0 @@ const segment = query.top ? '/collections/top' : '/collections'; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"local-client.js","sourceRoot":"","sources":["../../src/api/local-client.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"local-client.js","sourceRoot":"","sources":["../../src/api/local-client.ts"],"names":[],"mappings":"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"} |
+2
-0
| export interface ZoteusConfig { | ||
| apiKey?: string; | ||
| /** Pre-provisioned Zotero 9+ desktop local-API key (skips the grant dialog). */ | ||
| localApiKey?: string; | ||
| libraryId?: number; | ||
@@ -4,0 +6,0 @@ libraryType: 'user' | 'group'; |
+2
-0
@@ -20,2 +20,3 @@ import { z } from 'zod'; | ||
| ZOTERO_API_KEY: optionalNonEmpty(), | ||
| ZOTEUS_LOCAL_API_KEY: optionalNonEmpty(), | ||
| ZOTERO_LIBRARY_ID: z.coerce.number().int().positive().optional(), | ||
@@ -88,2 +89,3 @@ ZOTERO_LIBRARY_TYPE: z.enum(['user', 'group']).default('user'), | ||
| apiKey: parsed.ZOTERO_API_KEY, | ||
| localApiKey: parsed.ZOTEUS_LOCAL_API_KEY, | ||
| libraryId: parsed.ZOTERO_LIBRARY_ID, | ||
@@ -90,0 +92,0 @@ libraryType: parsed.ZOTERO_LIBRARY_TYPE, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"} |
@@ -16,3 +16,5 @@ /** | ||
| }): Promise<string[] | null>; | ||
| /** Join extracted page texts into one document text (pages separated by a blank line). */ | ||
| export declare function pdfPagesToText(pages: string[]): string; | ||
| /** 1-based page whose text contains the passage's leading window, or undefined. */ | ||
| export declare function locatePage(pages: string[], passage: string, headChars?: number): number | undefined; |
@@ -27,3 +27,6 @@ /** | ||
| try { | ||
| const loadingTask = pdfjs.getDocument({ data: bytes, useSystemFonts: true, isEvalSupported: false }); | ||
| // pdfjs transfers (detaches) the buffer it is given; hand it a copy so the | ||
| // caller's bytes stay intact (matters when the same buffer is re-extracted). | ||
| const data = bytes.slice(); | ||
| const loadingTask = pdfjs.getDocument({ data, useSystemFonts: true, isEvalSupported: false }); | ||
| const doc = await loadingTask.promise; | ||
@@ -42,2 +45,6 @@ const pages = []; | ||
| } | ||
| /** Join extracted page texts into one document text (pages separated by a blank line). */ | ||
| export function pdfPagesToText(pages) { | ||
| return pages.join('\n\n'); | ||
| } | ||
| function normalize(s) { | ||
@@ -44,0 +51,0 @@ return s.toLowerCase().replace(/\s+/g, ' ').trim(); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"pdf-pages.js","sourceRoot":"","sources":["../../../src/features/fulltext/pdf-pages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAEnE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAiB,EACjB,OAA8B,EAAE;IAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,yBAAyB,CAAC;IAC5D,gFAAgF;IAChF,IAAI,KAAK,CAAC,UAAU,GAAG,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,KAAU,CAAC;IACf,IAAI,CAAC;QACH,8CAA8C;QAC9C,KAAK,GAAG,MAAM,MAAM,CAAC,iCAAwC,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,qCAAqC;IACpD,CAAC;IACD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QACrG,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC;QACtC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAE,OAAO,CAAC,KAAe,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,wCAAwC;IACvD,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACrD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,KAAe,EAAE,OAAe,EAAE,SAAS,GAAG,EAAE;IACzE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"} | ||
| {"version":3,"file":"pdf-pages.js","sourceRoot":"","sources":["../../../src/features/fulltext/pdf-pages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAEnE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAiB,EACjB,OAA8B,EAAE;IAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,yBAAyB,CAAC;IAC5D,gFAAgF;IAChF,IAAI,KAAK,CAAC,UAAU,GAAG,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,KAAU,CAAC;IACf,IAAI,CAAC;QACH,8CAA8C;QAC9C,KAAK,GAAG,MAAM,MAAM,CAAC,iCAAwC,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,qCAAqC;IACpD,CAAC;IACD,IAAI,CAAC;QACH,2EAA2E;QAC3E,6EAA6E;QAC7E,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9F,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC;QACtC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAE,OAAO,CAAC,KAAe,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,wCAAwC;IACvD,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,KAAe;IAC5C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACrD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU,CAAC,KAAe,EAAE,OAAe,EAAE,SAAS,GAAG,EAAE;IACzE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"} |
@@ -15,6 +15,17 @@ import type { ZoteusConfig } from '../../config.js'; | ||
| private readonly model; | ||
| /** Injectable extractor factory (tests); defaults to the transformers.js pipeline. */ | ||
| private readonly loadExtractor?; | ||
| readonly name = "local"; | ||
| /** Texts handed to the transformers pipeline in a single call. */ | ||
| static readonly BATCH_SIZE = 32; | ||
| private extractor; | ||
| constructor(model?: string); | ||
| constructor(model?: string, | ||
| /** Injectable extractor factory (tests); defaults to the transformers.js pipeline. */ | ||
| loadExtractor?: (() => Promise<any>) | undefined); | ||
| private ensure; | ||
| /** | ||
| * Embed texts in batches through the pipeline (one call per batch instead of one | ||
| * per text), yielding to the event loop between batches so long builds stay | ||
| * responsive and interruptible. Returns exactly one vector per input text. | ||
| */ | ||
| embed(texts: string[]): Promise<number[][]>; | ||
@@ -21,0 +32,0 @@ } |
@@ -23,6 +23,12 @@ const DIM = 64; | ||
| model; | ||
| loadExtractor; | ||
| name = 'local'; | ||
| /** Texts handed to the transformers pipeline in a single call. */ | ||
| static BATCH_SIZE = 32; | ||
| extractor; | ||
| constructor(model = 'Xenova/all-MiniLM-L6-v2') { | ||
| constructor(model = 'Xenova/all-MiniLM-L6-v2', | ||
| /** Injectable extractor factory (tests); defaults to the transformers.js pipeline. */ | ||
| loadExtractor) { | ||
| this.model = model; | ||
| this.loadExtractor = loadExtractor; | ||
| } | ||
@@ -32,2 +38,6 @@ async ensure() { | ||
| return this.extractor; | ||
| if (this.loadExtractor) { | ||
| this.extractor = await this.loadExtractor(); | ||
| return this.extractor; | ||
| } | ||
| let transformers; | ||
@@ -43,8 +53,24 @@ try { | ||
| } | ||
| /** | ||
| * Embed texts in batches through the pipeline (one call per batch instead of one | ||
| * per text), yielding to the event loop between batches so long builds stay | ||
| * responsive and interruptible. Returns exactly one vector per input text. | ||
| */ | ||
| async embed(texts) { | ||
| if (texts.length === 0) | ||
| return []; | ||
| const extractor = await this.ensure(); | ||
| const out = []; | ||
| for (const t of texts) { | ||
| const tensor = await extractor(t, { pooling: 'mean', normalize: true }); | ||
| out.push(Array.from(tensor.data)); | ||
| for (let i = 0; i < texts.length; i += LocalEmbeddingProvider.BATCH_SIZE) { | ||
| const batch = texts.slice(i, i + LocalEmbeddingProvider.BATCH_SIZE); | ||
| const tensor = await extractor(batch, { pooling: 'mean', normalize: true }); | ||
| const data = tensor.data; | ||
| const dims = tensor.dims; | ||
| const dim = dims && dims.length > 1 ? dims[dims.length - 1] : data.length / batch.length; | ||
| for (let b = 0; b < batch.length; b++) { | ||
| out.push(Array.from(data.slice(b * dim, (b + 1) * dim))); | ||
| } | ||
| if (i + LocalEmbeddingProvider.BATCH_SIZE < texts.length) { | ||
| await new Promise((resolve) => setImmediate(resolve)); | ||
| } | ||
| } | ||
@@ -51,0 +77,0 @@ return out; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../../src/features/search/embeddings.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../../src/features/search/embeddings.ts"],"names":[],"mappings":"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"} |
@@ -17,2 +17,44 @@ import { VectorStore } from './vector-store.js'; | ||
| } | ||
| /** Lifecycle of the asynchronous background index build. */ | ||
| export type BuildState = 'idle' | 'building' | 'done' | 'error'; | ||
| /** | ||
| * Live build/status snapshot. Backward compatible with SearchIndexStatus (it keeps | ||
| * documents/vectors/items/embedder/builtFromVersion) and adds build progress. | ||
| */ | ||
| export interface IndexBuildStatus extends SearchIndexStatus { | ||
| state: BuildState; | ||
| /** Items pulled from the Zotero API so far. */ | ||
| itemsFetched: number; | ||
| /** Total items expected (0 = not yet known). Capped by the build limit. */ | ||
| itemsTotal: number; | ||
| /** Passages indexed so far (alias of documents). */ | ||
| passages: number; | ||
| /** Set when state === 'error'. */ | ||
| lastError?: string; | ||
| } | ||
| /** One page of library items plus the library-wide total (for progress). */ | ||
| export interface PageResult { | ||
| items: any[]; | ||
| totalResults: number; | ||
| } | ||
| /** Fetch a page of items starting at offset `start` (the Web API pages 100-at-a-time). */ | ||
| export type PageFetcher = (start: number) => Promise<PageResult>; | ||
| export interface IncrementalBuildOptions { | ||
| /** Hard cap on items to index (defaults to no cap beyond the fetcher). */ | ||
| maxItems?: number; | ||
| /** Embedding batch size (texts handed to the provider per call). */ | ||
| embedBatchSize?: number; | ||
| /** Persist partial progress every N items. */ | ||
| persistEveryItems?: number; | ||
| /** Persist partial progress at least every N ms. */ | ||
| persistEveryMs?: number; | ||
| /** Log/report progress every N items. */ | ||
| progressEveryItems?: number; | ||
| /** Log/report progress at least every N ms. */ | ||
| progressEveryMs?: number; | ||
| /** Atomically persist the current (partial) index; called periodically and at the end. */ | ||
| persist?: () => Promise<void>; | ||
| /** Optional progress hook (e.g. MCP notifications) fired alongside the logger. */ | ||
| onProgress?: (status: IndexBuildStatus) => void; | ||
| } | ||
| interface ChunkRecord { | ||
@@ -42,5 +84,19 @@ id: string; | ||
| private builtFromVersion; | ||
| private buildState; | ||
| private itemsFetched; | ||
| private itemsTotal; | ||
| private lastBuildError; | ||
| private cancelToken; | ||
| constructor(opts: SearchIndexOptions); | ||
| get embedderName(): string; | ||
| get hasEmbedder(): boolean; | ||
| /** True while a background build is running. */ | ||
| get isBuilding(): boolean; | ||
| /** Full live status: index size + build progress. Backward compatible with status(). */ | ||
| buildStatus(): IndexBuildStatus; | ||
| /** | ||
| * Cooperatively cancel the running build. Returns false if nothing is building. | ||
| * The build halts between pages/batches and keeps whatever was already indexed. | ||
| */ | ||
| requestStop(): boolean; | ||
| /** Embed arbitrary texts with the configured provider (empty array if none). */ | ||
@@ -52,2 +108,14 @@ embed(texts: string[]): Promise<number[][]>; | ||
| build(libraryItems: any[], opts?: BuildOptions): Promise<SearchIndexStatus>; | ||
| /** | ||
| * Asynchronous, incremental, resumable index build. | ||
| * | ||
| * Pages items via `fetchPage`, chunks/keyword-indexes them as they arrive, embeds in | ||
| * small batches, and atomically persists partial progress along the way — so a | ||
| * timeout, crash, or `requestStop()` never leaves a corrupt index and whatever was | ||
| * saved stays queryable. Returns the final build status; the caller should kick this | ||
| * off without awaiting (fire-and-forget) and poll `buildStatus()`. | ||
| */ | ||
| buildIncremental(fetchPage: PageFetcher, opts?: IncrementalBuildOptions): Promise<IndexBuildStatus>; | ||
| /** Chunk a single library item into the keyword index and queue passages for embedding. */ | ||
| private addOneItem; | ||
| query(q: string, opts?: { | ||
@@ -54,0 +122,0 @@ limit?: number; |
@@ -58,2 +58,8 @@ import { BM25Index } from './bm25.js'; | ||
| builtFromVersion = 0; | ||
| // Asynchronous build lifecycle (see buildIncremental / requestStop / buildStatus). | ||
| buildState = 'idle'; | ||
| itemsFetched = 0; | ||
| itemsTotal = 0; | ||
| lastBuildError = undefined; | ||
| cancelToken = null; | ||
| constructor(opts) { | ||
@@ -68,2 +74,30 @@ this.opts = opts; | ||
| } | ||
| /** True while a background build is running. */ | ||
| get isBuilding() { | ||
| return this.buildState === 'building'; | ||
| } | ||
| /** Full live status: index size + build progress. Backward compatible with status(). */ | ||
| buildStatus() { | ||
| const base = this.status(); | ||
| const s = { | ||
| ...base, | ||
| passages: base.documents, | ||
| state: this.buildState, | ||
| itemsFetched: this.itemsFetched, | ||
| itemsTotal: this.itemsTotal, | ||
| }; | ||
| if (this.buildState === 'error' && this.lastBuildError) | ||
| s.lastError = this.lastBuildError; | ||
| return s; | ||
| } | ||
| /** | ||
| * Cooperatively cancel the running build. Returns false if nothing is building. | ||
| * The build halts between pages/batches and keeps whatever was already indexed. | ||
| */ | ||
| requestStop() { | ||
| if (!this.isBuilding || !this.cancelToken) | ||
| return false; | ||
| this.cancelToken.cancelled = true; | ||
| return true; | ||
| } | ||
| /** Embed arbitrary texts with the configured provider (empty array if none). */ | ||
@@ -127,2 +161,159 @@ async embed(texts) { | ||
| } | ||
| /** | ||
| * Asynchronous, incremental, resumable index build. | ||
| * | ||
| * Pages items via `fetchPage`, chunks/keyword-indexes them as they arrive, embeds in | ||
| * small batches, and atomically persists partial progress along the way — so a | ||
| * timeout, crash, or `requestStop()` never leaves a corrupt index and whatever was | ||
| * saved stays queryable. Returns the final build status; the caller should kick this | ||
| * off without awaiting (fire-and-forget) and poll `buildStatus()`. | ||
| */ | ||
| async buildIncremental(fetchPage, opts = {}) { | ||
| if (this.isBuilding) | ||
| throw new Error('Index build already in progress; poll action:"status".'); | ||
| this.buildState = 'building'; | ||
| this.lastBuildError = undefined; | ||
| this.itemsFetched = 0; | ||
| this.itemsTotal = 0; | ||
| const token = { cancelled: false }; | ||
| this.cancelToken = token; | ||
| this.reset(); | ||
| const embedBatchSize = opts.embedBatchSize ?? 32; | ||
| const persistEveryItems = opts.persistEveryItems ?? 200; | ||
| const persistEveryMs = opts.persistEveryMs ?? 10_000; | ||
| const progressEveryItems = opts.progressEveryItems ?? 500; | ||
| const progressEveryMs = opts.progressEveryMs ?? 10_000; | ||
| const maxItems = opts.maxItems; | ||
| const pending = []; // passages awaiting embedding | ||
| let start = 0; | ||
| let itemsSincePersist = 0; | ||
| let lastPersistAt = Date.now(); | ||
| let itemsSinceLog = 0; | ||
| let lastLogAt = Date.now(); | ||
| let embeddingDisabled = false; | ||
| let warnedEmbed = false; | ||
| const persistNow = async () => { | ||
| itemsSincePersist = 0; | ||
| lastPersistAt = Date.now(); | ||
| if (!opts.persist) | ||
| return; | ||
| try { | ||
| await opts.persist(); | ||
| } | ||
| catch (e) { | ||
| this.opts.logger?.warn(`Could not persist index: ${e instanceof Error ? e.message : String(e)}`); | ||
| } | ||
| }; | ||
| const maybePersist = async () => { | ||
| if (itemsSincePersist >= persistEveryItems || Date.now() - lastPersistAt >= persistEveryMs) | ||
| await persistNow(); | ||
| }; | ||
| const maybeLog = () => { | ||
| if (itemsSinceLog < progressEveryItems && Date.now() - lastLogAt < progressEveryMs) | ||
| return; | ||
| itemsSinceLog = 0; | ||
| lastLogAt = Date.now(); | ||
| const s = this.buildStatus(); | ||
| const total = s.itemsTotal > 0 ? String(s.itemsTotal) : '?'; | ||
| this.opts.logger?.info(`index build: ${s.itemsFetched}/${total} items, ${s.passages} passages, ${s.vectors} vectors (embedder=${s.embedder})`); | ||
| opts.onProgress?.(s); | ||
| }; | ||
| const embedPending = async (force) => { | ||
| if (!this.hasEmbedder || embeddingDisabled) { | ||
| pending.length = 0; | ||
| return; | ||
| } | ||
| while (pending.length >= (force ? 1 : embedBatchSize)) { | ||
| if (token.cancelled) | ||
| return; | ||
| const batch = pending.splice(0, Math.min(embedBatchSize, pending.length)); | ||
| try { | ||
| const vecs = await this.opts.embedder.embed(batch.map((r) => r.text)); | ||
| batch.forEach((r, i) => { | ||
| if (vecs[i]) | ||
| this.vectors.add(r.id, vecs[i]); | ||
| }); | ||
| } | ||
| catch (e) { | ||
| embeddingDisabled = true; | ||
| pending.length = 0; | ||
| if (!warnedEmbed) { | ||
| warnedEmbed = true; | ||
| this.opts.logger?.warn(`Embedding failed; falling back to keyword-only. ${e instanceof Error ? e.message : String(e)}`); | ||
| } | ||
| } | ||
| // Yield so long embedding runs stay interruptible and the event loop breathes. | ||
| await new Promise((resolve) => setImmediate(resolve)); | ||
| } | ||
| }; | ||
| try { | ||
| for (;;) { | ||
| if (token.cancelled) | ||
| break; | ||
| if (maxItems !== undefined && this.itemsFetched >= maxItems) | ||
| break; | ||
| const page = await fetchPage(start); | ||
| const pageItems = page.items ?? []; | ||
| if (pageItems.length === 0) | ||
| break; | ||
| if (!this.itemsTotal && page.totalResults) { | ||
| this.itemsTotal = maxItems !== undefined ? Math.min(page.totalResults, maxItems) : page.totalResults; | ||
| } | ||
| for (const item of pageItems) { | ||
| if (token.cancelled) | ||
| break; | ||
| if (maxItems !== undefined && this.itemsFetched >= maxItems) | ||
| break; | ||
| this.addOneItem(item, pending); | ||
| this.itemsFetched++; | ||
| itemsSincePersist++; | ||
| itemsSinceLog++; | ||
| } | ||
| start += pageItems.length; | ||
| await embedPending(false); | ||
| maybeLog(); | ||
| await maybePersist(); | ||
| if (start >= page.totalResults) | ||
| break; | ||
| } | ||
| if (!token.cancelled) | ||
| await embedPending(true); | ||
| this.builtFromVersion = this.itemsFetched; | ||
| await persistNow(); | ||
| this.buildState = 'done'; | ||
| const final = this.buildStatus(); | ||
| const total = final.itemsTotal > 0 ? String(final.itemsTotal) : '?'; | ||
| this.opts.logger?.info(`index build ${token.cancelled ? 'stopped' : 'complete'}: ` + | ||
| `${final.itemsFetched}/${total} items, ${final.passages} passages, ${final.vectors} vectors (embedder=${final.embedder})`); | ||
| opts.onProgress?.(final); | ||
| return final; | ||
| } | ||
| catch (e) { | ||
| this.buildState = 'error'; | ||
| this.lastBuildError = e instanceof Error ? e.message : String(e); | ||
| this.opts.logger?.error(`index build failed: ${this.lastBuildError}`); | ||
| // Keep whatever partial data we already indexed, and persist it best-effort. | ||
| await persistNow().catch(() => { }); | ||
| opts.onProgress?.(this.buildStatus()); | ||
| return this.buildStatus(); | ||
| } | ||
| finally { | ||
| this.cancelToken = null; | ||
| } | ||
| } | ||
| /** Chunk a single library item into the keyword index and queue passages for embedding. */ | ||
| addOneItem(item, pending) { | ||
| const d = item.data ?? item; | ||
| const key = item.key ?? d.key; | ||
| if (!key) | ||
| return; | ||
| this.items.add(key); | ||
| for (const ch of chunkText(itemText(d))) { | ||
| const rec = { id: `${key}#${ch.index}`, itemKey: key, title: d.title ?? '(untitled)', text: ch.text }; | ||
| this.chunks.set(rec.id, rec); | ||
| this.bm25.addDoc(rec.id, rec.text); | ||
| if (this.hasEmbedder) | ||
| pending.push(rec); | ||
| } | ||
| } | ||
| async query(q, opts = {}) { | ||
@@ -129,0 +320,0 @@ const limit = opts.limit ?? 10; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index-manager.js","sourceRoot":"","sources":["../../../src/features/search/index-manager.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"index-manager.js","sourceRoot":"","sources":["../../../src/features/search/index-manager.ts"],"names":[],"mappings":"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"} |
| import type { SearchIndex } from './index-manager.js'; | ||
| /** | ||
| * Atomically persist the index: write to a temp file in the same directory, then | ||
| * rename over the target. A crash mid-write can therefore never leave a corrupt or | ||
| * half-written search-index.json — readers see either the previous complete snapshot | ||
| * or the new one. | ||
| */ | ||
| export declare function saveIndex(index: SearchIndex, path: string): Promise<void>; | ||
| export declare function loadIndex(index: SearchIndex, path: string): Promise<boolean>; |
@@ -1,6 +0,20 @@ | ||
| import { readFile, writeFile, mkdir } from 'node:fs/promises'; | ||
| import { readFile, writeFile, mkdir, rename, unlink } from 'node:fs/promises'; | ||
| import { dirname } from 'node:path'; | ||
| /** | ||
| * Atomically persist the index: write to a temp file in the same directory, then | ||
| * rename over the target. A crash mid-write can therefore never leave a corrupt or | ||
| * half-written search-index.json — readers see either the previous complete snapshot | ||
| * or the new one. | ||
| */ | ||
| export async function saveIndex(index, path) { | ||
| await mkdir(dirname(path), { recursive: true }); | ||
| await writeFile(path, JSON.stringify(index.toJSON())); | ||
| const tmp = `${path}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`; | ||
| try { | ||
| await writeFile(tmp, JSON.stringify(index.toJSON())); | ||
| await rename(tmp, path); | ||
| } | ||
| catch (e) { | ||
| await unlink(tmp).catch(() => { }); | ||
| throw e; | ||
| } | ||
| } | ||
@@ -7,0 +21,0 @@ export async function loadIndex(index, path) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../../src/features/search/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAkB,EAAE,IAAY;IAC9D,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAkB,EAAE,IAAY;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"} | ||
| {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../../src/features/search/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAkB,EAAE,IAAY;IAC9D,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,GAAG,IAAI,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAkB,EAAE,IAAY;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"} |
@@ -9,2 +9,4 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; | ||
| import type { LocalApiClient } from '../api/local-client.js'; | ||
| import type { LocalWriteClient } from '../api/local-writes.js'; | ||
| import type { ConnectorWriteClient } from '../api/connector-writes.js'; | ||
| import type { Logger } from '../lib/logger.js'; | ||
@@ -23,2 +25,6 @@ import type { StyleResolver } from '../features/citation/styles.js'; | ||
| local?: LocalApiClient; | ||
| /** Zotero 9+ desktop local-API writes (user-granted key); undefined when unavailable. */ | ||
| localWrites?: LocalWriteClient; | ||
| /** Desktop connector-API writes (Zotero 7+): saveItems/saveAttachment/updateSession. */ | ||
| connectorWrites?: ConnectorWriteClient; | ||
| styles: StyleResolver; | ||
@@ -85,1 +91,15 @@ translation: TranslationServerClient; | ||
| export declare function registerAllTools(server: McpServer, defs: ToolDefinition[], ctx: ToolContext): void; | ||
| /** | ||
| * True when a local-API write failure means the running Zotero simply does not have | ||
| * (or accept) local writes yet — e.g. Zotero <= 9.0 whose local API is read-only | ||
| * ("No endpoint found", 501 "Endpoint does not support method") — as opposed to a | ||
| * real write failure (denied grant, validation error, stale version). Callers use | ||
| * this to fall back to the connector protocol or the cloud Web API. | ||
| */ | ||
| export declare function isLocalWritesUnavailable(err: unknown): boolean; | ||
| /** | ||
| * The local-API capability is probed at startup, but Zotero may be restarted (or | ||
| * briefly unresponsive) during a long-lived server process. This re-pings once and | ||
| * refreshes the flag so desktop write paths recover without a restart. | ||
| */ | ||
| export declare function ensureLocalApi(ctx: ToolContext): Promise<boolean>; |
@@ -29,3 +29,4 @@ import { ZoteroApiError } from '../api/errors.js'; | ||
| if (!cloud) { | ||
| throw new Error('This operation writes to Zotero and requires a cloud API key (set ZOTERO_API_KEY). The desktop local API is read-only.'); | ||
| throw new Error('This operation writes to a cloud/group library and requires a cloud API key (set ZOTERO_API_KEY). ' + | ||
| 'For the personal library, writes can instead go through the running Zotero 9+ desktop app (local API).'); | ||
| } | ||
@@ -58,2 +59,28 @@ return { type: 'user', id: cloud.userID }; | ||
| } | ||
| /** | ||
| * True when a local-API write failure means the running Zotero simply does not have | ||
| * (or accept) local writes yet — e.g. Zotero <= 9.0 whose local API is read-only | ||
| * ("No endpoint found", 501 "Endpoint does not support method") — as opposed to a | ||
| * real write failure (denied grant, validation error, stale version). Callers use | ||
| * this to fall back to the connector protocol or the cloud Web API. | ||
| */ | ||
| export function isLocalWritesUnavailable(err) { | ||
| const msg = err instanceof Error ? err.message : String(err); | ||
| return /local api/i.test(msg) && /404|no endpoint|not implemented|not supported|unreachable/i.test(msg); | ||
| } | ||
| /** | ||
| * The local-API capability is probed at startup, but Zotero may be restarted (or | ||
| * briefly unresponsive) during a long-lived server process. This re-pings once and | ||
| * refreshes the flag so desktop write paths recover without a restart. | ||
| */ | ||
| export async function ensureLocalApi(ctx) { | ||
| if (ctx.capabilities.localApi) | ||
| return true; | ||
| if (!ctx.local || ctx.config.local === 'off') | ||
| return false; | ||
| const up = await ctx.local.ping().catch(() => false); | ||
| if (up) | ||
| ctx.capabilities.localApi = true; | ||
| return up; | ||
| } | ||
| //# sourceMappingURL=registry.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAiDlD;;;;;;;GAOG;AACH,MAAM,UAAU,EAAE,CAAC,UAAmC,EAAE,OAAe;IACrE,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;YAC/B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SAC5D;QACD,iBAAiB,EAAE,UAAU;KAC9B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAgB,EAChB,IAA+D;IAE/D,IAAI,IAAI,EAAE,UAAU;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,IAAI,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;IACzF,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC;IACrC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,wHAAwH,CACzH,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAiB,EACjB,IAAsB,EACtB,GAAgB;IAEhB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,YAAY,CACjB,GAAG,CAAC,IAAI,EACR;YACE,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,WAAW,EAAE;SAC3E,EACD,KAAK,EAAE,IAAa,EAAE,EAAE;YACtB,IAAI,CAAC;gBACH,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GACX,GAAG,YAAY,cAAc;oBAC3B,CAAC,CAAC,GAAG,CAAC,OAAO;oBACb,CAAC,CAAC,GAAG,YAAY,KAAK;wBACpB,CAAC,CAAC,GAAG,CAAC,OAAO;wBACb,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACpB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,UAAU,EAAE,OAAO,CAAC,CAAC;gBACtD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAChF,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"} | ||
| {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry/registry.ts"],"names":[],"mappings":"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"} |
@@ -11,3 +11,14 @@ export async function probeCapabilities(config, deps) { | ||
| : Promise.resolve(null); | ||
| const localPromise = config.local !== 'off' && deps.local ? deps.local.ping().catch(() => false) : Promise.resolve(false); | ||
| // The desktop app may be mid-startup when zoteus boots; a single instant ping can | ||
| // race it and wrongly disable every desktop write path for the process lifetime. | ||
| const localPromise = config.local !== 'off' && deps.local | ||
| ? (async () => { | ||
| for (let attempt = 0; attempt < 3; attempt++) { | ||
| if (await deps.local.ping().catch(() => false)) | ||
| return true; | ||
| await new Promise((r) => setTimeout(r, 600)); | ||
| } | ||
| return false; | ||
| })() | ||
| : Promise.resolve(false); | ||
| const [cloud, localApi] = await Promise.all([cloudPromise, localPromise]); | ||
@@ -14,0 +25,0 @@ deps.logger.info(`Capabilities: cloud=${cloud ? `user ${cloud.userID}` : 'none'}, localApi=${localApi}`); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/router/capabilities.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAoB,EACpB,IAAe;IAEf,MAAM,YAAY,GAA4B,IAAI,CAAC,GAAG,CAAC,MAAM;QAC3D,CAAC,CAAC,IAAI,CAAC,GAAG;aACL,WAAW,EAAE;aACb,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;aACpB,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACN,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,MAAM,YAAY,GAChB,MAAM,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAEvG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,uBAAuB,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,cAAc,QAAQ,EAAE,CACvF,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC"} | ||
| {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/router/capabilities.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAoB,EACpB,IAAe;IAEf,MAAM,YAAY,GAA4B,IAAI,CAAC,GAAG,CAAC,MAAM;QAC3D,CAAC,CAAC,IAAI,CAAC,GAAG;aACL,WAAW,EAAE;aACb,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;aACpB,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACN,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,kFAAkF;IAClF,iFAAiF;IACjF,MAAM,YAAY,GAChB,MAAM,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK;QAClC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACV,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;gBAC7C,IAAI,MAAM,IAAI,CAAC,KAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;oBAAE,OAAO,IAAI,CAAC;gBAC7D,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,EAAE;QACN,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE7B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,uBAAuB,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,cAAc,QAAQ,EAAE,CACvF,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC"} |
@@ -52,3 +52,6 @@ /** | ||
| const lib = library ?? this.defaultLibrary(); | ||
| // Children are always available via the cloud; local may not implement /children uniformly. | ||
| // Prefer the desktop app for the personal library (local-only mode has no cloud | ||
| // fallback — hitting api.zotero.org with user id 0 yields "Invalid user ID"). | ||
| if (this.useLocal(lib)) | ||
| return this.local.getItemChildren(key, rest); | ||
| return this.web.getItemChildren(lib, key, rest); | ||
@@ -55,0 +58,0 @@ } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"library-router.js","sourceRoot":"","sources":["../../src/router/library-router.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"library-router.js","sourceRoot":"","sources":["../../src/router/library-router.ts"],"names":[],"mappings":"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"} |
+21
-0
@@ -6,2 +6,4 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; | ||
| import { LocalApiClient } from './api/local-client.js'; | ||
| import { LocalWriteClient } from './api/local-writes.js'; | ||
| import { ConnectorWriteClient } from './api/connector-writes.js'; | ||
| import { probeCapabilities } from './router/capabilities.js'; | ||
@@ -49,2 +51,19 @@ import { LibraryRouter } from './router/library-router.js'; | ||
| const router = new LibraryRouter({ config, capabilities, web, local }); | ||
| // Zotero 9+ accepts local-API writes behind a user-granted key. Only the operator | ||
| // context (never per-user tenants) talks to the desktop app. The client is created | ||
| // eagerly but authorizes lazily, on first write. | ||
| const localWrites = !perUser && capabilities.localApi | ||
| ? new LocalWriteClient({ | ||
| port: config.localPort, | ||
| fetcher, | ||
| logger, | ||
| key: config.localApiKey, | ||
| keyStorePath: join(config.dataDir, 'local-api-key.json'), | ||
| }) | ||
| : undefined; | ||
| // The connector protocol works on all recent Zotero versions while the app runs, | ||
| // including ones whose local API is still read-only (no grant dialog involved). | ||
| const connectorWrites = !perUser && capabilities.localApi | ||
| ? new ConnectorWriteClient({ port: config.localPort, fetcher, logger }) | ||
| : undefined; | ||
| const schema = new SchemaService({ web }); | ||
@@ -64,2 +83,4 @@ const styles = new StyleResolver(); | ||
| local, | ||
| localWrites, | ||
| connectorWrites, | ||
| styles, | ||
@@ -66,0 +87,0 @@ translation, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"} |
| import { z } from 'zod'; | ||
| import { ok } from '../registry/registry.js'; | ||
| import { rankPassages, approxPage } from '../features/fulltext/passages.js'; | ||
| import { extractPdfPages, locatePage, DEFAULT_PRECISE_MAX_BYTES } from '../features/fulltext/pdf-pages.js'; | ||
| import { extractPdfPages, locatePage, pdfPagesToText, DEFAULT_PRECISE_MAX_BYTES } from '../features/fulltext/pdf-pages.js'; | ||
| function err(text) { | ||
@@ -39,3 +39,3 @@ return { content: [{ type: 'text', text }], isError: true }; | ||
| title: 'Get attachment full text / passages (read-only)', | ||
| description: "Retrieve an item's PDF text for grounding. Pass a parent `item_key` (its best PDF attachment is resolved automatically) or an attachment key. With `query`, returns the top relevant passages with locators (char offsets, nearest section, and a page); with `page_range` (e.g. \"3-7\"), returns that span; with neither, returns a truncated head. Page numbers are an estimate (pageApprox) unless `precise_pages:true`, which re-extracts the PDF for exact pages when possible (otherwise it degrades to approximate with a notice). Read-only; cloud full text. Use this to cite a claim with a page after finding an item via zotero_search_items / zotero_semantic_search.", | ||
| description: "Retrieve an item's PDF text for grounding. Pass a parent `item_key` (its best PDF attachment is resolved automatically) or an attachment key. With `query`, returns the top relevant passages with locators (char offsets, nearest section, and a page); with `page_range` (e.g. \"3-7\"), returns that span; with neither, returns a truncated head. Text comes from Zotero's full-text index when available; when the attachment is NOT indexed yet, the PDF itself is downloaded and parsed on the fly (`fallback`, on by default — set `fallback:false` to disable), so unindexed PDFs still return text (marked fulltextSource:\"pdf\"). Page numbers are exact in that case, and otherwise an estimate (pageApprox) unless `precise_pages:true`, which re-extracts the PDF for exact pages when possible (otherwise it degrades to approximate with a notice). Read-only; cloud full text. Use this to cite a claim with a page after finding an item via zotero_search_items / zotero_semantic_search.", | ||
| inputSchema: { | ||
@@ -54,2 +54,6 @@ item_key: z.string().describe('Parent item key or attachment key.'), | ||
| precise_pages: z.boolean().optional().describe('Re-extract the PDF for exact page numbers.'), | ||
| fallback: z | ||
| .boolean() | ||
| .optional() | ||
| .describe('When Zotero has no indexed full text for the attachment, download the PDF and extract it directly (default true).'), | ||
| library_type: z.enum(['user', 'group']).optional(), | ||
@@ -67,9 +71,50 @@ library_id: z.number().int().optional(), | ||
| return err(resolved.error); | ||
| const maxMb = Math.round(DEFAULT_PRECISE_MAX_BYTES / (1024 * 1024)); | ||
| const ft = await ctx.web.getFullText(lib, resolved.attachmentKey); | ||
| if (!ft || typeof ft.content !== 'string' || !ft.content.length) { | ||
| return err(`No extracted full text for attachment ${resolved.attachmentKey}. Zotero may not have indexed it yet (open it once in Zotero, or check it is a text PDF).`); | ||
| const indexed = Boolean(ft && typeof ft.content === 'string' && ft.content.length); | ||
| // Where the text comes from: Zotero's index when available, otherwise (fallback, | ||
| // on by default) the attachment PDF itself, parsed on the fly with pdfjs. | ||
| let content; | ||
| let totalChars; | ||
| let totalPages; | ||
| let pages = null; | ||
| let fulltextSource = 'zotero'; | ||
| let sourceNotice = ''; | ||
| if (indexed) { | ||
| content = ft.content; | ||
| totalChars = typeof ft.totalChars === 'number' && ft.totalChars > 0 ? ft.totalChars : content.length; | ||
| totalPages = typeof ft.totalPages === 'number' ? ft.totalPages : undefined; | ||
| } | ||
| const content = ft.content; | ||
| const totalChars = typeof ft.totalChars === 'number' && ft.totalChars > 0 ? ft.totalChars : content.length; | ||
| const totalPages = typeof ft.totalPages === 'number' ? ft.totalPages : undefined; | ||
| else if (args.fallback === false) { | ||
| return err(`No extracted full text for attachment ${resolved.attachmentKey}. Zotero has not indexed it yet ` + | ||
| `(open it once in Zotero to index it, or retry with fallback enabled to parse the PDF directly).`); | ||
| } | ||
| else { | ||
| // --- PDF fallback: download the attachment and extract text directly --- | ||
| const noText = `No extracted full text for attachment ${resolved.attachmentKey} (Zotero has not indexed it)`; | ||
| if (resolved.size && resolved.size > DEFAULT_PRECISE_MAX_BYTES) { | ||
| return err(`${noText}, and direct PDF extraction is skipped: the file is larger than the ${maxMb} MB limit for on-the-fly parsing. ` + | ||
| `Open the PDF once in Zotero to have it indexed, then retry.`); | ||
| } | ||
| let bytes; | ||
| try { | ||
| const dl = await ctx.web.downloadFileBytes(lib, resolved.attachmentKey); | ||
| bytes = dl.bytes; | ||
| } | ||
| catch (e) { | ||
| return err(`${noText}, and the attachment file could not be downloaded either (${e instanceof Error ? e.message : String(e)}). ` + | ||
| `It may be a linked file with no stored copy.`); | ||
| } | ||
| const extracted = await extractPdfPages(bytes); | ||
| if (!extracted || !extracted.some((p) => p.trim())) { | ||
| return err(`${noText}, and direct PDF extraction yielded nothing (corrupt/scanned PDF, oversized file, or the optional pdfjs-dist parser is missing). ` + | ||
| `Open the PDF once in Zotero to have it indexed, then retry.`); | ||
| } | ||
| pages = extracted; | ||
| content = pdfPagesToText(extracted); | ||
| totalChars = content.length; | ||
| totalPages = extracted.length; | ||
| fulltextSource = 'pdf'; | ||
| sourceNotice = ` Zotero had no indexed full text for this attachment; the text was extracted directly from the PDF (fallback).`; | ||
| } | ||
| const maxChars = args.max_chars ?? 12000; | ||
@@ -82,11 +127,12 @@ const base = { | ||
| title: resolved.title, | ||
| fulltextSource, | ||
| totalChars, | ||
| totalPages, | ||
| indexedChars: ft.indexedChars, | ||
| indexedPages: ft.indexedPages, | ||
| indexedChars: indexed ? ft.indexedChars : undefined, | ||
| indexedPages: indexed ? ft.indexedPages : undefined, | ||
| }; | ||
| // Optionally pull exact pages once (shared by passages / page_range). | ||
| let pages = null; | ||
| // Optionally pull exact pages once (shared by passages / page_range). When the text | ||
| // came from the PDF fallback we already hold the exact pages. | ||
| let tooLarge = false; | ||
| if (args.precise_pages) { | ||
| if (!pages && args.precise_pages) { | ||
| // Pre-download guard: skip the (potentially large) file transfer + pdfjs extraction | ||
@@ -112,5 +158,4 @@ // when the attachment is already known to exceed the safe size for this host. pdfjs can | ||
| const exact = Boolean(pages && pages.length); | ||
| const pageSource = args.precise_pages ? (exact ? 'exact' : 'approximate') : 'approximate'; | ||
| const maxMb = Math.round(DEFAULT_PRECISE_MAX_BYTES / (1024 * 1024)); | ||
| const degradeNotice = args.precise_pages && !exact | ||
| const pageSource = exact ? 'exact' : 'approximate'; | ||
| const degradeNotice = indexed && args.precise_pages && !exact | ||
| ? tooLarge | ||
@@ -152,4 +197,5 @@ ? ` Exact pages skipped: this PDF exceeds the ${maxMb} MB re-extraction limit on this instance; pageApprox is an estimate.` | ||
| (truncated ? ' Some lower-ranked passages omitted (max_chars).' : '') + | ||
| sourceNotice + | ||
| degradeNotice; | ||
| return ok({ ...base, mode: 'passages', pageSource, passages, truncated, notice: degradeNotice.trim() || undefined }, summary); | ||
| return ok({ ...base, mode: 'passages', pageSource, passages, truncated, notice: (sourceNotice + degradeNotice).trim() || undefined }, summary); | ||
| } | ||
@@ -184,5 +230,6 @@ // --- page_range mode --- | ||
| omittedChars: truncated ? slice.length - maxChars : 0, | ||
| notice: (degradeNotice + emptyNotice).trim() || undefined, | ||
| notice: (sourceNotice + degradeNotice + emptyNotice).trim() || undefined, | ||
| }, `Text for pages ${args.page_range} of ${args.item_key} (${pageSource}).` + | ||
| (truncated ? ' Truncated (max_chars).' : '') + | ||
| sourceNotice + | ||
| degradeNotice + | ||
@@ -194,6 +241,8 @@ emptyNotice); | ||
| const text = truncated ? content.slice(0, maxChars) : content; | ||
| const notice = truncated | ||
| ? `Truncated to ${maxChars} of ${content.length} chars — pass query (for relevant passages), page_range, or a larger max_chars.` | ||
| : undefined; | ||
| return ok({ ...base, mode: 'document', pageSource, text, truncated, omittedChars: truncated ? content.length - maxChars : 0, notice }, `Full text of ${args.item_key}: ${content.length} chars${truncated ? `, returned first ${maxChars}` : ''}.`); | ||
| const truncNotice = truncated | ||
| ? ` Truncated to ${maxChars} of ${content.length} chars — pass query (for relevant passages), page_range, or a larger max_chars.` | ||
| : ''; | ||
| const notice = (sourceNotice + truncNotice).trim() || undefined; | ||
| return ok({ ...base, mode: 'document', pageSource, text, truncated, omittedChars: truncated ? content.length - maxChars : 0, notice }, `Full text of ${args.item_key}: ${content.length} chars${truncated ? `, returned first ${maxChars}` : ''} ` + | ||
| `(${fulltextSource === 'pdf' ? 'extracted from the PDF directly' : 'from the Zotero full-text index'}).`); | ||
| }, | ||
@@ -200,0 +249,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"get-fulltext.js","sourceRoot":"","sources":["../../src/tools/get-fulltext.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"get-fulltext.js","sourceRoot":"","sources":["../../src/tools/get-fulltext.ts"],"names":[],"mappings":"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"} |
+149
-9
| import { z } from 'zod'; | ||
| import { ok, requireCloudLibrary } from '../registry/registry.js'; | ||
| import { ok, requireCloudLibrary, isLocalWritesUnavailable, ensureLocalApi } from '../registry/registry.js'; | ||
| import { arxivItem, fromScholarWork, parseIdentifier, bareDoi } from '../features/resolve/resolve.js'; | ||
@@ -45,3 +45,3 @@ function err(text) { | ||
| title: 'Import items by identifier or URL', | ||
| description: 'Resolve bibliographic metadata to Zotero item-data and optionally save it to your library. `action: "by_identifier"` resolves a DOI, ISBN, PMID, arXiv id, or ADS bibcode (set `identifier`); `action: "by_url"` scrapes a web page (set `url`) and may return multiple choices to pick from. Set `save_to_library:true` (and optionally `collection_key`) to persist the resolved items (requires a cloud API key); otherwise the resolved metadata is returned without saving. When a Zotero translation-server is reachable (ZOTEUS_TRANSLATION_SERVER_URL, default http://127.0.0.1:1969) it is the primary path; if none is running, DOI and arXiv ids fall back to built-in resolution (OpenAlex/Crossref and the arXiv API respectively) — the result then carries a `source` field ("scholar" or "arxiv"). ISBN/PMID/bibcode and web URLs require a translation-server.', | ||
| description: 'Resolve bibliographic metadata to Zotero item-data and optionally save it to your library. `action: "by_identifier"` resolves a DOI, ISBN, PMID, arXiv id, or ADS bibcode (set `identifier`); `action: "by_url"` scrapes a web page (set `url`) and may return multiple choices to pick from. Set `save_to_library:true` (and optionally `collection_key`) to persist the resolved items — saved into the running Zotero desktop app when available, otherwise via the cloud Web API (requires ZOTERO_API_KEY); otherwise the resolved metadata is returned without saving. When a Zotero translation-server is reachable (ZOTEUS_TRANSLATION_SERVER_URL, default http://127.0.0.1:1969) it is the primary path; if none is running, DOI and arXiv ids fall back to built-in resolution (OpenAlex/Crossref and the arXiv API respectively) — the result then carries a `source` field ("scholar" or "arxiv"). ISBN/PMID/bibcode and web URLs require a translation-server.', | ||
| inputSchema: { | ||
@@ -51,4 +51,6 @@ action: z.enum(['by_identifier', 'by_url']), | ||
| url: z.string().optional().describe('Web page URL to scrape (needs a translation-server).'), | ||
| save_to_library: z.boolean().optional().describe('Persist the resolved items (needs a cloud key).'), | ||
| collection_key: z.string().optional().describe('Collection to add saved items to.'), | ||
| save_to_library: z.boolean().optional().describe('Persist the resolved items — into the running Zotero desktop app when available, otherwise the cloud Web API (needs a cloud key).'), | ||
| collection_key: z.string().optional().describe('Collection to add saved items to: an 8-char collection key or a Zotero treeViewID like "C20".'), | ||
| attach_url: z.string().url().optional().describe('File URL (e.g. an arXiv PDF) to download and attach as a stored attachment to the (single) imported item when saving to the desktop app.'), | ||
| attach_title: z.string().optional().describe('Title for the attached file, e.g. "Full Text PDF".'), | ||
| library_type: z.enum(['user', 'group']).optional(), | ||
@@ -73,3 +75,3 @@ library_id: z.number().int().optional(), | ||
| if (items.length) | ||
| return maybeSave(ctx, args, items, 'translation-server'); | ||
| return await maybeSave(ctx, args, items, 'translation-server'); | ||
| } | ||
@@ -79,3 +81,3 @@ // translation-server down (or the identifier failed): try the built-in path. | ||
| const { items, source } = await resolveBuiltin(ctx, args.identifier); | ||
| return maybeSave(ctx, args, items, source); | ||
| return await maybeSave(ctx, args, items, source); | ||
| } | ||
@@ -96,3 +98,3 @@ catch (e) { | ||
| return err(`No items found at ${args.url}.`); | ||
| return maybeSave(ctx, args, items, 'translation-server'); | ||
| return await maybeSave(ctx, args, items, 'translation-server'); | ||
| }, | ||
@@ -110,3 +112,73 @@ }; | ||
| } | ||
| const lib = requireCloudLibrary(ctx, args); | ||
| // Prefer the desktop app for the personal library (no cloud key needed); | ||
| // fall back to the cloud Web API otherwise. | ||
| if (!args.library_id && (await ensureLocalApi(ctx)) && ctx.localWrites) { | ||
| try { | ||
| if (args.collection_key) { | ||
| for (const it of payload) | ||
| it.collections = [...(it.collections ?? []), args.collection_key]; | ||
| } | ||
| const result = await ctx.localWrites.writeItems(payload); | ||
| return ok({ created: result.successful.map((s) => s.key), failed: result.failed, resolved: payload.length, source, target: 'local' }, `Imported ${result.successful.length} of ${payload.length} resolved item(s) via ${source} into the library (Zotero desktop).`); | ||
| } | ||
| catch (e) { | ||
| if (!isLocalWritesUnavailable(e)) | ||
| throw e; | ||
| ctx.logger.info(`Local-API writes unavailable (${e instanceof Error ? e.message : e}); using the connector protocol.`); | ||
| } | ||
| } | ||
| if (!args.library_id && ctx.connectorWrites && (await ensureLocalApi(ctx))) { | ||
| // Connector protocol: collections are targeted by treeViewID via updateSession, | ||
| // not by the collections array, so strip it from the payload. | ||
| const stripped = payload.map(({ collections: _c, ...rest }) => rest); | ||
| const { sessionID, connectorIds } = await ctx.connectorWrites.saveItems(stripped, { | ||
| uri: 'zotero://zoteus/import', | ||
| }); | ||
| let placedIn; | ||
| if (args.collection_key) { | ||
| try { | ||
| const target = await resolveTreeViewId(ctx, args.collection_key); | ||
| if (target) { | ||
| await ctx.connectorWrites.updateSession(sessionID, { target }); | ||
| placedIn = target; | ||
| } | ||
| } | ||
| catch (e) { | ||
| return ok({ sessionID, resolved: stripped.length, source, target: 'desktop', warning: String(e) }, `Saved ${stripped.length} item(s) via ${source}, but could not place them in "${args.collection_key}": ${e}`); | ||
| } | ||
| } | ||
| let attached; | ||
| if (args.attach_url && connectorIds[0]) { | ||
| const res = await ctx.fetcher.fetch(args.attach_url, { method: 'GET' }, { maxRetries: 2, deadlineMs: 300_000 }); | ||
| if (!res.ok) { | ||
| return ok({ sessionID, resolved: stripped.length, source, target: 'desktop', warning: `File download failed (${res.status}) for ${args.attach_url}` }, `Saved ${stripped.length} item(s) via ${source}; attachment download failed (${res.status}).`); | ||
| } | ||
| const contentType = res.headers.get('content-type')?.split(';')[0] ?? 'application/pdf'; | ||
| const bytes = new Uint8Array(await res.arrayBuffer()); | ||
| await ctx.connectorWrites.saveAttachment({ | ||
| sessionID, | ||
| parentConnectorId: connectorIds[0], | ||
| url: args.attach_url, | ||
| title: args.attach_title ?? 'Full Text PDF', | ||
| bytes, | ||
| contentType, | ||
| }); | ||
| attached = { bytes: bytes.length, contentType }; | ||
| } | ||
| const created = await pollImportedItems(ctx, stripped); | ||
| return ok({ | ||
| sessionID, | ||
| created, | ||
| resolved: stripped.length, | ||
| source, | ||
| target: 'desktop', | ||
| placedIn, | ||
| attached, | ||
| note: created.length < stripped.length | ||
| ? 'Some items could not be matched back yet; they may still appear in Zotero.' | ||
| : undefined, | ||
| }, `Imported ${created.length}/${stripped.length} resolved item(s) via ${source} into the running Zotero desktop app` + | ||
| (placedIn ? ` (collection ${placedIn})` : '') + | ||
| (attached ? `, with ${attached.bytes}-byte PDF attached` : '') + '.'); | ||
| } | ||
| if (args.collection_key) { | ||
@@ -116,6 +188,74 @@ for (const it of payload) | ||
| } | ||
| let lib; | ||
| try { | ||
| lib = requireCloudLibrary(ctx, args); | ||
| } | ||
| catch (e) { | ||
| return { | ||
| content: [{ | ||
| type: 'text', | ||
| text: `${e instanceof Error ? e.message : e} Tip: with the Zotero desktop app running, saving needs no cloud key — start the app (or set ZOTEUS_LOCAL=on) and retry.`, | ||
| }], | ||
| isError: true, | ||
| }; | ||
| } | ||
| const result = await ctx.web.writeItems(lib, payload); | ||
| return ok({ created: result.successful.map((s) => s.key), failed: result.failed, resolved: payload.length, source }, `Imported ${result.successful.length} of ${payload.length} resolved item(s) via ${source} into the library.`); | ||
| return ok({ | ||
| created: result.successful.map((s) => s.key), | ||
| failed: result.failed, | ||
| resolved: payload.length, | ||
| source, | ||
| target: 'cloud', | ||
| warning: args.attach_url ? 'attach_url is only supported for desktop-app saves; the file was not attached.' : undefined, | ||
| }, `Imported ${result.successful.length} of ${payload.length} resolved item(s) via ${source} into the library.`); | ||
| } | ||
| export default importTool; | ||
| /** | ||
| * Resolve a caller-supplied collection to the connector protocol's treeViewID | ||
| * ("L1" for My Library, "C<id>" for collections). Accepts a treeViewID directly, | ||
| * or an 8-char collection key that is matched by name against the app's target list. | ||
| */ | ||
| async function resolveTreeViewId(ctx, collectionKey) { | ||
| if (/^[CL]\d+$/.test(collectionKey)) | ||
| return collectionKey; | ||
| const collections = await ctx.router.listCollections({ limit: 1000 }); | ||
| const match = collections.data | ||
| .map((c) => c?.data ?? c) | ||
| .find((c) => c?.key === collectionKey); | ||
| if (!match) | ||
| throw new Error(`Collection key ${collectionKey} not found in the library.`); | ||
| const { targets } = await ctx.connectorWrites.getSelectedCollection(); | ||
| const byName = targets.filter((t) => t.name === match.name); | ||
| if (!byName.length) | ||
| return undefined; | ||
| if (byName.length > 1) { | ||
| throw new Error(`Multiple collections named "${match.name}" exist (${byName.map((t) => t.id).join(', ')}); pass an explicit treeViewID instead.`); | ||
| } | ||
| return byName[0]?.id; | ||
| } | ||
| /** Recover the keys of items just saved through the connector protocol (no payload). */ | ||
| async function pollImportedItems(ctx, sent) { | ||
| const found = []; | ||
| const deadline = Date.now() + 15_000; | ||
| const wanted = new Set(sent.map((it) => String(it.title ?? ''))); | ||
| while (wanted.size && Date.now() < deadline) { | ||
| try { | ||
| const res = await ctx.local.listItems({ sort: 'dateAdded', direction: 'desc', limit: 25 }); | ||
| for (const item of res.data) { | ||
| const d = item?.data ?? item; | ||
| const title = String(d?.title ?? ''); | ||
| if (wanted.has(title)) { | ||
| wanted.delete(title); | ||
| found.push(d.key); | ||
| } | ||
| } | ||
| } | ||
| catch { | ||
| // Keep polling until the deadline. | ||
| } | ||
| if (wanted.size) | ||
| await new Promise((r) => setTimeout(r, 750)); | ||
| } | ||
| return found; | ||
| } | ||
| //# sourceMappingURL=import.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/tools/import.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/tools/import.ts"],"names":[],"mappings":"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"} |
+29
-24
| import { z } from 'zod'; | ||
| import { ok } from '../registry/registry.js'; | ||
| import { saveIndex } from '../features/search/persistence.js'; | ||
| const MAX_ITEMS = 5000; | ||
| async function fetchAllItems(ctx, lib) { | ||
| const all = []; | ||
| let start = 0; | ||
| for (;;) { | ||
| const page = await ctx.web.listItems(lib, { limit: 100, start, top: true }); | ||
| all.push(...page.data); | ||
| start += page.data.length; | ||
| if (page.data.length === 0 || all.length >= page.totalResults || all.length >= MAX_ITEMS) | ||
| break; | ||
| } | ||
| return all; | ||
| } | ||
| import { MAX_ITEMS, progressLine, startIndexBuild, statusSummary } from '../features/search/build.js'; | ||
| const indexTool = { | ||
| name: 'zotero_index', | ||
| title: 'Build the semantic search index', | ||
| description: "Build, refresh, or report the status of the local hybrid-search index used by zotero_semantic_search. `action: \"build\"` (or \"refresh\") fetches the library's top-level items and indexes their text (title, abstract, creators, tags) for BM25 keyword search and — if an embedding provider is configured — vector search; the index is persisted under the Zoteus data dir. `action: \"status\"` reports the index size and which embedder is active (it falls back to keyword-only when no local model or embedding API is available). Run a build before semantic searching, and refresh after large library changes.", | ||
| description: "Manage the local hybrid-search index used by zotero_semantic_search. The build runs as a background job on the server, so this tool returns immediately — never blocks on large libraries. `action: \"build\"` (or \"refresh\") starts a background build: it pages the library's top-level items (100-at-a-time, capped at 5000 items unless a smaller `limit` is given), indexes their text (title, abstract, creators, tags) for BM25 keyword search and — if an embedding provider is configured — vector search, persisting partial progress atomically as it goes. Start a build, then POLL `action: \"status\"` every few seconds until `state` is \"done\" (or \"error\"); calling build again while one is running just returns current progress. `action: \"status\"` reports the build state (idle|building|done|error), fetch/embed progress, index size and the active embedder. `action: \"stop\"` cancels a running build (partial data is kept and stays searchable). A partially built index is always usable for keyword search. Local embeddings are CPU-bound (see ZOTEUS_EMBEDDINGS), so large builds take a while — poll status rather than retrying build.", | ||
| inputSchema: { | ||
| action: z.enum(['build', 'refresh', 'status']), | ||
| action: z.enum(['build', 'refresh', 'status', 'stop']), | ||
| library_type: z.enum(['user', 'group']).optional(), | ||
| library_id: z.number().int().optional(), | ||
| limit: z | ||
| .number() | ||
| .int() | ||
| .min(1) | ||
| .max(MAX_ITEMS) | ||
| .optional() | ||
| .describe(`Max items to index (default ${MAX_ITEMS}, which is also the hard cap).`), | ||
| }, | ||
@@ -29,13 +23,24 @@ annotations: { readOnlyHint: false, openWorldHint: true }, | ||
| if (args.action === 'status') { | ||
| const s = ctx.search.status(); | ||
| return ok({ ...s }, `Index: ${s.documents} passages over ${s.items} items; embedder=${s.embedder}.`); | ||
| const s = ctx.search.buildStatus(); | ||
| return ok({ ...s }, statusSummary(s)); | ||
| } | ||
| if (args.action === 'stop') { | ||
| const stopped = ctx.search.requestStop(); | ||
| if (stopped) { | ||
| return ok({ ...ctx.search.buildStatus() }, 'Stop requested — the build halts after the current page/batch and keeps the partial index. Poll action:"status".'); | ||
| } | ||
| return ok({ ...ctx.search.buildStatus() }, 'No build is currently running.'); | ||
| } | ||
| // build / refresh: kick off a background job and return immediately. | ||
| if (ctx.search.isBuilding) { | ||
| const s = ctx.search.buildStatus(); | ||
| return ok({ ...s }, `A build is already in progress — ${progressLine(s)}. Poll action:"status" instead of starting another build.`); | ||
| } | ||
| const lib = args.library_id | ||
| ? { type: (args.library_type ?? 'group'), id: args.library_id } | ||
| : ctx.router.defaultLibrary(); | ||
| const items = await fetchAllItems(ctx, lib); | ||
| const status = await ctx.search.build(items, { version: items.length }); | ||
| await saveIndex(ctx.search, ctx.searchIndexPath).catch((e) => ctx.logger.warn(`Could not persist index: ${e instanceof Error ? e.message : String(e)}`)); | ||
| return ok({ ...status }, `Indexed ${status.documents} passages over ${status.items} items (embedder=${status.embedder}). ` + | ||
| 'The index is ready — run zotero_semantic_search now to search the library by meaning.'); | ||
| : undefined; | ||
| const maxItems = Math.min(args.limit ?? MAX_ITEMS, MAX_ITEMS); | ||
| const s = startIndexBuild(ctx, lib, maxItems); | ||
| return ok({ ...s }, `Index build started in the background (up to ${maxItems} items). ` + | ||
| 'Poll zotero_index action:"status" every few seconds until state is "done"; use action:"stop" to cancel.'); | ||
| }, | ||
@@ -42,0 +47,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index-tool.js","sourceRoot":"","sources":["../../src/tools/index-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAG9D,MAAM,SAAS,GAAG,IAAI,CAAC;AAEvB,KAAK,UAAU,aAAa,CAAC,GAAgB,EAAE,GAAe;IAC5D,MAAM,GAAG,GAAU,EAAE,CAAC;IACtB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,IAAI,GAAG,CAAC,MAAM,IAAI,SAAS;YAAE,MAAM;IAClG,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,SAAS,GAAmB;IAChC,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,iCAAiC;IACxC,WAAW,EACT,+lBAA+lB;IACjmB,WAAW,EAAE;QACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC9C,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACxC;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;IACzD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,SAAS,kBAAkB,CAAC,CAAC,KAAK,oBAAoB,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvG,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU;YACzB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY,IAAI,OAAO,CAAqB,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE;YACnF,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,MAAM,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3D,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAC1F,CAAC;QACF,OAAO,EAAE,CACP,EAAE,GAAG,MAAM,EAAE,EACb,WAAW,MAAM,CAAC,SAAS,kBAAkB,MAAM,CAAC,KAAK,oBAAoB,MAAM,CAAC,QAAQ,KAAK;YAC/F,uFAAuF,CAC1F,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,SAAS,CAAC"} | ||
| {"version":3,"file":"index-tool.js","sourceRoot":"","sources":["../../src/tools/index-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGtG,MAAM,SAAS,GAAmB;IAChC,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,iCAAiC;IACxC,WAAW,EACT,mnCAAmnC;IACrnC,WAAW,EAAE;QACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtD,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACvC,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,SAAS,CAAC;aACd,QAAQ,EAAE;aACV,QAAQ,CAAC,+BAA+B,SAAS,gCAAgC,CAAC;KACtF;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;IACzD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACnC,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACzC,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,EAAE,CACP,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,EAC/B,kHAAkH,CACnH,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE,gCAAgC,CAAC,CAAC;QAC/E,CAAC;QAED,qEAAqE;QACrE,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACnC,OAAO,EAAE,CACP,EAAE,GAAG,CAAC,EAAE,EACR,oCAAoC,YAAY,CAAC,CAAC,CAAC,2DAA2D,CAC/G,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAA2B,IAAI,CAAC,UAAU;YACjD,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY,IAAI,OAAO,CAAqB,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE;YACnF,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,EAAE,CACP,EAAE,GAAG,CAAC,EAAE,EACR,gDAAgD,QAAQ,WAAW;YACjE,yGAAyG,CAC5G,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,SAAS,CAAC"} |
@@ -18,2 +18,4 @@ import whoami from './whoami.js'; | ||
| import attachment from './attachment.js'; | ||
| import annotate from './annotate.js'; | ||
| import attachFile from './attach-file.js'; | ||
| import importTool from './import.js'; | ||
@@ -51,2 +53,4 @@ import styles from './styles.js'; | ||
| attachment, | ||
| annotate, | ||
| attachFile, | ||
| // Citation pipeline (M5) | ||
@@ -53,0 +57,0 @@ importTool, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,OAAO,MAAM,eAAe,CAAC;AACpC,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AACxD,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,kBAAkB,MAAM,0BAA0B,CAAC;AAC1D,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,cAAc,MAAM,sBAAsB,CAAC;AAClD,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,eAAe,MAAM,uBAAuB,CAAC;AACpD,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,MAAM,CAAC,MAAM,KAAK,GAAqB;IACrC,OAAO;IACP,MAAM;IACN,WAAW;IACX,OAAO;IACP,UAAU;IACV,aAAa;IACb,WAAW;IACX,UAAU;IACV,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,UAAU;IACV,aAAa;IACb,sCAAsC;IACtC,MAAM;IACN,UAAU;IACV,QAAQ;IACR,WAAW;IACX,IAAI;IACJ,UAAU;IACV,yBAAyB;IACzB,UAAU;IACV,MAAM;IACN,kBAAkB;IAClB,YAAY;IACZ,8BAA8B;IAC9B,SAAS;IACT,cAAc;IACd,+BAA+B;IAC/B,OAAO;IACP,kCAAkC;IAClC,WAAW;IACX,uDAAuD;IACvD,QAAQ;IACR,eAAe;IACf,QAAQ;CACT,CAAC"} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,OAAO,MAAM,eAAe,CAAC;AACpC,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,iBAAiB,MAAM,yBAAyB,CAAC;AACxD,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAC1C,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,kBAAkB,MAAM,0BAA0B,CAAC;AAC1D,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,cAAc,MAAM,sBAAsB,CAAC;AAClD,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAC5C,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,eAAe,MAAM,uBAAuB,CAAC;AACpD,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,MAAM,CAAC,MAAM,KAAK,GAAqB;IACrC,OAAO;IACP,MAAM;IACN,WAAW;IACX,OAAO;IACP,UAAU;IACV,aAAa;IACb,WAAW;IACX,UAAU;IACV,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,UAAU;IACV,aAAa;IACb,sCAAsC;IACtC,MAAM;IACN,UAAU;IACV,QAAQ;IACR,WAAW;IACX,IAAI;IACJ,UAAU;IACV,QAAQ;IACR,UAAU;IACV,yBAAyB;IACzB,UAAU;IACV,MAAM;IACN,kBAAkB;IAClB,YAAY;IACZ,8BAA8B;IAC9B,SAAS;IACT,cAAc;IACd,+BAA+B;IAC/B,OAAO;IACP,kCAAkC;IAClC,WAAW;IACX,uDAAuD;IACvD,QAAQ;IACR,eAAe;IACf,QAAQ;CACT,CAAC"} |
| import { z } from 'zod'; | ||
| import { ok } from '../registry/registry.js'; | ||
| import { progressLine, startIndexBuild } from '../features/search/build.js'; | ||
| const semanticSearch = { | ||
| name: 'zotero_semantic_search', | ||
| title: 'Semantic / hybrid library search', | ||
| description: 'Search the library by meaning, not just keywords. Combines BM25 keyword scoring with vector similarity (when an embedding provider is configured) via reciprocal-rank fusion, and returns the best-matching items with a snippet and score. `mode`: "auto" (hybrid, default), "keyword" (BM25 only), or "semantic" (vector only). Requires the index to be built first with zotero_index (action:"build"); if it is empty, this returns guidance to build it. For exact field/tag/itemType filtering use zotero_search_items instead; use this for conceptual/"papers about X" queries. To read the actual passages of a found item (with page locators) use zotero_get_fulltext.', | ||
| description: 'Search the library by meaning, not just keywords. Combines BM25 keyword scoring with vector similarity (when an embedding provider is configured) via reciprocal-rank fusion, and returns the best-matching items with a snippet and score. `mode`: "auto" (hybrid, default), "keyword" (BM25 only), or "semantic" (vector only). The index must be built once before first use: when it is empty this tool starts a background build automatically (`auto_build`, on by default) and tells you to poll zotero_index action:"status" and retry — pass `auto_build:false` to opt out. For exact field/tag/itemType filtering use zotero_search_items instead; use this for conceptual/"papers about X" queries. To read the actual passages of a found item (with page locators) use zotero_get_fulltext.', | ||
| inputSchema: { | ||
@@ -11,2 +12,6 @@ q: z.string().min(1).describe('Natural-language query.'), | ||
| mode: z.enum(['auto', 'keyword', 'semantic']).optional(), | ||
| auto_build: z | ||
| .boolean() | ||
| .optional() | ||
| .describe('Start building the index automatically in the background when it is empty (default true).'), | ||
| }, | ||
@@ -16,2 +21,33 @@ annotations: { readOnlyHint: true, openWorldHint: true }, | ||
| if (ctx.search.isEmpty) { | ||
| // A build is already on its way (started here or via zotero_index): report progress. | ||
| if (ctx.search.isBuilding) { | ||
| const s = ctx.search.buildStatus(); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: `The semantic-search index is being built right now — ${progressLine(s)}. ` + | ||
| 'Poll zotero_index with action:"status" until state is "done", then retry this search.', | ||
| }, | ||
| ], | ||
| structuredContent: { ...s, autoBuild: true }, | ||
| isError: true, | ||
| }; | ||
| } | ||
| if (args.auto_build !== false) { | ||
| // First use: populate the index on the fly instead of leaving the user stranded. | ||
| const s = startIndexBuild(ctx); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: 'The semantic-search index is empty, so a background build was started automatically ' + | ||
| `(first-time setup; ${progressLine(s)}). Poll zotero_index with action:"status" every few seconds ` + | ||
| 'until state is "done", then retry this search. Pass auto_build:false to opt out.', | ||
| }, | ||
| ], | ||
| structuredContent: { ...s, autoBuild: true }, | ||
| isError: true, | ||
| }; | ||
| } | ||
| return { | ||
@@ -18,0 +54,0 @@ content: [ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../src/tools/semantic-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,EAAE,EAAE,MAAM,yBAAyB,CAAC;AAE7C,MAAM,cAAc,GAAmB;IACrC,IAAI,EAAE,wBAAwB;IAC9B,KAAK,EAAE,kCAAkC;IACzC,WAAW,EACT,mpBAAmpB;IACrpB,WAAW,EAAE;QACX,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QACxD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QACvF,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;KACzD;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IACxD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,oFAAoF;qBAC3F;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1F,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM;YACzB,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,mBAAmB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI;YAC9E,CAAC,CAAC,mBAAmB,IAAI,CAAC,CAAC,IAAI,CAAC;QAClC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC;CACF,CAAC;AAEF,eAAe,cAAc,CAAC"} | ||
| {"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../src/tools/semantic-search.ts"],"names":[],"mappings":"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"} |
| import { z } from 'zod'; | ||
| import { ok, requireCloudLibrary } from '../registry/registry.js'; | ||
| import { ok, requireCloudLibrary, isLocalWritesUnavailable, ensureLocalApi } from '../registry/registry.js'; | ||
| function versionOf(item) { | ||
@@ -9,3 +9,3 @@ return item?.version ?? item?.data?.version; | ||
| title: 'Trash or restore Zotero items', | ||
| description: 'Move items to the trash (the safe, REVERSIBLE default) or restore them. This sets the `deleted` flag (1=trash, 0=restore) — it is NOT a permanent delete, so trashed items can be recovered here or in the Zotero app. Use this instead of zotero_delete_items unless you truly need irreversible removal. Provide `item_keys` and optional `action` (default "trash"). Writes go to the cloud Web API.', | ||
| description: 'Move items to the trash (the safe, REVERSIBLE default) or restore them. This sets the `deleted` flag (1=trash, 0=restore) — it is NOT a permanent delete, so trashed items can be recovered here or in the Zotero app. Use this instead of zotero_delete_items unless you truly need irreversible removal. Provide `item_keys` and optional `action` (default "trash"). Writes go to the running Zotero desktop app for your personal library (via its local-API writes where available), otherwise to the cloud Web API.', | ||
| inputSchema: { | ||
@@ -19,4 +19,23 @@ item_keys: z.array(z.string()).min(1).describe('Item keys to trash or restore.'), | ||
| handler: async (args, ctx) => { | ||
| const deleted = args.action === 'restore' ? 0 : 1; | ||
| // Local-first for the personal library when the desktop app supports writes. | ||
| if (ctx.localWrites && !args.library_id && (await ensureLocalApi(ctx))) { | ||
| try { | ||
| if (deleted === 1) { | ||
| await ctx.localWrites.deleteItems(args.item_keys, false); | ||
| return ok({ updated: args.item_keys, target: 'local' }, `Trashed ${args.item_keys.length} item(s) via the Zotero desktop app.`); | ||
| } | ||
| const objects = []; | ||
| for (const key of args.item_keys) | ||
| objects.push({ key, deleted: 0 }); | ||
| const result = await ctx.localWrites.writeItems(objects); | ||
| return ok({ updated: result.successful.map((s) => s.key), failed: result.failed, target: 'local' }, `Restored ${result.successful.length} item(s) via the Zotero desktop app.`); | ||
| } | ||
| catch (e) { | ||
| if (!isLocalWritesUnavailable(e)) | ||
| throw e; | ||
| ctx.logger.info(`Local-API writes unavailable (${e instanceof Error ? e.message : e}); falling back to the cloud Web API.`); | ||
| } | ||
| } | ||
| const lib = requireCloudLibrary(ctx, args); | ||
| const deleted = args.action === 'restore' ? 0 : 1; | ||
| const objects = []; | ||
@@ -23,0 +42,0 @@ for (const key of args.item_keys) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"trash-items.js","sourceRoot":"","sources":["../../src/tools/trash-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,EAAE,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAElE,SAAS,SAAS,CAAC,IAAS;IAC1B,OAAO,IAAI,EAAE,OAAO,IAAI,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,GAAmB;IACjC,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,+BAA+B;IACtC,WAAW,EACT,yYAAyY;IAC3Y,WAAW,EAAE;QACX,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAChF,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC5E,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACxC;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;IACjF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,MAAM,OAAO,GAAU,EAAE,CAAC;QAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QAC9C,MAAM,OAAO,GACX,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,UAAU;YAC7C,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrE,OAAO,EAAE,CACP,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,iBAAiB,EAAE,EACjH,OAAO,CACR,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,UAAU,CAAC"} | ||
| {"version":3,"file":"trash-items.js","sourceRoot":"","sources":["../../src/tools/trash-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,EAAE,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE5G,SAAS,SAAS,CAAC,IAAS;IAC1B,OAAO,IAAI,EAAE,OAAO,IAAI,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,GAAmB;IACjC,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,+BAA+B;IACtC,WAAW,EACT,2fAA2f;IAC7f,WAAW,EAAE;QACX,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QAChF,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC5E,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;KACxC;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;IACjF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,6EAA6E;QAC7E,IAAI,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACvE,IAAI,CAAC;gBACH,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;oBAClB,MAAM,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;oBACzD,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,WAAW,IAAI,CAAC,SAAS,CAAC,MAAM,sCAAsC,CAAC,CAAC;gBAClI,CAAC;gBACD,MAAM,OAAO,GAAU,EAAE,CAAC;gBAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS;oBAAE,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;gBACpE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACzD,OAAO,EAAE,CACP,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EACxF,YAAY,MAAM,CAAC,UAAU,CAAC,MAAM,sCAAsC,CAC3E,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;oBAAE,MAAM,CAAC,CAAC;gBAC1C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC;YAC9H,CAAC;QACH,CAAC;QACD,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAU,EAAE,CAAC;QAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QAC9C,MAAM,OAAO,GACX,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,UAAU;YAC7C,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrE,OAAO,EAAE,CACP,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,iBAAiB,EAAE,EACjH,OAAO,CACR,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,UAAU,CAAC"} |
+1
-1
| { | ||
| "name": "@oscardvs/zoteus", | ||
| "version": "1.1.0", | ||
| "version": "1.2.0", | ||
| "description": "The everything Zotero MCP server — complete Zotero Web API v3 + desktop local API for Claude and any MCP client.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
+20
-13
@@ -7,3 +7,3 @@ <div align="center"> | ||
| The **everything Zotero MCP server**. Give Claude, Cursor, and any [MCP](https://modelcontextprotocol.io) client complete, **safe** access to your [Zotero](https://www.zotero.org) library — search papers, add by DOI, format bibliographies in ~2,800 styles, run semantic search over your own PDFs, and ground every answer in a source you actually own. **Local-first. Private. One command.** | ||
| The **everything Zotero MCP server**. Give Claude, Cursor, and any [MCP](https://modelcontextprotocol.io) client complete, **safe** access to your [Zotero](https://www.zotero.org) library — search papers, add by DOI, format bibliographies in ~2,800 styles, run semantic search over your library's metadata and abstracts, pull exact passages from your PDFs, and ground every answer in a source you actually own. **Local-first. Private. One command.** | ||
@@ -29,10 +29,12 @@ [](https://www.npmjs.com/package/@oscardvs/zoteus) | ||
| For normal use there is **nothing to download or unzip from GitHub** — your AI app fetches Zoteus automatically when it first runs. New to this? Follow the no-code getting-started guide → [`docs/getting-started.md`](./docs/getting-started.md) | ||
| | Client | Command | | ||
| |---|---| | ||
| | **Claude Desktop (one-click)** | download `zoteus.mcpb` from the [latest release](https://github.com/oscardvs/zoteus/releases/latest) → double-click | | ||
| | **Claude Code** | `claude mcp add --transport stdio zoteus -- npx -y @oscardvs/zoteus` | | ||
| | **Cursor / VS Code / Claude Desktop / Codex / Zed…** | `npx add-mcp @oscardvs/zoteus` | | ||
| | **Claude Desktop (one-click)** | download `zoteus.mcpb` from the [latest release](https://github.com/oscardvs/zoteus/releases/latest) → double-click | | ||
| | **claude.ai (web)** | Add custom connector → your hosted URL (OAuth) | | ||
| Add your cloud key for writes/sync/groups (optional — reads work key-free against the desktop app): | ||
| Add your cloud key for sync, group libraries, and writes without the desktop app (optional — reads *and* personal-library writes work key-free against a running Zotero): | ||
@@ -43,3 +45,3 @@ ```bash | ||
| > Get a key at [zotero.org/settings/keys](https://www.zotero.org/settings/keys). For key-free local reads, enable **Settings → Advanced → "Allow other applications on this computer to communicate with Zotero"** in the desktop app. | ||
| > Get a key at [zotero.org/settings/keys](https://www.zotero.org/settings/keys). For key-free local reads and writes, enable **Settings → Advanced → "Allow other applications on this computer to communicate with Zotero"** in the desktop app. | ||
@@ -58,3 +60,3 @@ --- | ||
| | CSL bibliographies (~2,800 styles) | ✅ | rare | ❌ | | ||
| | Local hybrid semantic search over PDFs | ✅ | some (cloud) | varies | | ||
| | Local hybrid semantic search + full-text PDF retrieval | ✅ | some (cloud) | varies | | ||
| | No Python — TypeScript, one `npx` | ✅ | varies | n/a | | ||
@@ -66,9 +68,11 @@ | MCP Resources + Prompts + code-execution | ✅ | ❌ | n/a | | ||
| - **Find anything in your own work.** *"Find papers in my library that argue against X"* — hybrid keyword + semantic search across metadata, full text, and annotations, returned **with the page number**. | ||
| - **Find anything in your own work.** *"Find papers in my library that argue against X"* — hybrid keyword + semantic search over your library's titles, abstracts, creators, and tags, plus full-text keyword search inside your PDFs and notes, with the matching passage returned **with the page number**. | ||
| - **Cite without hallucinating.** Zoteus surfaces *your* Zotero citation data and formats it with [citeproc-js](https://citeproc-js.readthedocs.io) in any [CSL](https://citationstyles.org) style — it never invents a reference. | ||
| - **Add a paper by identifier.** Drop in a DOI or arXiv id and Zoteus fetches the metadata and files it — works out of the box via built-in resolvers, no extra services needed (a Zotero translation-server extends this to ISBN/PMID/URLs; see [`docs/resolver.md`](./docs/resolver.md)). | ||
| - **Write back, safely.** Create items, edit, tag, organize — versioned with optimistic-locking retries, reversible trash by default, permanent delete opt-in and confirmation-gated. | ||
| - **Ground claims in the PDF.** `zotero_get_fulltext` returns the relevant passage with character offsets, nearest heading, and a page locator. | ||
| - **Write straight to the desktop app.** Personal-library writes go to your running Zotero — **no cloud API key needed**. On Zotero 9+ that's the local API behind a key you grant once ("Always Allow"); on older builds it's the same connector protocol the browser extensions use. The cloud Web API is the fallback for group libraries and for when the app isn't running. | ||
| - **Annotate PDFs and attach files.** `zotero_annotate` adds real highlights, underlines, and notes — the same objects the Zotero PDF reader creates, positioned on the page — and `zotero_attach_file` stores a local file or a URL as an attachment under any item. | ||
| - **Ground claims in the PDF.** `zotero_get_fulltext` returns the relevant passage with character offsets, nearest heading, and a page locator — extracting the text on the fly when Zotero hasn't indexed the PDF. | ||
| - **Follow the scholarship.** A scholarly-context graph over OpenAlex / Crossref / Semantic Scholar. | ||
| - **Built for agents.** ~28 consolidated, well-described tools (not 70 thin endpoint mirrors), `zotero_*`-namespaced, structured outputs, and a generated tool tree for the [code-execution-with-MCP](https://www.anthropic.com/engineering/code-execution-with-mcp) pattern. | ||
| - **Built for agents.** 30 consolidated, well-described tools (not 70 thin endpoint mirrors), `zotero_*`-namespaced, structured outputs, and a generated tool tree for the [code-execution-with-MCP](https://www.anthropic.com/engineering/code-execution-with-mcp) pattern. | ||
@@ -78,7 +82,9 @@ ## How it works | ||
| 1. **Install** — one `npx` command (or the one-click `.mcpb`). | ||
| 2. **Connect** — paste your Zotero API key (or just run the desktop app for key-free local reads). | ||
| 2. **Connect** — just run the desktop app for key-free local access, or paste your Zotero API key. | ||
| 3. **Ask** — your AI can now search, cite, add, and organize your library. | ||
| Zoteus auto-detects your running Zotero desktop app and uses its fast, key-free **local API** for reads (full PDFs, real saved-search results), falling back to the cloud **Web API v3** for writes, sync, and group libraries. | ||
| Zoteus auto-detects your running Zotero desktop app and talks to it directly: its fast, key-free **local API** for reads (full PDFs, real saved-search results), and the desktop app itself for personal-library writes (imports, annotations, attachments, trash). The cloud **Web API v3** is the fallback — and stays required for sync, group libraries, and writes when the app isn't running. Details: [`docs/writing.md`](./docs/writing.md). | ||
| > **Semantic search — one-time setup.** The first `zotero_semantic_search` builds the library index automatically in the background (auto-build). On very large libraries you can also run `zotero_index` (action:"build") yourself, then poll action:"status" until done. | ||
| ## Configuration | ||
@@ -88,4 +94,5 @@ | ||
| |---|---|---| | ||
| | `ZOTERO_API_KEY` | — | Cloud auth (writes/sync/groups; optional for local-only reads) | | ||
| | `ZOTEUS_LOCAL` | `auto` | `auto\|on\|off` — use the Zotero desktop local API | | ||
| | `ZOTERO_API_KEY` | — | Cloud auth (sync, groups, writes without the desktop app; optional otherwise) | | ||
| | `ZOTEUS_LOCAL` | `auto` | `auto\|on\|off` — use the Zotero desktop app (reads + personal-library writes) | | ||
| | `ZOTEUS_LOCAL_API_KEY` | — | Pre-provision the Zotero 9+ desktop write key (else granted once, in-app) | | ||
| | `ZOTEUS_EMBEDDINGS` | `local` | `local\|openai\|gemini\|off` for semantic search | | ||
@@ -98,3 +105,3 @@ | `ZOTEUS_ALLOW_DELETE` | `false` | Must be `true` to expose permanent deletion | | ||
| 📚 **[zoteus.com/docs](https://zoteus.com/docs)** · [Configuration](./docs/configuration.md) · [Import & resolver](./docs/resolver.md) · [Architecture](./docs/architecture.md) · [Safe writes](./docs/writing.md) · [Citations](./docs/citations.md) · [Semantic search](./docs/semantic-search.md) · [Scholarly context](./docs/scholar.md) · [Code execution](./docs/code-execution.md) · [Deployment](./docs/deployment.md) | ||
| 📚 **[zoteus.com/docs](https://zoteus.com/docs)** · [Getting started](./docs/getting-started.md) · [Configuration](./docs/configuration.md) · [Import & resolver](./docs/resolver.md) · [Architecture](./docs/architecture.md) · [Safe writes](./docs/writing.md) · [Citations](./docs/citations.md) · [Semantic search](./docs/semantic-search.md) · [Scholarly context](./docs/scholar.md) · [Code execution](./docs/code-execution.md) · [Deployment](./docs/deployment.md) | ||
@@ -101,0 +108,0 @@ ## Contributing |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
772290
22.16%258
6.17%9486
21.79%107
7%25
19.05%51
27.5%