@karmaniverous/jeeves-meta 0.15.2 → 0.15.4

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
@@ -418,6 +418,231 @@ declare const SERVICE_VERSION: string;
418
418
  /** Register all custom meta commands on the parent program. */
419
419
  declare function registerCustomCliCommands(program: Command): void;
420
420
 
421
+ /**
422
+ * Types for meta discovery and ownership tree.
423
+ *
424
+ * @module discovery/types
425
+ */
426
+ /** A discovered meta node in the ownership tree. */
427
+ interface MetaNode {
428
+ /** Absolute path to the .meta directory. */
429
+ metaPath: string;
430
+ /** Absolute path to the parent directory that this meta owns. */
431
+ ownerPath: string;
432
+ /** Depth in the ownership tree (root = 0). */
433
+ treeDepth: number;
434
+ /** Child meta nodes (subtrees with their own .meta/). */
435
+ children: MetaNode[];
436
+ /** Parent meta node, or null for roots. */
437
+ parent: MetaNode | null;
438
+ }
439
+ /** The full ownership tree discovered from watchPaths. */
440
+ interface OwnershipTree {
441
+ /** All discovered meta nodes, keyed by metaPath. */
442
+ nodes: Map<string, MetaNode>;
443
+ /** Root nodes (metas with no parent meta). */
444
+ roots: MetaNode[];
445
+ }
446
+
447
+ /**
448
+ * Unified meta listing: scan, dedup, enrich.
449
+ *
450
+ * Single source of truth for all consumers that need a list of metas
451
+ * with enriched metadata. Replaces duplicated scan+dedup logic in
452
+ * plugin tools, CLI, and prompt injection.
453
+ *
454
+ * @module discovery/listMetas
455
+ */
456
+
457
+ /** Enriched meta entry returned by listMetas(). */
458
+ interface MetaEntry {
459
+ /** Normalized .meta/ directory path. */
460
+ path: string;
461
+ /** Tree depth (0 = leaf, higher = more abstract). */
462
+ depth: number;
463
+ /** Scheduling emphasis multiplier. */
464
+ emphasis: number;
465
+ /** Seconds since last synthesis, or Infinity if never synthesized. */
466
+ stalenessSeconds: number;
467
+ /** ISO timestamp of last synthesis, or null. */
468
+ lastSynthesized: string | null;
469
+ /** Whether the last synthesis had an error. */
470
+ hasError: boolean;
471
+ /** Whether this meta is currently locked. */
472
+ locked: boolean;
473
+ /** Whether this meta is disabled (skipped during staleness scheduling). */
474
+ disabled: boolean;
475
+ /** Cumulative architect tokens, or null if never run. */
476
+ architectTokens: number | null;
477
+ /** Cumulative builder tokens, or null if never run. */
478
+ builderTokens: number | null;
479
+ /** Cumulative critic tokens, or null if never run. */
480
+ criticTokens: number | null;
481
+ /** Number of direct children in the ownership tree. */
482
+ children: number;
483
+ /** The underlying MetaNode from the ownership tree. */
484
+ node: MetaNode;
485
+ /** The parsed meta.json content. */
486
+ meta: MetaJson;
487
+ }
488
+ /** Summary statistics computed from the meta list. */
489
+ interface MetaListSummary {
490
+ total: number;
491
+ stale: number;
492
+ errors: number;
493
+ locked: number;
494
+ disabled: number;
495
+ neverSynthesized: number;
496
+ tokens: {
497
+ architect: number;
498
+ builder: number;
499
+ critic: number;
500
+ };
501
+ stalestPath: string | null;
502
+ lastSynthesizedPath: string | null;
503
+ lastSynthesizedAt: string | null;
504
+ }
505
+ /** Full result from listMetas(). */
506
+ interface MetaListResult {
507
+ summary: MetaListSummary;
508
+ entries: MetaEntry[];
509
+ tree: OwnershipTree;
510
+ }
511
+ /**
512
+ * Discover, deduplicate, and enrich all metas.
513
+ *
514
+ * This is the single consolidated function that replaces all duplicated
515
+ * scan+dedup+enrich logic across the codebase. All enrichment comes from
516
+ * reading meta.json on disk (the canonical source).
517
+ *
518
+ * @param config - Validated synthesis config.
519
+ * @param watcher - Watcher HTTP client for discovery.
520
+ * @returns Enriched meta list with summary statistics and ownership tree.
521
+ */
522
+ declare function listMetas(config: MetaConfig, watcher: WatcherClient): Promise<MetaListResult>;
523
+
524
+ /**
525
+ * Discover .meta/ directories via watcher `/walk` endpoint.
526
+ *
527
+ * Uses filesystem enumeration through the watcher (not Qdrant) to find
528
+ * all `.meta/meta.json` files and returns deduplicated meta directory paths.
529
+ *
530
+ * @module discovery/discoverMetas
531
+ */
532
+
533
+ /**
534
+ * Discover all .meta/ directories via watcher walk.
535
+ *
536
+ * Uses the watcher's `/walk` endpoint to find all `.meta/meta.json` files
537
+ * and returns deduplicated meta directory paths.
538
+ *
539
+ * @param watcher - WatcherClient for walk queries.
540
+ * @returns Array of normalized .meta/ directory paths.
541
+ */
542
+ declare function discoverMetas(watcher: WatcherClient): Promise<string[]>;
543
+
544
+ /**
545
+ * Build the ownership tree from discovered .meta/ paths.
546
+ *
547
+ * Each .meta/ directory owns its parent directory and all descendants,
548
+ * except subtrees that contain their own .meta/. For those subtrees,
549
+ * the parent meta consumes the child meta's synthesis output.
550
+ *
551
+ * @module discovery/ownershipTree
552
+ */
553
+
554
+ /**
555
+ * Build an ownership tree from an array of .meta/ directory paths.
556
+ *
557
+ * @param metaPaths - Absolute paths to .meta/ directories.
558
+ * @returns The ownership tree with parent/child relationships.
559
+ */
560
+ declare function buildOwnershipTree(metaPaths: string[]): OwnershipTree;
561
+ /**
562
+ * Find a node in the ownership tree by meta path or owner path.
563
+ *
564
+ * @param tree - The ownership tree to search.
565
+ * @param targetPath - Path to search for (meta path or owner path).
566
+ * @returns The matching node, or undefined if not found.
567
+ */
568
+ declare function findNode(tree: OwnershipTree, targetPath: string): MetaNode | undefined;
569
+
570
+ /**
571
+ * Pino logger factory.
572
+ *
573
+ * @module logger
574
+ */
575
+
576
+ /** Minimal logger interface accepted by library functions. */
577
+ interface MinimalLogger {
578
+ debug: (obj: Record<string, unknown>, msg: string) => void;
579
+ info: (obj: Record<string, unknown>, msg: string) => void;
580
+ warn: (obj: Record<string, unknown>, msg: string) => void;
581
+ error: (obj: Record<string, unknown>, msg: string) => void;
582
+ }
583
+ /** Logger configuration options. */
584
+ interface LoggerConfig {
585
+ /** Log level (default: 'info'). */
586
+ level?: string;
587
+ /** Optional file path to write logs to. */
588
+ file?: string;
589
+ }
590
+ /**
591
+ * Create a pino logger instance.
592
+ *
593
+ * @param config - Optional logger configuration.
594
+ * @returns Configured pino logger.
595
+ */
596
+ declare function createLogger(config?: LoggerConfig): pino.Logger;
597
+
598
+ /**
599
+ * Compute the file scope owned by a meta node.
600
+ *
601
+ * A meta owns: parent dir + all descendants, minus:
602
+ * - Its own .meta/ subtree (outputs, not inputs)
603
+ * - Child meta ownerPath subtrees (except their .meta/meta.json for rollups)
604
+ *
605
+ * All filesystem enumeration delegated to the watcher's `/walk` endpoint.
606
+ *
607
+ * @module discovery/scope
608
+ */
609
+
610
+ /**
611
+ * Get the scope path prefix for a meta node.
612
+ */
613
+ declare function getScopePrefix(node: MetaNode): string;
614
+ /**
615
+ * Filter a list of file paths to only those in scope for a meta node.
616
+ *
617
+ * Excludes:
618
+ * - The node's own .meta/ subtree (synthesis outputs are not scope inputs)
619
+ * - Child meta ownerPath subtrees (except child .meta/meta.json for rollups)
620
+ *
621
+ * Watcher walk returns normalized forward-slash paths.
622
+ */
623
+ declare function filterInScope(node: MetaNode, files: string[]): string[];
624
+
625
+ /**
626
+ * In-memory cache for listMetas results with TTL and concurrent refresh guard.
627
+ *
628
+ * @module cache
629
+ */
630
+
631
+ /**
632
+ * Caches listMetas results to avoid expensive repeated filesystem walks.
633
+ * Supports concurrent refresh coalescing and manual invalidation.
634
+ */
635
+ declare class MetaCache {
636
+ private result;
637
+ private updatedAt;
638
+ private refreshPromise;
639
+ /** Get cached result or refresh if stale. */
640
+ get(config: ServiceConfig, watcher: WatcherClient): Promise<MetaListResult>;
641
+ /** Force-expire the cache so next get() triggers a refresh. */
642
+ invalidate(): void;
643
+ private refresh;
644
+ }
645
+
421
646
  /**
422
647
  * Hybrid 3-layer synthesis queue.
423
648
  *
@@ -648,9 +873,10 @@ declare class Scheduler {
648
873
  private readonly queue;
649
874
  private readonly logger;
650
875
  private readonly watcher;
876
+ private readonly cache;
651
877
  private registrar;
652
878
  private currentExpression;
653
- constructor(config: ServiceConfig, queue: SynthesisQueue, logger: Logger, watcher: HttpWatcherClient);
879
+ constructor(config: ServiceConfig, queue: SynthesisQueue, logger: Logger, watcher: HttpWatcherClient, cache: MetaCache);
654
880
  /** Set the rule registrar for watcher restart detection. */
655
881
  setRegistrar(registrar: RuleRegistrar): void;
656
882
  /** Start the cron job. */
@@ -682,277 +908,73 @@ declare class Scheduler {
682
908
  }
683
909
 
684
910
  /**
685
- * Shared live config hot-reload support.
686
- *
687
- * Used by both file-watch reloads in bootstrap and POST /config/apply
688
- * via the component descriptor's onConfigApply callback.
689
- *
690
- * @module configHotReload
691
- */
692
-
693
- /**
694
- * Fields that require a service restart to take effect.
695
- *
696
- * Shared between the descriptor's `onConfigApply` and the file-watcher
697
- * hot-reload in `bootstrap.ts`.
698
- */
699
- declare const RESTART_REQUIRED_FIELDS: readonly ["port", "watcherUrl", "gatewayUrl", "gatewayApiKey", "defaultArchitect", "defaultCritic"];
700
-
701
- /**
702
- * Load and resolve jeeves-meta service config.
703
- *
704
- * Supports \@file: indirection and environment-variable substitution (dollar-brace pattern).
705
- *
706
- * @module configLoader
707
- */
708
-
709
- /**
710
- * Migrate legacy config path to the new canonical location.
711
- *
712
- * If the old path `{configRoot}/jeeves-meta.config.json` exists and the new
713
- * path `{configRoot}/jeeves-meta/config.json` does NOT exist, copies the file
714
- * to the new location and logs a warning.
715
- *
716
- * @param configRoot - Root directory for configuration files.
717
- * @param warn - Optional callback for logging the migration warning.
718
- */
719
- declare function migrateConfigPath(configRoot: string, warn?: (msg: string) => void): void;
720
- /**
721
- * Resolve config path from --config flag or JEEVES_META_CONFIG env var.
722
- *
723
- * @param args - CLI arguments (process.argv.slice(2)).
724
- * @returns Resolved config path.
725
- * @throws If no config path found.
726
- */
727
- declare function resolveConfigPath(args: string[]): string;
728
- /**
729
- * Load service config from a JSON file.
730
- *
731
- * Resolves \@file: references for defaultArchitect and defaultCritic,
732
- * and substitutes environment-variable placeholders throughout.
733
- *
734
- * @param configPath - Path to config JSON file.
735
- * @returns Validated ServiceConfig.
736
- */
737
- declare function loadServiceConfig(configPath: string): ServiceConfig;
738
-
739
- /**
740
- * Jeeves component descriptor for jeeves-meta.
741
- *
742
- * Single source of truth consumed by the service CLI, plugin writer, and
743
- * config-apply pipeline.
744
- *
745
- * @module descriptor
746
- */
747
-
748
- /**
749
- * Parsed jeeves-meta component descriptor.
750
- */
751
- declare const metaDescriptor: JeevesComponentDescriptor;
752
-
753
- /**
754
- * Types for meta discovery and ownership tree.
755
- *
756
- * @module discovery/types
757
- */
758
- /** A discovered meta node in the ownership tree. */
759
- interface MetaNode {
760
- /** Absolute path to the .meta directory. */
761
- metaPath: string;
762
- /** Absolute path to the parent directory that this meta owns. */
763
- ownerPath: string;
764
- /** Depth in the ownership tree (root = 0). */
765
- treeDepth: number;
766
- /** Child meta nodes (subtrees with their own .meta/). */
767
- children: MetaNode[];
768
- /** Parent meta node, or null for roots. */
769
- parent: MetaNode | null;
770
- }
771
- /** The full ownership tree discovered from watchPaths. */
772
- interface OwnershipTree {
773
- /** All discovered meta nodes, keyed by metaPath. */
774
- nodes: Map<string, MetaNode>;
775
- /** Root nodes (metas with no parent meta). */
776
- roots: MetaNode[];
777
- }
778
-
779
- /**
780
- * Unified meta listing: scan, dedup, enrich.
781
- *
782
- * Single source of truth for all consumers that need a list of metas
783
- * with enriched metadata. Replaces duplicated scan+dedup logic in
784
- * plugin tools, CLI, and prompt injection.
785
- *
786
- * @module discovery/listMetas
787
- */
788
-
789
- /** Enriched meta entry returned by listMetas(). */
790
- interface MetaEntry {
791
- /** Normalized .meta/ directory path. */
792
- path: string;
793
- /** Tree depth (0 = leaf, higher = more abstract). */
794
- depth: number;
795
- /** Scheduling emphasis multiplier. */
796
- emphasis: number;
797
- /** Seconds since last synthesis, or Infinity if never synthesized. */
798
- stalenessSeconds: number;
799
- /** ISO timestamp of last synthesis, or null. */
800
- lastSynthesized: string | null;
801
- /** Whether the last synthesis had an error. */
802
- hasError: boolean;
803
- /** Whether this meta is currently locked. */
804
- locked: boolean;
805
- /** Whether this meta is disabled (skipped during staleness scheduling). */
806
- disabled: boolean;
807
- /** Cumulative architect tokens, or null if never run. */
808
- architectTokens: number | null;
809
- /** Cumulative builder tokens, or null if never run. */
810
- builderTokens: number | null;
811
- /** Cumulative critic tokens, or null if never run. */
812
- criticTokens: number | null;
813
- /** Number of direct children in the ownership tree. */
814
- children: number;
815
- /** The underlying MetaNode from the ownership tree. */
816
- node: MetaNode;
817
- /** The parsed meta.json content. */
818
- meta: MetaJson;
819
- }
820
- /** Summary statistics computed from the meta list. */
821
- interface MetaListSummary {
822
- total: number;
823
- stale: number;
824
- errors: number;
825
- locked: number;
826
- disabled: number;
827
- neverSynthesized: number;
828
- tokens: {
829
- architect: number;
830
- builder: number;
831
- critic: number;
832
- };
833
- stalestPath: string | null;
834
- lastSynthesizedPath: string | null;
835
- lastSynthesizedAt: string | null;
836
- }
837
- /** Full result from listMetas(). */
838
- interface MetaListResult {
839
- summary: MetaListSummary;
840
- entries: MetaEntry[];
841
- tree: OwnershipTree;
842
- }
843
- /**
844
- * Discover, deduplicate, and enrich all metas.
845
- *
846
- * This is the single consolidated function that replaces all duplicated
847
- * scan+dedup+enrich logic across the codebase. All enrichment comes from
848
- * reading meta.json on disk (the canonical source).
849
- *
850
- * @param config - Validated synthesis config.
851
- * @param watcher - Watcher HTTP client for discovery.
852
- * @returns Enriched meta list with summary statistics and ownership tree.
853
- */
854
- declare function listMetas(config: MetaConfig, watcher: WatcherClient): Promise<MetaListResult>;
855
-
856
- /**
857
- * Discover .meta/ directories via watcher `/walk` endpoint.
858
- *
859
- * Uses filesystem enumeration through the watcher (not Qdrant) to find
860
- * all `.meta/meta.json` files and returns deduplicated meta directory paths.
861
- *
862
- * @module discovery/discoverMetas
863
- */
864
-
865
- /**
866
- * Discover all .meta/ directories via watcher walk.
867
- *
868
- * Uses the watcher's `/walk` endpoint to find all `.meta/meta.json` files
869
- * and returns deduplicated meta directory paths.
870
- *
871
- * @param watcher - WatcherClient for walk queries.
872
- * @returns Array of normalized .meta/ directory paths.
873
- */
874
- declare function discoverMetas(watcher: WatcherClient): Promise<string[]>;
875
-
876
- /**
877
- * Build the ownership tree from discovered .meta/ paths.
878
- *
879
- * Each .meta/ directory owns its parent directory and all descendants,
880
- * except subtrees that contain their own .meta/. For those subtrees,
881
- * the parent meta consumes the child meta's synthesis output.
882
- *
883
- * @module discovery/ownershipTree
884
- */
885
-
886
- /**
887
- * Build an ownership tree from an array of .meta/ directory paths.
911
+ * Shared live config hot-reload support.
888
912
  *
889
- * @param metaPaths - Absolute paths to .meta/ directories.
890
- * @returns The ownership tree with parent/child relationships.
891
- */
892
- declare function buildOwnershipTree(metaPaths: string[]): OwnershipTree;
893
- /**
894
- * Find a node in the ownership tree by meta path or owner path.
913
+ * Used by both file-watch reloads in bootstrap and POST /config/apply
914
+ * via the component descriptor's onConfigApply callback.
895
915
  *
896
- * @param tree - The ownership tree to search.
897
- * @param targetPath - Path to search for (meta path or owner path).
898
- * @returns The matching node, or undefined if not found.
916
+ * @module configHotReload
899
917
  */
900
- declare function findNode(tree: OwnershipTree, targetPath: string): MetaNode | undefined;
901
918
 
902
919
  /**
903
- * Pino logger factory.
920
+ * Fields that require a service restart to take effect.
904
921
  *
905
- * @module logger
922
+ * Shared between the descriptor's `onConfigApply` and the file-watcher
923
+ * hot-reload in `bootstrap.ts`.
906
924
  */
925
+ declare const RESTART_REQUIRED_FIELDS: readonly ["port", "watcherUrl", "gatewayUrl", "gatewayApiKey", "defaultArchitect", "defaultCritic"];
907
926
 
908
- /** Minimal logger interface accepted by library functions. */
909
- interface MinimalLogger {
910
- debug: (obj: Record<string, unknown>, msg: string) => void;
911
- info: (obj: Record<string, unknown>, msg: string) => void;
912
- warn: (obj: Record<string, unknown>, msg: string) => void;
913
- error: (obj: Record<string, unknown>, msg: string) => void;
914
- }
915
- /** Logger configuration options. */
916
- interface LoggerConfig {
917
- /** Log level (default: 'info'). */
918
- level?: string;
919
- /** Optional file path to write logs to. */
920
- file?: string;
921
- }
922
927
  /**
923
- * Create a pino logger instance.
928
+ * Load and resolve jeeves-meta service config.
924
929
  *
925
- * @param config - Optional logger configuration.
926
- * @returns Configured pino logger.
930
+ * Supports \@file: indirection and environment-variable substitution (dollar-brace pattern).
931
+ *
932
+ * @module configLoader
927
933
  */
928
- declare function createLogger(config?: LoggerConfig): pino.Logger;
929
934
 
930
935
  /**
931
- * Compute the file scope owned by a meta node.
936
+ * Migrate legacy config path to the new canonical location.
932
937
  *
933
- * A meta owns: parent dir + all descendants, minus:
934
- * - Its own .meta/ subtree (outputs, not inputs)
935
- * - Child meta ownerPath subtrees (except their .meta/meta.json for rollups)
938
+ * If the old path `{configRoot}/jeeves-meta.config.json` exists and the new
939
+ * path `{configRoot}/jeeves-meta/config.json` does NOT exist, copies the file
940
+ * to the new location and logs a warning.
936
941
  *
937
- * All filesystem enumeration delegated to the watcher's `/walk` endpoint.
942
+ * @param configRoot - Root directory for configuration files.
943
+ * @param warn - Optional callback for logging the migration warning.
944
+ */
945
+ declare function migrateConfigPath(configRoot: string, warn?: (msg: string) => void): void;
946
+ /**
947
+ * Resolve config path from --config flag or JEEVES_META_CONFIG env var.
938
948
  *
939
- * @module discovery/scope
949
+ * @param args - CLI arguments (process.argv.slice(2)).
950
+ * @returns Resolved config path.
951
+ * @throws If no config path found.
940
952
  */
