@karmaniverous/jeeves-meta 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -82,6 +82,7 @@ declare const serviceConfigSchema: z.ZodObject<{
82
82
  port: z.ZodDefault<z.ZodNumber>;
83
83
  schedule: z.ZodDefault<z.ZodString>;
84
84
  reportChannel: z.ZodOptional<z.ZodString>;
85
+ watcherHealthIntervalMs: z.ZodDefault<z.ZodNumber>;
85
86
  logging: z.ZodDefault<z.ZodObject<{
86
87
  level: z.ZodDefault<z.ZodString>;
87
88
  file: z.ZodOptional<z.ZodString>;
@@ -238,7 +239,7 @@ declare function loadServiceConfig(configPath: string): ServiceConfig;
238
239
  * Context package for a single synthesis cycle.
239
240
  *
240
241
  * The orchestrator computes this once per cycle from the meta path,
241
- * ownership tree, watcher scan results, and filesystem reads.
242
+ * ownership tree, watcher walk results, and filesystem reads.
242
243
  */
243
244
  interface MetaContext {
244
245
  /** Absolute path to the .meta directory. */
@@ -303,45 +304,11 @@ interface MetaExecutor {
303
304
  /**
304
305
  * Abstraction over the jeeves-watcher HTTP API.
305
306
  *
306
- * The orchestrator uses this for structured queries (POST /scan)
307
- * and virtual rule registration. Subprocesses use watcher_search
308
- * directly via tools.
307
+ * The service uses this for filesystem enumeration (POST /walk)
308
+ * and virtual rule registration (POST /rules/register).
309
309
  *
310
310
  * @module interfaces/WatcherClient
311
311
  */
312
- /** A file returned from a scan query. */
313
- interface ScanFile {
314
- /** Absolute file path. */
315
- file_path: string;
316
- /** Last modified time as Unix seconds. */
317
- modified_at: number;
318
- /** SHA-256 hash of file content. */
319
- content_hash: string;
320
- /** Additional payload fields requested via `fields`. */
321
- [key: string]: unknown;
322
- }
323
- /** Parameters for a scan request. */
324
- interface ScanParams {
325
- /** File path prefix to match. Required unless filter is provided. */
326
- pathPrefix?: string;
327
- /** Qdrant filter object for structural queries. */
328
- filter?: Record<string, unknown>;
329
- /** Filter files modified after this Unix timestamp (seconds). */
330
- modifiedAfter?: number;
331
- /** Which payload fields to return (default: all). */
332
- fields?: string[];
333
- /** Maximum results per page. */
334
- limit?: number;
335
- /** Pagination cursor from previous response. */
336
- cursor?: string;
337
- }
338
- /** Response from a scan request. */
339
- interface ScanResponse {
340
- /** Deduplicated file results (one per file). */
341
- files: ScanFile[];
342
- /** Pagination cursor. Absent when no more results. */
343
- next?: string;
344
- }
345
312
  /** An inference rule to register with the watcher. */
346
313
  interface InferenceRuleSpec {
347
314
  /** Rule name. */
@@ -365,11 +332,6 @@ interface InferenceRuleSpec {
365
332
  * Implementations handle retry with backoff internally.
366
333
  */
367
334
  interface WatcherClient {
368
- /**
369
- * Query indexed files by path prefix and optional filters.
370
- * Qdrant has no native prefix match; the watcher handles this internally.
371
- */
372
- scan(params: ScanParams): Promise<ScanResponse>;
373
335
  /**
374
336
  * Register virtual inference rules with the watcher.
375
337
  *
@@ -378,72 +340,33 @@ interface WatcherClient {
378
340
  */
379
341
  registerRules(source: string, rules: InferenceRuleSpec[]): Promise<void>;
380
342
  /**
381
- * Unregister virtual inference rules by source.
343
+ * Walk filesystem using glob patterns.
382
344
  *
383
- * @param source - Source identifier to unregister.
345
+ * @param globs - Array of glob patterns to match against.
346
+ * @returns Promise resolving to array of matching file paths.
384
347
  */
385
- unregisterRules(source: string): Promise<void>;
348
+ walk(globs: string[]): Promise<string[]>;
386
349
  }
387
350
 
388
351
  /**
389
- * Pino logger factory.
352
+ * Discover .meta/ directories via watcher `/walk` endpoint.
390
353
  *
391
- * @module logger
392
- */
393
-
394
- /** Minimal logger interface accepted by library functions. */
395
- interface MinimalLogger {
396
- debug: (obj: Record<string, unknown>, msg: string) => void;
397
- info: (obj: Record<string, unknown>, msg: string) => void;
398
- warn: (obj: Record<string, unknown>, msg: string) => void;
399
- error: (obj: Record<string, unknown>, msg: string) => void;
400
- }
401
- /** Logger configuration options. */
402
- interface LoggerConfig {
403
- /** Log level (default: 'info'). */
404
- level?: string;
405
- /** Optional file path to write logs to. */
406
- file?: string;
407
- }
408
- /**
409
- * Create a pino logger instance.
410
- *
411
- * @param config - Optional logger configuration.
412
- * @returns Configured pino logger.
413
- */
414
- declare function createLogger(config?: LoggerConfig): pino.Logger;
415
-
416
- /**
417
- * Discover .meta/ directories via watcher scan.
418
- *
419
- * Replaces filesystem-based globMetas() with a watcher query
420
- * that returns indexed .meta/meta.json points, filtered by domain.
354
+ * Uses filesystem enumeration through the watcher (not Qdrant) to find
355
+ * all `.meta/meta.json` files and returns deduplicated meta directory paths.
421
356
  *
422
357
  * @module discovery/discoverMetas
423
358
  */
424
359
 
425
360
  /**
426
- * Build a Qdrant filter from config metaProperty.
427
- *
428
- * Iterates all key-value pairs in `metaProperty` (a generic record)
429
- * to construct `must` clauses. Always appends `file_path: meta.json`
430
- * for deduplication.
431
- *
432
- * @param config - Meta config with metaProperty.
433
- * @returns Qdrant filter object for scanning live metas.
434
- */
435
- declare function buildMetaFilter(config: MetaConfig): Record<string, unknown>;
436
- /**
437
- * Discover all .meta/ directories via watcher scan.
361
+ * Discover all .meta/ directories via watcher walk.
438
362
  *
439
- * Queries the watcher for indexed .meta/meta.json points using the
440
- * configured domain filter. Returns deduplicated meta directory paths.
363
+ * Uses the watcher's `/walk` endpoint to find all `.meta/meta.json` files
364
+ * and returns deduplicated meta directory paths.
441
365
  *
442
- * @param config - Meta config (for domain filter).
443
- * @param watcher - WatcherClient for scan queries.
366
+ * @param watcher - WatcherClient for walk queries.
444
367
  * @returns Array of normalized .meta/ directory paths.
445
368
  */
446
- declare function discoverMetas(config: MetaConfig, watcher: WatcherClient, logger?: MinimalLogger): Promise<string[]>;
369
+ declare function discoverMetas(watcher: WatcherClient): Promise<string[]>;
447
370
 
448
371
  /**
449
372
  * Types for meta discovery and ownership tree.
@@ -543,7 +466,7 @@ interface MetaListResult {
543
466
  * @param watcher - Watcher HTTP client for discovery.
544
467
  * @returns Enriched meta list with summary statistics and ownership tree.
545
468
  */
546
- declare function listMetas(config: MetaConfig, watcher: WatcherClient, logger?: MinimalLogger): Promise<MetaListResult>;
469
+ declare function listMetas(config: MetaConfig, watcher: WatcherClient): Promise<MetaListResult>;
547
470
 
548
471
  /**
549
472
  * Build the ownership tree from discovered .meta/ paths.
@@ -578,7 +501,7 @@ declare function findNode(tree: OwnershipTree, targetPath: string): MetaNode | u
578
501
  * - Its own .meta/ subtree (outputs, not inputs)
579
502
  * - Child meta ownerPath subtrees (except their .meta/meta.json for rollups)
580
503
  *
581
- * Uses filesystem walks instead of watcher scans for performance.
504
+ * All filesystem enumeration delegated to the watcher's `/walk` endpoint.
582
505
  *
583
506
  * @module discovery/scope
584
507
  */
@@ -594,7 +517,7 @@ declare function getScopePrefix(node: MetaNode): string;
594
517
  * - The node's own .meta/ subtree (synthesis outputs are not scope inputs)
595
518
  * - Child meta ownerPath subtrees (except child .meta/meta.json for rollups)
596
519
  *
597
- * walkFiles already returns normalized forward-slash paths.
520
+ * Watcher walk returns normalized forward-slash paths.
598
521
  */
599
522
  declare function filterInScope(node: MetaNode, files: string[]): string[];
600
523
 
@@ -717,21 +640,6 @@ declare function cleanupStaleLocks(metaPaths: string[], logger?: {
717
640
  */
718
641
  declare function normalizePath(p: string): string;
719
642
 
720
- /**
721
- * Paginated scan helper for exhaustive scope enumeration.
722
- *
723
- * @module paginatedScan
724
- */
725
-
726
- /**
727
- * Perform a paginated scan that follows cursor tokens until exhausted.
728
- *
729
- * @param watcher - WatcherClient instance.
730
- * @param params - Base scan parameters (cursor is managed internally).
731
- * @returns All matching files across all pages.
732
- */
733
- declare function paginatedScan(watcher: WatcherClient, params: Omit<ScanParams, 'cursor'>, logger?: MinimalLogger): Promise<ScanFile[]>;
734
-
735
643
  /**
736
644
  * Compute a structure hash from a sorted file listing.
737
645
  *
@@ -748,32 +656,6 @@ declare function paginatedScan(watcher: WatcherClient, params: Omit<ScanParams,
748
656
  */
749
657
  declare function computeStructureHash(filePaths: string[]): string;
750
658
 
751
- /**
752
- * Recursive filesystem walker for file enumeration.
753
- *
754
- * Replaces paginated watcher scans for scope/delta/staleness checks.
755
- * Returns normalized forward-slash paths.
756
- *
757
- * @module walkFiles
758
- */
759
- /** Options for walkFiles. */
760
- interface WalkFilesOptions {
761
- /** Directory names to exclude (in addition to defaults). */
762
- exclude?: string[];
763
- /** Only include files modified after this Unix timestamp (seconds). */
764
- modifiedAfter?: number;
765
- /** Maximum recursion depth. Default: 50. */
766
- maxDepth?: number;
767
- }
768
- /**
769
- * Recursively walk a directory and return all file paths.
770
- *
771
- * @param root - Root directory to walk.
772
- * @param options - Walk options.
773
- * @returns Array of normalized file paths.
774
- */
775
- declare function walkFiles(root: string, options?: WalkFilesOptions): string[];
776
-
777
659
  /**
778
660
  * MetaExecutor implementation using the OpenClaw gateway HTTP API.
779
661
  *
@@ -816,6 +698,34 @@ declare class GatewayExecutor implements MetaExecutor {
816
698
  spawn(task: string, options?: MetaSpawnOptions): Promise<MetaSpawnResult>;
817
699
  }
818
700
 
701
+ /**
702
+ * Pino logger factory.
703
+ *
704
+ * @module logger
705
+ */
706
+
707
+ /** Minimal logger interface accepted by library functions. */
708
+ interface MinimalLogger {
709
+ debug: (obj: Record<string, unknown>, msg: string) => void;
710
+ info: (obj: Record<string, unknown>, msg: string) => void;
711
+ warn: (obj: Record<string, unknown>, msg: string) => void;
712
+ error: (obj: Record<string, unknown>, msg: string) => void;
713
+ }
714
+ /** Logger configuration options. */
715
+ interface LoggerConfig {
716
+ /** Log level (default: 'info'). */
717
+ level?: string;
718
+ /** Optional file path to write logs to. */
719
+ file?: string;
720
+ }
721
+ /**
722
+ * Create a pino logger instance.
723
+ *
724
+ * @param config - Optional logger configuration.
725
+ * @returns Configured pino logger.
726
+ */
727
+ declare function createLogger(config?: LoggerConfig): pino.Logger;
728
+
819
729
  /**
820
730
  * Build task prompts for each synthesis step.
821
731
  *
@@ -867,7 +777,7 @@ declare function buildCriticTask(ctx: MetaContext, meta: MetaJson, config: MetaC
867
777
  * @param watcher - WatcherClient for scope enumeration.
868
778
  * @returns The computed context package.
869
779
  */
870
- declare function buildContextPackage(node: MetaNode, meta: MetaJson): MetaContext;
780
+ declare function buildContextPackage(node: MetaNode, meta: MetaJson, watcher: WatcherClient): Promise<MetaContext>;
871
781
 
872
782
  /**
873
783
  * Parse subprocess outputs for each synthesis step.
@@ -1078,22 +988,27 @@ declare function computeEffectiveStaleness(candidates: Array<{
1078
988
  declare function selectCandidate(candidates: StalenessCandidate[]): StalenessCandidate | null;
1079
989
 
1080
990
  /**
1081
- * Staleness detection via watcher scan.
991
+ * Staleness detection via watcher walk.
1082
992
  *
1083
- * A meta is stale when any file in its scope was modified after _generatedAt.
993
+ * A meta is stale when any watched file in its scope was modified after
994
+ * `_generatedAt`.
1084
995
  *
1085
996
  * @module scheduling/staleness
1086
997
  */
1087
998
 
1088
999
  /**
1089
- * Check if a meta is stale by querying the watcher for modified files.
1000
+ * Check if a meta is stale.
1001
+ *
1002
+ * Uses watcher `/walk` to enumerate watched files under the scope prefix,
1003
+ * then applies a local mtime check (fast) to detect any modifications since
1004
+ * `_generatedAt`. Short-circuits on first match.
1090
1005
  *
1091
1006
  * @param scopePrefix - Path prefix for this meta's scope.
1092
1007
  * @param meta - Current meta.json content.
1093
1008
  * @param watcher - WatcherClient instance.
1094
- * @returns True if any file in scope was modified after _generatedAt.
1009
+ * @returns True if any file in scope was modified after `_generatedAt`.
1095
1010
  */
1096
- declare function isStale(scopePrefix: string, meta: MetaJson): boolean;
1011
+ declare function isStale(scopePrefix: string, meta: MetaJson, watcher: WatcherClient): Promise<boolean>;
1097
1012
  /**
1098
1013
  * Compute actual staleness in seconds (now minus _generatedAt).
1099
1014
  *
@@ -1272,7 +1187,7 @@ declare class RuleRegistrar {
1272
1187
  /**
1273
1188
  * HTTP implementation of the WatcherClient interface.
1274
1189
  *
1275
- * Talks to jeeves-watcher's POST /scan and POST /rules endpoints
1190
+ * Talks to jeeves-watcher's POST /walk and POST /rules/register endpoints
1276
1191
  * with retry and exponential backoff.
1277
1192
  *
1278
1193
  * @module watcher-client/HttpWatcherClient
@@ -1303,9 +1218,8 @@ declare class HttpWatcherClient implements WatcherClient {
1303
1218
  constructor(options: HttpWatcherClientOptions);
1304
1219
  /** POST JSON with retry. */
1305
1220
  private post;
1306
- scan(params: ScanParams): Promise<ScanResponse>;
1307
1221
  registerRules(source: string, rules: InferenceRuleSpec[]): Promise<void>;
1308
- unregisterRules(source: string): Promise<void>;
1222
+ walk(globs: string[]): Promise<string[]>;
1309
1223
  }
1310
1224
 
1311
1225
  /**
@@ -1381,6 +1295,8 @@ interface RouteDeps {
1381
1295
  watcher: HttpWatcherClient;
1382
1296
  scheduler: Scheduler | null;
1383
1297
  stats: ServiceStats;
1298
+ /** Rule registrar for reporting registration state in /status. */
1299
+ registrar?: RuleRegistrar;
1384
1300
  /** Set to true during graceful shutdown. */
1385
1301
  shuttingDown?: boolean;
1386
1302
  }
@@ -1394,16 +1310,8 @@ declare function sleep(ms: number): Promise<void>;
1394
1310
  interface ServerOptions {
1395
1311
  /** Pino logger instance. */
1396
1312
  logger: Logger;
1397
- /** Synthesis queue instance. */
1398
- queue: SynthesisQueue;
1399
- /** Validated service configuration. */
1400
- config: ServiceConfig;
1401
- /** Watcher client for data queries. */
1402
- watcher: HttpWatcherClient;
1403
- /** Scheduler instance (null during tests). */
1404
- scheduler: Scheduler | null;
1405
- /** Mutable runtime stats. */
1406
- stats: ServiceStats;
1313
+ /** Shared route dependencies (mutable — late-bound properties like registrar are set after creation). */
1314
+ deps: RouteDeps;
1407
1315
  }
1408
1316
  /**
1409
1317
  * Create and configure the Fastify server.
@@ -1431,6 +1339,8 @@ interface ShutdownDeps {
1431
1339
  queue: SynthesisQueue;
1432
1340
  logger: Logger;
1433
1341
  routeDeps?: RouteDeps;
1342
+ /** Optional cleanup callback (e.g., stop health check). */
1343
+ onShutdown?: () => void;
1434
1344
  }
1435
1345
  /**
1436
1346
  * Register shutdown handlers for SIGTERM and SIGINT.
@@ -1459,5 +1369,5 @@ declare function registerShutdownHandlers(deps: ShutdownDeps): void;
1459
1369
  */
1460
1370
  declare function startService(config: ServiceConfig, configPath?: string): Promise<void>;
1461
1371
 
1462
- export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, ProgressReporter, RuleRegistrar, SERVICE_NAME, SERVICE_VERSION, Scheduler, SynthesisQueue, acquireLock, actualStaleness, buildArchitectTask, buildBuilderTask, buildContextPackage, buildCriticTask, buildMetaFilter, buildOwnershipTree, cleanupStaleLocks, computeEffectiveStaleness, computeEma, computeStructureHash, createLogger, createServer, createSnapshot, discoverMetas, filterInScope, findNode, formatProgressEvent, getScopePrefix, hasSteerChanged, isArchitectTriggered, isLocked, isStale, listArchiveFiles, listMetas, loadServiceConfig, mergeAndWrite, metaConfigSchema, metaErrorSchema, metaJsonSchema, normalizePath, orchestrate, paginatedScan, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, selectCandidate, serviceConfigSchema, sleep, startService, toMetaError, walkFiles };
1463
- export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MergeOptions, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestrateResult, OwnershipTree, ProgressCallback, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ScanFile, ScanParams, ScanResponse, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient };
1372
+ export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, ProgressReporter, RuleRegistrar, SERVICE_NAME, SERVICE_VERSION, Scheduler, SynthesisQueue, acquireLock, actualStaleness, buildArchitectTask, buildBuilderTask, buildContextPackage, buildCriticTask, buildOwnershipTree, cleanupStaleLocks, computeEffectiveStaleness, computeEma, computeStructureHash, createLogger, createServer, createSnapshot, discoverMetas, filterInScope, findNode, formatProgressEvent, getScopePrefix, hasSteerChanged, isArchitectTriggered, isLocked, isStale, listArchiveFiles, listMetas, loadServiceConfig, mergeAndWrite, metaConfigSchema, metaErrorSchema, metaJsonSchema, normalizePath, orchestrate, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, selectCandidate, serviceConfigSchema, sleep, startService, toMetaError };
1373
+ export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MergeOptions, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestrateResult, OwnershipTree, ProgressCallback, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient };