@hiai-gg/docsmint 0.6.5 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -1
- package/dist/backend/index.js +32 -18
- package/package.json +1 -1
- package/packages/cli/src/index.ts +1 -1
- package/packages/mcp-server/src/server.ts +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -40,7 +40,32 @@ server.
|
|
|
40
40
|
- **Own the full stack**: application data, vectors, graph, queue, and files run
|
|
41
41
|
on infrastructure you control.
|
|
42
42
|
|
|
43
|
-
## What's new in DocsMint 0.6.
|
|
43
|
+
## What's new in DocsMint 0.6.7?
|
|
44
|
+
|
|
45
|
+
- **Reliable HTTPS sessions.** Every protected SvelteKit route accepts Better
|
|
46
|
+
Auth's secure production cookie as well as the local-development cookie.
|
|
47
|
+
- **Cleaner retrieval.** Deleted documents are excluded before exact, lexical,
|
|
48
|
+
fuzzy, vector, chunk, and graph ranking.
|
|
49
|
+
- **Explicit GraphRAG providers.** Entity extraction requires its own
|
|
50
|
+
chat-completion URL and never sends chat requests to an embedding endpoint.
|
|
51
|
+
- **Safer self-host defaults.** Auth origins are validated configuration, the
|
|
52
|
+
SeaweedFS Filer UI binds to loopback, folder moves refresh knowledge
|
|
53
|
+
metadata, and backups exclude `.env`.
|
|
54
|
+
|
|
55
|
+
DocsMint 0.6.7 includes the safe index recovery introduced in 0.6.6:
|
|
56
|
+
|
|
57
|
+
- **Safe explicit index recovery.** Admin document reindexing keeps the active
|
|
58
|
+
generation searchable until a new generation has passed embedding, graph,
|
|
59
|
+
summary, and finalize stages.
|
|
60
|
+
- **Truthful queue admission.** Maintenance requests force a replacement
|
|
61
|
+
generation and report an error when durable enqueue fails instead of
|
|
62
|
+
returning a false-positive success.
|
|
63
|
+
- **Verified MCP distribution.** The official MCP Registry manifest, npm stdio
|
|
64
|
+
package, hosted Streamable HTTP endpoint, bundled Skill, prompts, resources,
|
|
65
|
+
and 17-tool catalog remain one versioned contract.
|
|
66
|
+
|
|
67
|
+
DocsMint 0.6.6 includes the registry metadata fixes released in 0.6.3-0.6.5
|
|
68
|
+
and the complete MCP foundation introduced in 0.6.2:
|
|
44
69
|
|
|
45
70
|
- **Official MCP identity.** DocsMint now publishes the verified
|
|
46
71
|
`io.github.HiAi-gg/docsmint` registry identity for both the npm stdio server
|
package/dist/backend/index.js
CHANGED
|
@@ -77709,6 +77709,7 @@ var init_config_schema = __esm(() => {
|
|
|
77709
77709
|
WEBHOOK_SECRET: exports_external2.string().min(1, "WEBHOOK_SECRET must not be empty").default("change-me-to-random-32-chars").refine((val) => val !== "change-me-to-random-32-chars", "WEBHOOK_SECRET must be set in production"),
|
|
77710
77710
|
BETTER_AUTH_URL: exports_external2.string().default("http://localhost:50700"),
|
|
77711
77711
|
CORS_ORIGINS: exports_external2.string().optional(),
|
|
77712
|
+
TRUSTED_ORIGINS: exports_external2.string().optional(),
|
|
77712
77713
|
WEB_PORT: exports_external2.coerce.number().default(50701),
|
|
77713
77714
|
EMBEDDING_BASE_URL: exports_external2.string().optional(),
|
|
77714
77715
|
EMBEDDING_API_KEY: exports_external2.string().optional(),
|
|
@@ -192960,7 +192961,7 @@ var auth = betterAuth({
|
|
|
192960
192961
|
}),
|
|
192961
192962
|
secret: config3.BETTER_AUTH_SECRET,
|
|
192962
192963
|
baseURL: config3.BETTER_AUTH_URL,
|
|
192963
|
-
trustedOrigins:
|
|
192964
|
+
trustedOrigins: config3.TRUSTED_ORIGINS ? config3.TRUSTED_ORIGINS.split(",").map((origin) => origin.trim()).filter(Boolean) : ["http://localhost:50701", "http://127.0.0.1:50701"],
|
|
192964
192965
|
emailAndPassword: {
|
|
192965
192966
|
enabled: true
|
|
192966
192967
|
},
|
|
@@ -194473,7 +194474,7 @@ async function claimEnqueueSlot(docId, workspaceId) {
|
|
|
194473
194474
|
return true;
|
|
194474
194475
|
}
|
|
194475
194476
|
}
|
|
194476
|
-
async function enqueueReembed(docIds, workspaceId) {
|
|
194477
|
+
async function enqueueReembed(docIds, workspaceId, options = {}) {
|
|
194477
194478
|
const unique = new Set;
|
|
194478
194479
|
for (const id2 of docIds) {
|
|
194479
194480
|
if (typeof id2 !== "string" || id2.trim().length === 0)
|
|
@@ -194482,9 +194483,10 @@ async function enqueueReembed(docIds, workspaceId) {
|
|
|
194482
194483
|
}
|
|
194483
194484
|
let pushed = 0;
|
|
194484
194485
|
for (const id2 of unique) {
|
|
194485
|
-
if (await claimEnqueueSlot(id2, workspaceId)) {
|
|
194486
|
-
enqueueEmbedding(id2, "interactive", workspaceId);
|
|
194487
|
-
|
|
194486
|
+
if (options.bypassDedup || await claimEnqueueSlot(id2, workspaceId)) {
|
|
194487
|
+
const queued = await enqueueEmbedding(id2, options.source ?? "interactive", workspaceId, { forceNewGeneration: options.forceNewGeneration });
|
|
194488
|
+
if (queued)
|
|
194489
|
+
pushed += 1;
|
|
194488
194490
|
}
|
|
194489
194491
|
}
|
|
194490
194492
|
return pushed;
|
|
@@ -194620,14 +194622,20 @@ var adminRoutes = new Elysia({ prefix: "/api/admin" }).post("/reindex/:docId", a
|
|
|
194620
194622
|
set2.status = 404;
|
|
194621
194623
|
return { error: "Document not found" };
|
|
194622
194624
|
}
|
|
194623
|
-
await
|
|
194624
|
-
|
|
194625
|
+
const enqueued = await enqueueReembed([params.docId], undefined, {
|
|
194626
|
+
bypassDedup: true,
|
|
194627
|
+
forceNewGeneration: true,
|
|
194628
|
+
source: "reindex"
|
|
194625
194629
|
});
|
|
194626
|
-
|
|
194630
|
+
if (enqueued !== 1) {
|
|
194631
|
+
set2.status = 503;
|
|
194632
|
+
return { error: "Failed to queue document reindex" };
|
|
194633
|
+
}
|
|
194627
194634
|
return {
|
|
194628
194635
|
success: true,
|
|
194629
194636
|
documentId: params.docId,
|
|
194630
|
-
|
|
194637
|
+
enqueued,
|
|
194638
|
+
message: "Document reindex queued with a new generation"
|
|
194631
194639
|
};
|
|
194632
194640
|
} catch (err) {
|
|
194633
194641
|
logger3.error({ err, docId: params.docId }, "Admin reindex failed");
|
|
@@ -229059,8 +229067,8 @@ var folderRoutes = new Elysia({ prefix: "/api/folders" }).get("/:id", async ({ p
|
|
|
229059
229067
|
set2.status = 404;
|
|
229060
229068
|
return { error: "Folder not found" };
|
|
229061
229069
|
}
|
|
229062
|
-
if (parsed.data.name !== undefined) {
|
|
229063
|
-
reembedDocsInFolder(params2.id, userId, ctx.workspaceId).catch((err) => logger3.warn({ err, folderId: params2.id }, "Failed to enqueue re-embedding for folder
|
|
229070
|
+
if (parsed.data.name !== undefined || parsed.data.parentId !== undefined || parsed.data.categoryId !== undefined) {
|
|
229071
|
+
reembedDocsInFolder(params2.id, userId, ctx.workspaceId).catch((err) => logger3.warn({ err, folderId: params2.id }, "Failed to enqueue re-embedding for folder metadata change"));
|
|
229064
229072
|
invalidateDocListCache(userId);
|
|
229065
229073
|
}
|
|
229066
229074
|
return result.updated;
|
|
@@ -229912,7 +229920,7 @@ async function resolveVisibleIds(ctx, ids, adapter, scope = _buildGraphVisibilit
|
|
|
229912
229920
|
id: documents.id,
|
|
229913
229921
|
ownerId: documents.ownerId,
|
|
229914
229922
|
visibility: documents.visibility
|
|
229915
|
-
}).from(documents).where(and(inArray(documents.id, ids), scope.kind === "admin" ? undefined : scope.kind === "public" ? eq(documents.visibility, "public") : scope.kind === "share" ? inArray(documents.id, scope.allowedDocumentIds) : or(eq(documents.ownerId, scope.ownerId), eq(documents.visibility, "public")))));
|
|
229923
|
+
}).from(documents).where(and(inArray(documents.id, ids), isNull(documents.deletedAt), scope.kind === "admin" ? undefined : scope.kind === "public" ? eq(documents.visibility, "public") : scope.kind === "share" ? inArray(documents.id, scope.allowedDocumentIds) : or(eq(documents.ownerId, scope.ownerId), eq(documents.visibility, "public")))));
|
|
229916
229924
|
return new Set(rows.filter((row) => _isGraphDocumentVisible(scope, {
|
|
229917
229925
|
id: row.id,
|
|
229918
229926
|
ownerId: row.ownerId,
|
|
@@ -230354,6 +230362,7 @@ async function retrieveExact(ctx, plan, limit, execute, scope) {
|
|
|
230354
230362
|
1.0::double precision AS score
|
|
230355
230363
|
FROM documents d
|
|
230356
230364
|
WHERE d.owner_id = ${ctx.userId}
|
|
230365
|
+
AND d.deleted_at IS NULL
|
|
230357
230366
|
${scope}
|
|
230358
230367
|
AND (
|
|
230359
230368
|
lower(trim(d.title)) = lower(trim(${plan.normalized}))
|
|
@@ -230381,6 +230390,7 @@ async function retrieveFts(ctx, plan, limit, execute, scope) {
|
|
|
230381
230390
|
ts_rank(d.search_vector, websearch_to_tsquery('english', ${plan.normalized})) AS score
|
|
230382
230391
|
FROM documents d
|
|
230383
230392
|
WHERE d.owner_id = ${ctx.userId}
|
|
230393
|
+
AND d.deleted_at IS NULL
|
|
230384
230394
|
${scope}
|
|
230385
230395
|
AND d.search_vector @@ websearch_to_tsquery('english', ${plan.normalized})
|
|
230386
230396
|
UNION ALL
|
|
@@ -230388,6 +230398,7 @@ async function retrieveFts(ctx, plan, limit, execute, scope) {
|
|
|
230388
230398
|
ts_rank(d.search_vector_simple, websearch_to_tsquery('simple', ${plan.normalized})) AS score
|
|
230389
230399
|
FROM documents d
|
|
230390
230400
|
WHERE d.owner_id = ${ctx.userId}
|
|
230401
|
+
AND d.deleted_at IS NULL
|
|
230391
230402
|
${scope}
|
|
230392
230403
|
AND d.search_vector_simple @@ websearch_to_tsquery('simple', ${plan.normalized})
|
|
230393
230404
|
)
|
|
@@ -230406,6 +230417,7 @@ async function retrieveFuzzy(ctx, plan, limit, minimum, execute, scope) {
|
|
|
230406
230417
|
similarity(d.title, ${plan.normalized})::double precision AS score
|
|
230407
230418
|
FROM documents d
|
|
230408
230419
|
WHERE d.owner_id = ${ctx.userId}
|
|
230420
|
+
AND d.deleted_at IS NULL
|
|
230409
230421
|
${scope}
|
|
230410
230422
|
AND d.title % ${plan.normalized}
|
|
230411
230423
|
AND similarity(d.title, ${plan.normalized}) >= ${minimum}
|
|
@@ -230440,6 +230452,7 @@ async function retrieveVector(ctx, plan, limit, minimum, chunkLimit, execute, pr
|
|
|
230440
230452
|
FROM document_embeddings de
|
|
230441
230453
|
JOIN documents d ON d.id = de.document_id
|
|
230442
230454
|
WHERE d.owner_id = ${ctx.userId}
|
|
230455
|
+
AND d.deleted_at IS NULL
|
|
230443
230456
|
${scope}
|
|
230444
230457
|
AND d.active_embedding_generation IS NOT NULL
|
|
230445
230458
|
AND de.generation_id = d.active_embedding_generation
|
|
@@ -231172,6 +231185,7 @@ async function hydrateResults(ctx, items, includeChunks, query, allowedDocumentI
|
|
|
231172
231185
|
JOIN documents d ON d.id = de.document_id
|
|
231173
231186
|
WHERE de.document_id IN (${sql.join(ids.map((id3) => sql`${id3}`), sql`, `)})
|
|
231174
231187
|
AND ${tenantOwnerSql("d", ctx)}
|
|
231188
|
+
AND d.deleted_at IS NULL
|
|
231175
231189
|
AND d.active_embedding_generation IS NOT NULL
|
|
231176
231190
|
AND de.generation_id = d.active_embedding_generation
|
|
231177
231191
|
AND de.is_valid = true
|
|
@@ -233294,13 +233308,13 @@ var extractionOutputSchema = exports_external2.object({
|
|
|
233294
233308
|
entities: exports_external2.array(exports_external2.unknown())
|
|
233295
233309
|
});
|
|
233296
233310
|
async function callEntityExtractionLLM(text4, options) {
|
|
233297
|
-
const primaryBase = options.llmBaseUrl ?? config3.GRAPH_EXTRACT_BASE_URL
|
|
233311
|
+
const primaryBase = options.llmBaseUrl ?? config3.GRAPH_EXTRACT_BASE_URL;
|
|
233298
233312
|
const primaryExplicitKey = options.llmApiKey ?? config3.GRAPH_EXTRACT_API_KEY;
|
|
233299
|
-
const primaryModel = options.llmModel ?? config3.GRAPH_EXTRACT_MODEL ??
|
|
233313
|
+
const primaryModel = options.llmModel ?? config3.GRAPH_EXTRACT_MODEL ?? "gpt-4o-mini";
|
|
233300
233314
|
const primaryKey = primaryBase ? resolveGraphProviderKey(primaryBase, primaryExplicitKey) : "";
|
|
233301
|
-
const fallbackBase = config3.GRAPH_EXTRACT_FALLBACK_BASE_URL
|
|
233315
|
+
const fallbackBase = config3.GRAPH_EXTRACT_FALLBACK_BASE_URL;
|
|
233302
233316
|
const fallbackExplicitKey = config3.GRAPH_EXTRACT_FALLBACK_API_KEY;
|
|
233303
|
-
const fallbackModel = config3.GRAPH_EXTRACT_FALLBACK_MODEL ??
|
|
233317
|
+
const fallbackModel = config3.GRAPH_EXTRACT_FALLBACK_MODEL ?? primaryModel;
|
|
233304
233318
|
const fallbackKey = fallbackBase ? resolveGraphProviderKey(fallbackBase, fallbackExplicitKey) : "";
|
|
233305
233319
|
const providers = [];
|
|
233306
233320
|
if (primaryBase) {
|
|
@@ -234946,7 +234960,7 @@ var swaggerConfig = {
|
|
|
234946
234960
|
},
|
|
234947
234961
|
info: {
|
|
234948
234962
|
title: "DocsMint API",
|
|
234949
|
-
version: "0.6.
|
|
234963
|
+
version: "0.6.7",
|
|
234950
234964
|
description: "Self-hosted AI-first documentation platform. Full-text + semantic search, version history, sharing, and folder organization.",
|
|
234951
234965
|
contact: { name: "HiAi-gg", url: "https://github.com/HiAi-gg/docsmint" },
|
|
234952
234966
|
license: {
|
|
@@ -234988,7 +235002,7 @@ var app = new Elysia().use(bodySizeLimit).onError(({ error: error53, set: set2 }
|
|
|
234988
235002
|
set2.headers["X-Content-Type-Options"] = "nosniff";
|
|
234989
235003
|
set2.headers["X-Frame-Options"] = "DENY";
|
|
234990
235004
|
}).use(cors({
|
|
234991
|
-
origin: config3.CORS_ORIGINS
|
|
235005
|
+
origin: config3.CORS_ORIGINS ? config3.CORS_ORIGINS.split(",").map((origin) => origin.trim()).filter(Boolean) : [config3.BETTER_AUTH_URL],
|
|
234992
235006
|
credentials: true,
|
|
234993
235007
|
maxAge: 86400
|
|
234994
235008
|
})).use(config3.NODE_ENV !== "production" ? swagger(swaggerConfig) : (e3) => e3).get("/api/health", async ({ request }) => {
|
package/package.json
CHANGED
|
@@ -24,7 +24,7 @@ import { registerSearch } from './commands/search.js';
|
|
|
24
24
|
import { registerSnapshot } from './commands/snapshot.js';
|
|
25
25
|
import { registerUpdate } from './commands/update.js';
|
|
26
26
|
|
|
27
|
-
const VERSION = '0.6.
|
|
27
|
+
const VERSION = '0.6.7';
|
|
28
28
|
|
|
29
29
|
const program = new Command();
|
|
30
30
|
program.name('hiai-docs').description('CLI for the hiai-docs knowledge base').version(VERSION);
|
|
@@ -81,7 +81,7 @@ export interface CreateDocsmintMcpServerOptions {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
export function createDocsmintMcpServer(options: CreateDocsmintMcpServerOptions = {}): McpServer {
|
|
84
|
-
const server = new McpServer({ name: 'docsmint', version: '0.6.
|
|
84
|
+
const server = new McpServer({ name: 'docsmint', version: '0.6.7' });
|
|
85
85
|
registerDocsmintMcpCapabilities(server, options.client ?? defaultClient);
|
|
86
86
|
return server;
|
|
87
87
|
}
|
package/server.json
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"source": "github",
|
|
9
9
|
"id": "1249550690"
|
|
10
10
|
},
|
|
11
|
-
"version": "0.6.
|
|
11
|
+
"version": "0.6.7",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "@hiai-gg/docsmint",
|
|
16
|
-
"version": "0.6.
|
|
16
|
+
"version": "0.6.7",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
},
|