941
-
953
+ declare function resolveConfigPath(args: string[]): string;
942
954
  /**
943
- * Get the scope path prefix for a meta node.
955
+ * Load service config from a JSON file.
956
+ *
957
+ * Resolves \@file: references for defaultArchitect and defaultCritic,
958
+ * and substitutes environment-variable placeholders throughout.
959
+ *
960
+ * @param configPath - Path to config JSON file.
961
+ * @returns Validated ServiceConfig.
944
962
  */
945
- declare function getScopePrefix(node: MetaNode): string;
963
+ declare function loadServiceConfig(configPath: string): ServiceConfig;
964
+
946
965
  /**
947
- * Filter a list of file paths to only those in scope for a meta node.
966
+ * Jeeves component descriptor for jeeves-meta.
948
967
  *
949
- * Excludes:
950
- * - The node's own .meta/ subtree (synthesis outputs are not scope inputs)
951
- * - Child meta ownerPath subtrees (except child .meta/meta.json for rollups)
968
+ * Single source of truth consumed by the service CLI, plugin writer, and
969
+ * config-apply pipeline.
952
970
  *
953
- * Watcher walk returns normalized forward-slash paths.
971
+ * @module descriptor
954
972
  */
955
- declare function filterInScope(node: MetaNode, files: string[]): string[];
973
+
974
+ /**
975
+ * Parsed jeeves-meta component descriptor.
976
+ */
977
+ declare const metaDescriptor: JeevesComponentDescriptor;
956
978
 
957
979
  /**
958
980
  * Exponential moving average helper for token tracking.
@@ -1129,8 +1151,8 @@ declare class GatewayExecutor implements MetaExecutor {
1129
1151
  private cleanupOutputFile;
1130
1152
  /** Invoke a gateway tool via the /tools/invoke HTTP endpoint. */
1131
1153
  private invoke;
1132
- /** Look up totalTokens for a session via sessions_list. */
1133
- private getSessionTokens;
1154
+ /** Look up session metadata (tokens, completion status) via sessions_list. */
1155
+ private getSessionInfo;
1134
1156
  /** Whether this executor has been aborted by the operator. */
1135
1157
  get aborted(): boolean;
1136
1158
  /** Abort the currently running spawn, if any. */
