@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 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.2?
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
@@ -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: process.env.TRUSTED_ORIGINS ? process.env.TRUSTED_ORIGINS.split(",").map((s2) => s2.trim()) : ["http://localhost:50701", "http://127.0.0.1:50701"],
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
- pushed += 1;
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 withTenant(adminTenantContextBound(), async (tx) => {
194624
- await tx.delete(documentEmbeddings).where(eq(documentEmbeddings.documentId, params.docId));
194625
+ const enqueued = await enqueueReembed([params.docId], undefined, {
194626
+ bypassDedup: true,
194627
+ forceNewGeneration: true,
194628
+ source: "reindex"
194625
194629
  });
194626
- enqueueReembed([params.docId]);
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
- message: "Existing embeddings cleared and document re-queued"
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 rename"));
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 ?? config3.EMBEDDING_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 ?? config3.EMBEDDING_MODEL ?? "gpt-4o-mini";
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 ?? config3.EMBEDDING_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 ?? config3.EMBEDDING_FALLBACK_MODEL ?? primaryModel;
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.5",
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?.split(",") ?? [config3.BETTER_AUTH_URL],
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hiai-gg/docsmint",
3
3
  "mcpName": "io.github.HiAi-gg/docsmint",
4
- "version": "0.6.5",
4
+ "version": "0.6.7",
5
5
  "type": "module",
6
6
  "browser": {
7
7
  "./dist/backend-launcher.js": false,
@@ -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.5';
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.5' });
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.5",
11
+ "version": "0.6.7",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "@hiai-gg/docsmint",
16
- "version": "0.6.5",
16
+ "version": "0.6.7",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },