daftari 1.6.0 → 1.7.1
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/CHANGELOG.md +52 -0
- package/README.md +63 -7
- package/dist/hooks/loader.d.ts +3 -1
- package/dist/hooks/loader.d.ts.map +1 -1
- package/dist/hooks/loader.js +37 -6
- package/dist/hooks/loader.js.map +1 -1
- package/dist/hooks/runner.d.ts +6 -1
- package/dist/hooks/runner.d.ts.map +1 -1
- package/dist/hooks/runner.js +48 -0
- package/dist/hooks/runner.js.map +1 -1
- package/dist/hooks/types.d.ts +7 -1
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -32
- package/dist/index.js.map +1 -1
- package/dist/search/index-state.d.ts +17 -0
- package/dist/search/index-state.d.ts.map +1 -0
- package/dist/search/index-state.js +68 -0
- package/dist/search/index-state.js.map +1 -0
- package/dist/search/reindex.d.ts +1 -0
- package/dist/search/reindex.d.ts.map +1 -1
- package/dist/search/reindex.js +105 -1
- package/dist/search/reindex.js.map +1 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +37 -8
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +67 -9
- package/dist/tools/write.js.map +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +49 -26
- package/dist/utils/config.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.7.1] - 2026-05-19
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **MCP server hang at startup** (#35, PR #36). The server no longer re-embeds
|
|
15
|
+
the entire vault on every launch and no longer waits for indexing to finish
|
|
16
|
+
before opening the stdio transport. Three compounding bugs are fixed:
|
|
17
|
+
(1) `main()` always called `reindexVault` even when `.daftari/index.db`
|
|
18
|
+
already reflected the files on disk — every restart re-embedded the whole
|
|
19
|
+
vault (~25 minutes on a 3,500-file vault); now a path→mtime manifest is
|
|
20
|
+
persisted in the SQLite meta table and compared on startup, so an
|
|
21
|
+
unchanged vault skips the embedding pass entirely. (2) The
|
|
22
|
+
`StdioServerTransport` opened only after indexing completed, so MCP
|
|
23
|
+
clients could not answer `initialize` for the whole duration; the
|
|
24
|
+
transport now opens first and indexing — when required — runs as a
|
|
25
|
+
background task. (3) Progress was emitted only on TTY stderr, leaving
|
|
26
|
+
every real (non-TTY) MCP client with zero output during a cold start;
|
|
27
|
+
progress now streams on stderr in both TTY (\\r-updated) and pipe (full
|
|
28
|
+
line every ~5%) modes. A new in-process `IndexState`
|
|
29
|
+
(`ready`/`indexing`/`error` + progress) gates `vault_search`,
|
|
30
|
+
`vault_search_related`, `vault_reindex`, `vault_write`, `vault_append`,
|
|
31
|
+
`vault_promote`, and `vault_deprecate` while indexing — those tools
|
|
32
|
+
return a progress-bearing busy error so clients can retry. Read tools
|
|
33
|
+
(`vault_read`, `vault_index`, `vault_status`) are unaffected because
|
|
34
|
+
they go to the filesystem, not the index. `--reindex` remains the one
|
|
35
|
+
synchronous mode (rebuild, exit).
|
|
36
|
+
|
|
37
|
+
## [1.7.0] - 2026-05-19
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- **Pre-write transform hooks** (#32). New `pre_write_transform` hook phase
|
|
42
|
+
runs before `validateFrontmatter` and can derive or override frontmatter
|
|
43
|
+
fields. Returns `Partial<Frontmatter>`. Refuses via throw. Existing
|
|
44
|
+
`pre_write` validators continue to run unchanged after validation. Closes
|
|
45
|
+
the gap where v1.6.0 hooks could observe and reject but could not derive
|
|
46
|
+
built-in fields. Declared under `hooks.pre_write_transform` in
|
|
47
|
+
`.daftari/config.yaml`; the runner merges each hook's patch Object.assign
|
|
48
|
+
style — shallow, last-writer-wins. Phase order is rigid:
|
|
49
|
+
`pre_write_transform` (declaration order), then `validateFrontmatter`, then
|
|
50
|
+
`pre_write` (declaration order), regardless of config layout. Fires for
|
|
51
|
+
`vault_write` and `vault_append`; `vault_promote` and `vault_deprecate`
|
|
52
|
+
bypass it, matching the `pre_write` bypass.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- The existing `pre_write` hook surface continues to half-mutate: a mutation
|
|
57
|
+
to `rawFrontmatter` inside a `pre_write` hook propagates for extension
|
|
58
|
+
fields but not for built-in fields. This behavior is preserved for
|
|
59
|
+
backward compatibility but is now implementation detail — new mutations
|
|
60
|
+
should use `pre_write_transform`.
|
|
61
|
+
|
|
10
62
|
## [1.6.0] - 2026-05-19
|
|
11
63
|
|
|
12
64
|
### Added
|
package/README.md
CHANGED
|
@@ -320,6 +320,59 @@ validate-only. Returning a non-array, or an array containing malformed issue
|
|
|
320
320
|
objects, is itself reported as a blocking issue tagged with the hook path —
|
|
321
321
|
hook bugs surface as loud failures, not silent passes.
|
|
322
322
|
|
|
323
|
+
### Transform hooks
|
|
324
|
+
|
|
325
|
+
A `pre_write` hook can observe and reject, but it cannot *change* the
|
|
326
|
+
frontmatter a write lands. **Transform hooks** can. A transform hook runs in an
|
|
327
|
+
earlier phase — before built-in schema validation — so it can derive or
|
|
328
|
+
override frontmatter fields the validator would otherwise reject as missing.
|
|
329
|
+
|
|
330
|
+
Transform hooks are declared under their own key, `pre_write_transform`:
|
|
331
|
+
|
|
332
|
+
```yaml
|
|
333
|
+
hooks:
|
|
334
|
+
pre_write_transform:
|
|
335
|
+
- path: .daftari/hooks/derive-status.mjs
|
|
336
|
+
pre_write:
|
|
337
|
+
- path: .daftari/hooks/forbid-status-skip.mjs
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
The phase order is fixed regardless of how the config lists the blocks: every
|
|
341
|
+
`pre_write_transform` hook runs (in declared order), then built-in schema
|
|
342
|
+
validation, then every `pre_write` validator (in declared order). A transform
|
|
343
|
+
always runs before any validator sees the frontmatter.
|
|
344
|
+
|
|
345
|
+
A transform hook returns a `Partial<Frontmatter>` patch — *not* a list of
|
|
346
|
+
issues:
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
// .daftari/hooks/derive-status.mjs
|
|
350
|
+
//
|
|
351
|
+
// context = { path: string; operation: 'create' | 'update' | 'append' }
|
|
352
|
+
export default function deriveStatus(frontmatter, context) {
|
|
353
|
+
if (frontmatter.decision_status === "ACTIVE") {
|
|
354
|
+
return { status: "canonical" };
|
|
355
|
+
}
|
|
356
|
+
return {}; // no change
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
The runner merges each patch into the candidate frontmatter **`Object.assign`
|
|
361
|
+
style**: shallow, last-writer-wins. A key present in the patch replaces the
|
|
362
|
+
existing value outright — arrays are replaced whole, never appended to or
|
|
363
|
+
merged element-wise. When two transforms target the same field, the
|
|
364
|
+
later-declared one wins. Each transform sees the merged output of every
|
|
365
|
+
transform declared before it.
|
|
366
|
+
|
|
367
|
+
A transform **refuses by throwing** — it does not return issues. A throw
|
|
368
|
+
becomes a synthetic blocking issue tagged with the hook path, identical to the
|
|
369
|
+
`pre_write` throw mechanism. Returning anything that is not an object (an
|
|
370
|
+
array, a primitive, `null`) is likewise a blocking issue.
|
|
371
|
+
|
|
372
|
+
Because transforms run before validation, a transform that sets an invalid
|
|
373
|
+
value — a `status` outside the allowed set, say — is caught by the built-in
|
|
374
|
+
validator exactly as a bad user-supplied value would be.
|
|
375
|
+
|
|
323
376
|
### Trust model
|
|
324
377
|
|
|
325
378
|
Hooks are **trusted code**. They run in the same Node process as the daftari
|
|
@@ -333,15 +386,18 @@ register hooks in v1.
|
|
|
333
386
|
|
|
334
387
|
### Scope and limits in v1
|
|
335
388
|
|
|
336
|
-
- **Surfaces:**
|
|
389
|
+
- **Surfaces:** `pre_write` (validators) and `pre_write_transform`
|
|
390
|
+
(field-deriving transforms). Future surfaces (`pre_read`, `post_write`,
|
|
337
391
|
etc.) are reserved — unrecognised keys under `hooks:` are a loud config
|
|
338
392
|
error, not a silent skip.
|
|
339
|
-
- **Operations:**
|
|
340
|
-
`vault_append`. `vault_promote` and `vault_deprecate` deliberately
|
|
341
|
-
hooks — they're narrow metadata mutations the server controls
|
|
342
|
-
-
|
|
343
|
-
|
|
344
|
-
|
|
393
|
+
- **Operations:** both hook surfaces fire for `vault_write` (create + update)
|
|
394
|
+
and `vault_append`. `vault_promote` and `vault_deprecate` deliberately
|
|
395
|
+
bypass hooks — they're narrow metadata mutations the server controls
|
|
396
|
+
end-to-end.
|
|
397
|
+
- **Two phases:** a `pre_write` hook returns a list of issues and can only
|
|
398
|
+
reject. A `pre_write_transform` hook returns a `Partial<Frontmatter>` patch
|
|
399
|
+
and can derive or override fields before validation — see "Transform
|
|
400
|
+
hooks" above.
|
|
345
401
|
- **Sync:** hook bodies are synchronous functions. The loader is async
|
|
346
402
|
(it has to dynamic-import the module), but each individual hook call is
|
|
347
403
|
not awaited.
|
package/dist/hooks/loader.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type Result } from "../frontmatter/types.js";
|
|
2
|
-
import type { HookDeclaration, LoadedHook } from "./types.js";
|
|
2
|
+
import type { HookDeclaration, LoadedHook, LoadedTransformHook } from "./types.js";
|
|
3
3
|
export declare function loadHook(vaultRoot: string, decl: HookDeclaration): Promise<Result<LoadedHook, Error>>;
|
|
4
|
+
export declare function loadPreWriteTransformHook(vaultRoot: string, decl: HookDeclaration): Promise<Result<LoadedTransformHook, Error>>;
|
|
4
5
|
export declare function loadHooks(vaultRoot: string, declarations: HookDeclaration[]): Promise<Result<LoadedHook[], Error>>;
|
|
6
|
+
export declare function loadPreWriteTransformHooks(vaultRoot: string, declarations: HookDeclaration[]): Promise<Result<LoadedTransformHook[], Error>>;
|
|
5
7
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/hooks/loader.ts"],"names":[],"mappings":"AAUA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/hooks/loader.ts"],"names":[],"mappings":"AAUA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AA0DpB,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAIpC;AAKD,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC,CAI7C;AAKD,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,eAAe,EAAE,GAC9B,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,CAAC,CAQtC;AAID,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,eAAe,EAAE,GAC9B,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,EAAE,KAAK,CAAC,CAAC,CAQ/C"}
|
package/dist/hooks/loader.js
CHANGED
|
@@ -26,11 +26,13 @@ function resolveHookPath(vaultRoot, hookPath) {
|
|
|
26
26
|
}
|
|
27
27
|
return ok(abs);
|
|
28
28
|
}
|
|
29
|
-
//
|
|
30
|
-
// anything else returns Result.err.
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
|
|
29
|
+
// Imports a hook module and returns its default export, which must be a
|
|
30
|
+
// function — anything else returns Result.err. Shared by both the pre_write
|
|
31
|
+
// and pre_write_transform loaders: the import, path-escape, and
|
|
32
|
+
// default-is-function checks are identical; only the typed cast the caller
|
|
33
|
+
// applies differs. The function is not validated beyond being callable —
|
|
34
|
+
// TypeScript types are erased at runtime.
|
|
35
|
+
async function importHookDefault(vaultRoot, decl) {
|
|
34
36
|
const resolved = resolveHookPath(vaultRoot, decl.path);
|
|
35
37
|
if (!resolved.ok)
|
|
36
38
|
return resolved;
|
|
@@ -50,7 +52,24 @@ export async function loadHook(vaultRoot, decl) {
|
|
|
50
52
|
if (typeof mod.default !== "function") {
|
|
51
53
|
return err(new Error(`hook '${decl.path}' must export a default function, got ${typeof mod.default}`));
|
|
52
54
|
}
|
|
53
|
-
return ok(
|
|
55
|
+
return ok(mod.default);
|
|
56
|
+
}
|
|
57
|
+
// Loads one pre_write hook module. The module's default export must be a
|
|
58
|
+
// function; anything else returns Result.err.
|
|
59
|
+
export async function loadHook(vaultRoot, decl) {
|
|
60
|
+
const fn = await importHookDefault(vaultRoot, decl);
|
|
61
|
+
if (!fn.ok)
|
|
62
|
+
return fn;
|
|
63
|
+
return ok({ declaration: decl, hook: fn.value });
|
|
64
|
+
}
|
|
65
|
+
// Loads one pre_write_transform hook module. Mirrors loadHook — same import,
|
|
66
|
+
// path-escape, and default-is-function checks — but the loaded function is
|
|
67
|
+
// typed as a transform hook (returns Partial<Frontmatter>, not issues).
|
|
68
|
+
export async function loadPreWriteTransformHook(vaultRoot, decl) {
|
|
69
|
+
const fn = await importHookDefault(vaultRoot, decl);
|
|
70
|
+
if (!fn.ok)
|
|
71
|
+
return fn;
|
|
72
|
+
return ok({ declaration: decl, hook: fn.value });
|
|
54
73
|
}
|
|
55
74
|
// Loads every declared hook in order. Returns Result.err on the first load
|
|
56
75
|
// failure — a vault with a broken hook declaration refuses to write, same
|
|
@@ -65,4 +84,16 @@ export async function loadHooks(vaultRoot, declarations) {
|
|
|
65
84
|
}
|
|
66
85
|
return ok(loaded);
|
|
67
86
|
}
|
|
87
|
+
// Loads every declared pre_write_transform hook in order. Fails fast on the
|
|
88
|
+
// first bad declaration, identical to loadHooks.
|
|
89
|
+
export async function loadPreWriteTransformHooks(vaultRoot, declarations) {
|
|
90
|
+
const loaded = [];
|
|
91
|
+
for (const decl of declarations) {
|
|
92
|
+
const result = await loadPreWriteTransformHook(vaultRoot, decl);
|
|
93
|
+
if (!result.ok)
|
|
94
|
+
return result;
|
|
95
|
+
loaded.push(result.value);
|
|
96
|
+
}
|
|
97
|
+
return ok(loaded);
|
|
98
|
+
}
|
|
68
99
|
//# sourceMappingURL=loader.js.map
|
package/dist/hooks/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/hooks/loader.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,0EAA0E;AAC1E,2EAA2E;AAC3E,wEAAwE;AACxE,mCAAmC;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/hooks/loader.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks/runner.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { ValidationIssue } from "../frontmatter/types.js";
|
|
2
|
-
import type { HookContext, LoadedHook } from "./types.js";
|
|
2
|
+
import type { HookContext, LoadedHook, LoadedTransformHook } from "./types.js";
|
|
3
3
|
export declare function runPreWriteHooks(hooks: LoadedHook[], frontmatter: Record<string, unknown>, context: HookContext): ValidationIssue[];
|
|
4
|
+
export interface TransformRunResult {
|
|
5
|
+
merged: Record<string, unknown>;
|
|
6
|
+
issues: ValidationIssue[];
|
|
7
|
+
}
|
|
8
|
+
export declare function runPreWriteTransformHooks(hooks: LoadedTransformHook[], frontmatter: Record<string, unknown>, context: HookContext): TransformRunResult;
|
|
4
9
|
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/hooks/runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/hooks/runner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE/E,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,UAAU,EAAE,EACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,EAAE,WAAW,GACnB,eAAe,EAAE,CAoCnB;AAaD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAcD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,mBAAmB,EAAE,EAC5B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,EAAE,WAAW,GACnB,kBAAkB,CA2BpB"}
|
package/dist/hooks/runner.js
CHANGED
|
@@ -39,4 +39,52 @@ export function runPreWriteHooks(hooks, frontmatter, context) {
|
|
|
39
39
|
}
|
|
40
40
|
return issues;
|
|
41
41
|
}
|
|
42
|
+
// Describes a transform hook's return value for an error message: "null",
|
|
43
|
+
// "array", or its typeof.
|
|
44
|
+
function describeReturn(v) {
|
|
45
|
+
if (v === null)
|
|
46
|
+
return "null";
|
|
47
|
+
if (Array.isArray(v))
|
|
48
|
+
return "array";
|
|
49
|
+
return typeof v;
|
|
50
|
+
}
|
|
51
|
+
// Executes pre_write_transform hooks against a candidate frontmatter. Hooks
|
|
52
|
+
// run in declaration order; each receives a fresh shallow copy of the
|
|
53
|
+
// *current* merged state, so a later transform sees an earlier one's output
|
|
54
|
+
// but cannot mutate the running state in place. A hook's Partial<Frontmatter>
|
|
55
|
+
// return is merged Object.assign-style — shallow, last-writer-wins, arrays
|
|
56
|
+
// replaced whole.
|
|
57
|
+
//
|
|
58
|
+
// A hook that throws becomes a synthetic blocking issue whose field is the
|
|
59
|
+
// hook path and whose message names the underlying error; nothing from a
|
|
60
|
+
// thrown hook is merged. A non-object return (array, primitive, null) is
|
|
61
|
+
// likewise a synthetic blocking issue with no merge. Every hook still runs
|
|
62
|
+
// even after an earlier hook failed — matching the run-all pre_write contract.
|
|
63
|
+
export function runPreWriteTransformHooks(hooks, frontmatter, context) {
|
|
64
|
+
const issues = [];
|
|
65
|
+
let merged = { ...frontmatter };
|
|
66
|
+
for (const { declaration, hook } of hooks) {
|
|
67
|
+
let partial;
|
|
68
|
+
try {
|
|
69
|
+
partial = hook({ ...merged }, context);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
73
|
+
issues.push({
|
|
74
|
+
field: declaration.path,
|
|
75
|
+
message: `transform hook threw: ${reason}`,
|
|
76
|
+
});
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (partial === null || typeof partial !== "object" || Array.isArray(partial)) {
|
|
80
|
+
issues.push({
|
|
81
|
+
field: declaration.path,
|
|
82
|
+
message: `transform hook returned non-object (got ${describeReturn(partial)})`,
|
|
83
|
+
});
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
merged = { ...merged, ...partial };
|
|
87
|
+
}
|
|
88
|
+
return { merged, issues };
|
|
89
|
+
}
|
|
42
90
|
//# sourceMappingURL=runner.js.map
|
package/dist/hooks/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/hooks/runner.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,wEAAwE;AACxE,0EAA0E;AAC1E,0EAA0E;AAC1E,mEAAmE;AAKnE,MAAM,UAAU,gBAAgB,CAC9B,KAAmB,EACnB,WAAoC,EACpC,OAAoB;IAEpB,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,KAAK,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAC1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,WAAW,CAAC,IAAI;oBACvB,OAAO,EAAE,gCAAgC,OAAO,MAAM,GAAG;iBAC1D,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IACE,KAAK,KAAK,IAAI;oBACd,OAAO,KAAK,KAAK,QAAQ;oBACzB,OAAQ,KAAyB,CAAC,KAAK,KAAK,QAAQ;oBACpD,OAAQ,KAAyB,CAAC,OAAO,KAAK,QAAQ,EACtD,CAAC;oBACD,MAAM,CAAC,IAAI,CAAC;wBACV,KAAK,EAAE,WAAW,CAAC,IAAI;wBACvB,OAAO,EAAE,kCAAkC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;qBACnE,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,KAAwB,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1D,MAAM,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,WAAW,CAAC,IAAI;gBACvB,OAAO,EAAE,eAAe,MAAM,EAAE;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/hooks/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/hooks/types.d.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import type { ValidationIssue } from "../frontmatter/types.js";
|
|
1
|
+
import type { Frontmatter, ValidationIssue } from "../frontmatter/types.js";
|
|
2
2
|
export type HookOperation = "create" | "update" | "append";
|
|
3
3
|
export interface HookContext {
|
|
4
4
|
path: string;
|
|
5
5
|
operation: HookOperation;
|
|
6
6
|
}
|
|
7
7
|
export type PreWriteHook = (frontmatter: Record<string, unknown>, context: HookContext) => ValidationIssue[];
|
|
8
|
+
export type PreWriteTransformHook = (frontmatter: Record<string, unknown>, context: HookContext) => Partial<Frontmatter>;
|
|
8
9
|
export interface HookDeclaration {
|
|
9
10
|
path: string;
|
|
10
11
|
}
|
|
11
12
|
export interface HookConfig {
|
|
12
13
|
preWrite: HookDeclaration[];
|
|
14
|
+
preWriteTransform: HookDeclaration[];
|
|
13
15
|
}
|
|
14
16
|
export interface LoadedHook {
|
|
15
17
|
declaration: HookDeclaration;
|
|
16
18
|
hook: PreWriteHook;
|
|
17
19
|
}
|
|
20
|
+
export interface LoadedTransformHook {
|
|
21
|
+
declaration: HookDeclaration;
|
|
22
|
+
hook: PreWriteTransformHook;
|
|
23
|
+
}
|
|
18
24
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/hooks/types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/hooks/types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAO5E,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAM3D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,aAAa,CAAC;CAC1B;AAOD,MAAM,MAAM,YAAY,GAAG,CACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,EAAE,WAAW,KACjB,eAAe,EAAE,CAAC;AASvB,MAAM,MAAM,qBAAqB,GAAG,CAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,WAAW,CAAC,CAAC;AAM1B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,iBAAiB,EAAE,eAAe,EAAE,CAAC;CACtC;AAKD,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,eAAe,CAAC;IAC7B,IAAI,EAAE,YAAY,CAAC;CACpB;AAID,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,eAAe,CAAC;IAC7B,IAAI,EAAE,qBAAqB,CAAC;CAC7B"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgCA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASrE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAE3D;AAED,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAuFhF"}
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
// Daftari MCP server entry point.
|
|
2
2
|
//
|
|
3
3
|
// Parses `--vault <path>`, verifies the vault directory exists, loads the RBAC
|
|
4
|
-
// config,
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// config, opens the MCP stdio transport, then — if the index isn't already
|
|
5
|
+
// current — runs a reindex in the background. Diagnostics go to stderr so they
|
|
6
|
+
// never corrupt the stdio JSON-RPC stream on stdout.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
8
|
+
// The transport opens before indexing on purpose: a cold reindex on a large
|
|
9
|
+
// vault is minutes long, and a client must be able to answer `initialize` and
|
|
10
|
+
// list tools immediately. Tools that depend on the index consult
|
|
11
|
+
// `getIndexStatus()` and reply "still indexing — N/M chunks" until the
|
|
12
|
+
// background pass finishes.
|
|
13
|
+
//
|
|
14
|
+
// `--reindex` is the one synchronous mode: rebuild the index, exit, do not
|
|
15
|
+
// start the server.
|
|
9
16
|
import { resolve } from "node:path";
|
|
10
17
|
import { pathToFileURL } from "node:url";
|
|
11
18
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
19
|
import { GUEST_ROLE, resolveAccess } from "./access/rbac.js";
|
|
13
|
-
import {
|
|
20
|
+
import { markIndexError, markIndexing, markIndexReady, setIndexProgress, } from "./search/index-state.js";
|
|
21
|
+
import { isIndexFresh, reindexVault } from "./search/reindex.js";
|
|
14
22
|
import { createServer } from "./server.js";
|
|
15
23
|
import { directoryExists } from "./storage/local.js";
|
|
16
24
|
import { loadConfig } from "./utils/config.js";
|
|
@@ -58,41 +66,98 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
58
66
|
if (access.role === null && roleName !== GUEST_ROLE) {
|
|
59
67
|
process.stderr.write(`daftari: warning: role '${roleName}' not found in config — running as deny-all guest\n`);
|
|
60
68
|
}
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
else {
|
|
82
|
-
// A failed index is not fatal: lexical search still works and the search
|
|
83
|
-
// tools retry indexing lazily on first use.
|
|
84
|
-
process.stderr.write(`daftari: warning: index build failed: ${reindexed.error.message}\n`);
|
|
85
|
-
}
|
|
86
|
-
if (argv.includes("--reindex")) {
|
|
87
|
-
if (!reindexed.ok)
|
|
69
|
+
// The persisted index is a derived cache: if every file on disk matches the
|
|
70
|
+
// manifest written by the last reindex, the on-disk index already reflects
|
|
71
|
+
// the vault and we can skip the embedding pass entirely (~25 min on a
|
|
72
|
+
// multi-thousand-file vault). --reindex forces a rebuild even when fresh.
|
|
73
|
+
const forceReindex = argv.includes("--reindex");
|
|
74
|
+
// --reindex is the one synchronous mode: rebuild and exit. No transport,
|
|
75
|
+
// no background work. The IndexState is updated for completeness but no
|
|
76
|
+
// tool runs against it in this mode.
|
|
77
|
+
if (forceReindex) {
|
|
78
|
+
markIndexing();
|
|
79
|
+
const reindexed = await reindexVault(vaultRoot, makeProgressReporter());
|
|
80
|
+
if (reindexed.ok) {
|
|
81
|
+
const r = reindexed.value;
|
|
82
|
+
markIndexReady();
|
|
83
|
+
process.stderr.write(`daftari: indexed ${r.documentCount} docs, ${r.chunkCount} chunks ` +
|
|
84
|
+
`(vectors ${r.vectorEnabled ? "on" : "off"})\n`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
markIndexError(reindexed.error.message);
|
|
88
|
+
process.stderr.write(`daftari: warning: index build failed: ${reindexed.error.message}\n`);
|
|
88
89
|
process.exitCode = 1;
|
|
90
|
+
}
|
|
89
91
|
return;
|
|
90
92
|
}
|
|
93
|
+
// Open MCP transport first so the client can answer `initialize` and
|
|
94
|
+
// `tools/list` immediately. Indexing — if needed — runs as a background
|
|
95
|
+
// task; tools that depend on the index will respond "still indexing" until
|
|
96
|
+
// it completes.
|
|
91
97
|
const server = createServer(vaultRoot, access);
|
|
92
98
|
const transport = new StdioServerTransport();
|
|
93
99
|
await server.connect(transport);
|
|
94
100
|
process.stderr.write(`daftari: serving vault at ${vaultRoot} (stdio) — ` +
|
|
95
101
|
`user=${access.user} role=${access.roleName}\n`);
|
|
102
|
+
const fresh = await isIndexFresh(vaultRoot);
|
|
103
|
+
if (fresh) {
|
|
104
|
+
process.stderr.write(`daftari: index is up to date — skipping reindex\n`);
|
|
105
|
+
markIndexReady();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// Background reindex. The promise is intentionally not awaited — main()
|
|
109
|
+
// returns once the transport is up, and the indexing pass runs to
|
|
110
|
+
// completion alongside the live server.
|
|
111
|
+
markIndexing();
|
|
112
|
+
process.stderr.write(`daftari: starting background reindex…\n`);
|
|
113
|
+
void runBackgroundReindex(vaultRoot);
|
|
114
|
+
}
|
|
115
|
+
async function runBackgroundReindex(vaultRoot) {
|
|
116
|
+
try {
|
|
117
|
+
const reindexed = await reindexVault(vaultRoot, makeProgressReporter());
|
|
118
|
+
if (reindexed.ok) {
|
|
119
|
+
const r = reindexed.value;
|
|
120
|
+
markIndexReady();
|
|
121
|
+
process.stderr.write(`daftari: indexed ${r.documentCount} docs, ${r.chunkCount} chunks ` +
|
|
122
|
+
`(vectors ${r.vectorEnabled ? "on" : "off"})\n`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
markIndexError(reindexed.error.message);
|
|
126
|
+
process.stderr.write(`daftari: warning: background index build failed: ${reindexed.error.message}\n`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
const reason = e instanceof Error ? (e.stack ?? e.message) : String(e);
|
|
131
|
+
markIndexError(reason);
|
|
132
|
+
process.stderr.write(`daftari: warning: background indexer crashed: ${reason}\n`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Builds a ReindexOptions whose onProgress streams to both stderr (for
|
|
136
|
+
// operator visibility) and the in-process IndexState (so tools can return
|
|
137
|
+
// progress to MCP clients). TTY stderr gets a \r-updated single line; piped
|
|
138
|
+
// stderr gets a full line every ~5% so MCP-client logs stay readable instead
|
|
139
|
+
// of going silent for tens of minutes.
|
|
140
|
+
function makeProgressReporter() {
|
|
141
|
+
const PIPE_STEP = 0.05;
|
|
142
|
+
let nextPipeMark = 0;
|
|
143
|
+
return {
|
|
144
|
+
onProgress: (done, total) => {
|
|
145
|
+
setIndexProgress(done, total);
|
|
146
|
+
if (total === 0)
|
|
147
|
+
return;
|
|
148
|
+
if (process.stderr.isTTY) {
|
|
149
|
+
process.stderr.write(`\rdaftari: embedding ${done}/${total} chunks`);
|
|
150
|
+
if (done === total)
|
|
151
|
+
process.stderr.write("\n");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const ratio = done / total;
|
|
155
|
+
if (ratio >= nextPipeMark || done === total) {
|
|
156
|
+
process.stderr.write(`daftari: embedding ${done}/${total} chunks\n`);
|
|
157
|
+
nextPipeMark = Math.floor(ratio / PIPE_STEP + 1) * PIPE_STEP;
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
};
|
|
96
161
|
}
|
|
97
162
|
// Auto-run only when this module is the process entry point (e.g. `tsx
|
|
98
163
|
// src/index.ts`). When imported (by cli.ts or tests) it stays inert.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type IndexStatus = "ready" | "indexing" | "error";
|
|
2
|
+
export interface IndexSnapshot {
|
|
3
|
+
status: IndexStatus;
|
|
4
|
+
done: number;
|
|
5
|
+
total: number;
|
|
6
|
+
error: string | null;
|
|
7
|
+
startedAt: string | null;
|
|
8
|
+
finishedAt: string | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function getIndexStatus(): IndexSnapshot;
|
|
11
|
+
export declare function markIndexing(): void;
|
|
12
|
+
export declare function setIndexProgress(done: number, total: number): void;
|
|
13
|
+
export declare function markIndexReady(): void;
|
|
14
|
+
export declare function markIndexError(message: string): void;
|
|
15
|
+
export declare function resetIndexState(): void;
|
|
16
|
+
export declare function indexingBusyMessage(snapshot: IndexSnapshot): string;
|
|
17
|
+
//# sourceMappingURL=index-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-state.d.ts","sourceRoot":"","sources":["../../src/search/index-state.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAeD,wBAAgB,cAAc,IAAI,aAAa,CAE9C;AAED,wBAAgB,YAAY,IAAI,IAAI,CASnC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGlE;AAED,wBAAgB,cAAc,IAAI,IAAI,CAOrC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAOpD;AAID,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAKD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAKnE"}
|