@@ -1195,107 +1217,6 @@ declare function buildCriticTask(ctx: MetaContext, meta: MetaJson, config: MetaC
1195
1217
  */
1196
1218
  declare function buildContextPackage(node: MetaNode, meta: MetaJson, watcher: WatcherClient, logger?: MinimalLogger): Promise<MetaContext>;
1197
1219
 
1198
- /**
1199
- * Parse subprocess outputs for each synthesis step.
1200
- *
1201
- * - Architect: returns text \> _builder
1202
- * - Builder: returns JSON \> _content + structured fields
1203
- * - Critic: returns text \> _feedback
1204
- *
1205
- * @module orchestrator/parseOutput
1206
- */
1207
- /** Parsed builder output. */
1208
- interface BuilderOutput {
1209
- /** Narrative synthesis content. */
1210
- content: string;
1211
- /** Additional structured fields (non-underscore keys). */
1212
- fields: Record<string, unknown>;
1213
- /** Opaque state for progressive synthesis, if provided by the builder. */
1214
- state?: unknown;
1215
- }
1216
- /**
1217
- * Parse architect output. The architect returns a task brief as text.
1218
- *
1219
- * @param output - Raw subprocess output.
1220
- * @returns The task brief string.
1221
- */
1222
- declare function parseArchitectOutput(output: string): string;
1223
- /**
1224
- * Parse builder output. The builder returns JSON with _content and optional fields.
1225
- *
1226
- * Attempts JSON parse first. If that fails, treats the entire output as _content.
1227
- *
1228
- * @param output - Raw subprocess output.
1229
- * @returns Parsed builder output with content and structured fields.
1230
- */
1231
- declare function parseBuilderOutput(output: string): BuilderOutput;
1232
- /**
1233
- * Parse critic output. The critic returns evaluation text.
1234
- *
1235
- * @param output - Raw subprocess output.
1236
- * @returns The feedback string.
1237
- */
1238
- declare function parseCriticOutput(output: string): string;
1239
-
1240
- /**
1241
- * Merge synthesis results into meta.json.
1242
- *
1243
- * Preserves human-set fields (_id, _steer, _depth).
1244
- * Writes engine fields (_generatedAt, _structureHash, etc.).
1245
- * Validates against schema before writing.
1246
- *
1247
- * @module orchestrator/merge
1248
- */
1249
-
1250
- /** Options for merging synthesis results. */
1251
- interface MergeOptions {
1252
- /** Path to .meta directory. */
1253
- metaPath: string;
1254
- /** Current meta.json content. */
1255
- current: MetaJson;
1256
- /** Architect prompt used (or existing). */
1257
- architect: string;
1258
- /** Builder task brief (new or cached). */
1259
- builder: string;
1260
- /** Critic prompt used (or existing). */
1261
- critic: string;
1262
- /** Builder output (content + structured fields), or null if builder failed. */
1263
- builderOutput: BuilderOutput | null;
1264
- /** Critic feedback, or null if critic failed. */
1265
- feedback: string | null;
1266
- /** New structure hash. */
1267
- structureHash: string;
1268
- /** New synthesis count. */
1269
- synthesisCount: number;
1270
- /** Error from any step, or null on full success. */
1271
- error: MetaError | null;
1272
- /** Token count from architect step. */
1273
- architectTokens?: number;
1274
- /** Token count from builder step. */
1275
- builderTokens?: number;
1276
- /** Token count from critic step. */
1277
- criticTokens?: number;
1278
- /** Override output path (default: metaPath/meta.json). Used for lock staging. */
1279
- outputPath?: string;
1280
- /** Opaque state from builder output for progressive synthesis. */
1281
- state?: unknown;
1282
- /**
1283
- * When true, preserve _content and _generatedAt from current meta.
1284
- * Used for timeout recovery where state advanced but content did not.
1285
- */
1286
- stateOnly?: boolean;
1287
- /** Phase state record to persist. */
1288
- phaseState?: PhaseState;
1289
- }
1290
- /**
1291
- * Merge results into meta.json and write atomically.
1292
- *
1293
- * @param options - Merge options.
1294
- * @returns The updated MetaJson.
1295
- * @throws If validation fails (malformed output).
1296
- */
1297
- declare function mergeAndWrite(options: MergeOptions): Promise<MetaJson>;
1298
-
1299
1220
  /**
1300
1221
  * Progress reporting via OpenClaw gateway `/tools/invoke` → `message` tool.
1301
1222
  *
@@ -1335,37 +1256,6 @@ declare class ProgressReporter {
1335
1256
  report(event: ProgressEvent): Promise<void>;
1336
1257
  }
1337
1258
 
1338
- /**
1339
- * Main orchestration entry point — discovery, scheduling, candidate selection.
1340
- *
1341
- * @module orchestrator/orchestrate
1342
- */
1343
-
1344
- /** Callback for synthesis progress events. */
1345
- type ProgressCallback$1 = (event: ProgressEvent) => void | Promise<void>;
1346
- /** Result of a single orchestration cycle. */
1347
- interface OrchestrateResult {
1348
- /** Whether a synthesis was performed. */
1349
- synthesized: boolean;
1350
- /** Path to the meta that was synthesized, if any. */
1351
- metaPath?: string;
1352
- /** Error if synthesis failed. */
1353
- error?: MetaError;
1354
- }
1355
- /**
1356
- * Run a single synthesis cycle.
1357
- *
1358
- * Selects the stalest candidate (or a specific target) and runs the
1359
- * full architect/builder/critic pipeline.
1360
- *
1361
- * @param config - Validated synthesis config.
1362
- * @param executor - Pluggable LLM executor.
1363
- * @param watcher - Watcher HTTP client.
1364
- * @param targetPath - Optional: specific meta/owner path to synthesize instead of stalest candidate.
1365
- * @returns Array with a single result.
1366
- */
1367
- declare function orchestrate(config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, targetPath?: string, onProgress?: ProgressCallback$1, logger?: MinimalLogger): Promise<OrchestrateResult[]>;
1368
-
1369
1259
  /**
1370
1260
  * Per-phase executors for the phase-state machine.
1371
1261
  *
@@ -1430,58 +1320,46 @@ interface OrchestratePhaseResult {
1430
1320
  declare function orchestratePhase(config: MetaConfig, executor: MetaExecutor, watcher: WatcherClient, targetPath?: string, onProgress?: PhaseProgressCallback, logger?: MinimalLogger): Promise<OrchestratePhaseResult>;
1431
1321
 
1432
1322
  /**
1433
- * Weighted staleness formula for candidate selection.
1323
+ * Parse subprocess outputs for each synthesis step.
1434
1324
  *
1435
- * effectiveStaleness = actualStaleness * (normalizedDepth + 1) ^ (depthWeight * emphasis)
1325
+ * - Architect: returns text \> _builder
1326
+ * - Builder: returns JSON \> _content + structured fields
1327
+ * - Critic: returns text \> _feedback
1436
1328
  *
1437
- * @module scheduling/weightedFormula
1329
+ * @module orchestrator/parseOutput
1438
1330
  */
1439
-
1440
- /** A candidate meta with computed staleness. */
1441
- interface StalenessCandidate {
1442
- /** The meta node. */
1443
- node: MetaNode;
1444
- /** Current meta.json content. */
1445
- meta: MetaJson;
1446
- /** Actual staleness in seconds. */
1447
- actualStaleness: number;
1448
- /** Effective staleness after depth weighting. */
1449
- effectiveStaleness: number;
1331
+ /** Parsed builder output. */
1332
+ interface BuilderOutput {
1333
+ /** Narrative synthesis content. */
1334
+ content: string;
1335
+ /** Additional structured fields (non-underscore keys). */
1336
+ fields: Record<string, unknown>;
1337
+ /** Opaque state for progressive synthesis, if provided by the builder. */
1338
+ state?: unknown;
1450
1339
  }
1451
1340
  /**
1452
- * Compute effective staleness for a set of candidates.
1453
- *
1454
- * Normalizes depths so the minimum becomes 0, then applies the formula:
1455
- * effectiveStaleness = actualStaleness * (normalizedDepth + 1) ^ (depthWeight * emphasis)
1456
- *
1457
- * Per-meta _emphasis (default 1) multiplies depthWeight, allowing individual
1458
- * metas to tune how much their tree position affects scheduling.
1341
+ * Parse architect output. The architect returns a task brief as text.
1459
1342
  *
1460
- * @param candidates - Array of \{ node, meta, actualStaleness \}.
1461
- * @param depthWeight - Exponent for depth weighting (0 = pure staleness).
1462
- * @returns Same array with effectiveStaleness computed.
1343
+ * @param output - Raw subprocess output.
1344
+ * @returns The task brief string.
1463
1345
  */
1464
- declare function computeEffectiveStaleness(candidates: Array<{
1465
- node: MetaNode;
1466
- meta: MetaJson;
1467
- actualStaleness: number;
1468
- }>, depthWeight: number): StalenessCandidate[];
1469
-
1346
+ declare function parseArchitectOutput(output: string): string;
1470
1347
  /**
1471
- * Select the best synthesis candidate from stale metas.
1348
+ * Parse builder output. The builder returns JSON with _content and optional fields.
1472
1349
  *
1473
- * Picks the meta with highest effective staleness.
1350
+ * Attempts JSON parse first. If that fails, treats the entire output as _content.
1474
1351
  *
1475
- * @module scheduling/selectCandidate
1352
+ * @param output - Raw subprocess output.
1353
+ * @returns Parsed builder output with content and structured fields.
1476
1354
  */
1477
-
1355
+ declare function parseBuilderOutput(output: string): BuilderOutput;
1478
1356
  /**
1479
- * Select the candidate with the highest effective staleness.
1357
+ * Parse critic output. The critic returns evaluation text.
1480
1358
  *
1481
- * @param candidates - Array of candidates with computed effective staleness.
1482
- * @returns The winning candidate, or null if no candidates.
1359
+ * @param output - Raw subprocess output.
1360
+ * @returns The feedback string.
1483
1361
  */
1484
- declare function selectCandidate(candidates: StalenessCandidate[]): StalenessCandidate | null;
1362
+ declare function parseCriticOutput(output: string): string;
1485
1363
 
1486
1364
  /**
1487
1365
  * Staleness detection via watcher walk.
@@ -1538,6 +1416,44 @@ declare function isArchitectTriggered(meta: MetaJson, structureChanged: boolean,
1538
1416
  */
1539
1417
  declare function hasSteerChanged(currentSteer: string | undefined, archiveSteer: string | undefined, hasArchive: boolean): boolean;
1540
1418
 
1419
+ /**
1420
+ * Weighted staleness formula for candidate selection.
1421
+ *
1422
+ * effectiveStaleness = actualStaleness * (normalizedDepth + 1) ^ (depthWeight * emphasis)
1423
+ *
1424
+ * @module scheduling/weightedFormula
1425
+ */
1426
+
1427
+ /** A candidate meta with computed staleness. */
1428
+ interface StalenessCandidate {
1429
+ /** The meta node. */
1430
+ node: MetaNode;
1431
+ /** Current meta.json content. */
1432
+ meta: MetaJson;
1433
+ /** Actual staleness in seconds. */
1434
+ actualStaleness: number;
1435
+ /** Effective staleness after depth weighting. */
1436
+ effectiveStaleness: number;
1437
+ }
1438
+ /**
1439
+ * Compute effective staleness for a set of candidates.
1440
+ *
1441
+ * Normalizes depths so the minimum becomes 0, then applies the formula:
1442
+ * effectiveStaleness = actualStaleness * (normalizedDepth + 1) ^ (depthWeight * emphasis)
1443
+ *
1444
+ * Per-meta _emphasis (default 1) multiplies depthWeight, allowing individual
1445
+ * metas to tune how much their tree position affects scheduling.
1446
+ *
1447
+ * @param candidates - Array of \{ node, meta, actualStaleness \}.
1448
+ * @param depthWeight - Exponent for depth weighting (0 = pure staleness).
1449
+ * @returns Same array with effectiveStaleness computed.
1450
+ */
1451
+ declare function computeEffectiveStaleness(candidates: Array<{
1452
+ node: MetaNode;
1453
+ meta: MetaJson;
1454
+ actualStaleness: number;
1455
+ }>, depthWeight: number): StalenessCandidate[];
1456
+
1541
1457
  /**
1542
1458
  * Route registration for jeeves-meta service.
1543
1459
  *
@@ -1560,6 +1476,10 @@ interface RouteDeps {
1560
1476
  watcher: WatcherClient;
1561
1477
  scheduler: Scheduler | null;
1562
1478
  stats: ServiceStats;
1479
+ /** Cached listMetas results with TTL. */
1480
+ cache: MetaCache;
1481
+ /** Service readiness flag — false during startup. */
1482
+ ready: boolean;
1563
1483
  /** Rule registrar for reporting registration state in /status. */
1564
1484
  registrar?: RuleRegistrar;
1565
1485
  /** Executor instance for abort support. */
@@ -1657,5 +1577,5 @@ declare function registerShutdownHandlers(deps: ShutdownDeps): void;
1657
1577
  */
1658
1578
  declare function startService(config: ServiceConfig, configPath?: string): Promise<void>;
1659
1579
 
1660
- export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, MAX_STALENESS_SECONDS, ProgressReporter, RESTART_REQUIRED_FIELDS, 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, metaDescriptor, metaErrorSchema, metaJsonSchema, migrateConfigPath, normalizePath, orchestrate, orchestratePhase, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerCustomCliCommands, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, runArchitect, runBuilder, runCritic, selectCandidate, serviceConfigSchema, startService, toMetaError, verifyRuleApplication };
1661
- export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MergeOptions, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestratePhaseResult, OrchestrateResult, OwnershipTree, PhaseProgressCallback, PhaseResult, ProgressCallback$1 as ProgressCallback, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient, WatcherScanPoint, WatcherScanRequest, WatcherScanResult };
1580
+ export { DEFAULT_PORT, DEFAULT_PORT_STR, GatewayExecutor, HttpWatcherClient, MAX_STALENESS_SECONDS, ProgressReporter, RESTART_REQUIRED_FIELDS, 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, metaConfigSchema, metaDescriptor, metaErrorSchema, metaJsonSchema, migrateConfigPath, normalizePath, orchestratePhase, parseArchitectOutput, parseBuilderOutput, parseCriticOutput, pruneArchive, readLatestArchive, readLockState, registerCustomCliCommands, registerRoutes, registerShutdownHandlers, releaseLock, resolveConfigPath, resolveMetaDir, runArchitect, runBuilder, runCritic, serviceConfigSchema, startService, toMetaError, verifyRuleApplication };
1581
+ export type { BuilderOutput, EnqueueResult, GatewayExecutorOptions, HttpWatcherClientOptions, InferenceRuleSpec, LockState, LoggerConfig, MetaConfig, MetaContext, MetaEntry, MetaError, MetaExecutor, MetaJson, MetaListResult, MetaListSummary, MetaNode, MetaSpawnOptions, MetaSpawnResult, MinimalLogger, OrchestratePhaseResult, OwnershipTree, PhaseProgressCallback, PhaseResult, ProgressEvent, ProgressPhase, ProgressReporterConfig, QueueItem, QueueState, RouteDeps, ServerOptions, ServiceConfig, ServiceStats, StalenessCandidate, WatcherClient, WatcherScanPoint, WatcherScanRequest, WatcherScanResult };