eminiar 0.11.0 → 0.13.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/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +64 -10
- package/bin/em-hook +75 -2
- package/dist/cli.js +31606 -16936
- package/dist/hook-async-4MIP3VHX.js +15 -0
- package/dist/hook-chunk-77I6QQ43.js +3780 -0
- package/dist/hook-chunk-IYHVLMJ4.js +24099 -0
- package/dist/hook-chunk-MVOBVFQL.js +9843 -0
- package/dist/hook-hooks-U6GDOQSY.js +1827 -0
- package/dist/hook.js +706 -30200
- package/dist/server.js +45060 -34225
- package/dist/ui/app.global.js +70 -63
- package/dist/ui/styles.css +1832 -0
- package/eminiar.config.schema.json +450 -1
- package/hooks/hooks.json +9 -1
- package/package.json +2 -2
- package/skills/em-doctor/SKILL.md +14 -1
- package/skills/em-onboard/SKILL.md +33 -1
- package/skills/em-swarm/SKILL.md +100 -0
|
@@ -260,7 +260,8 @@
|
|
|
260
260
|
"properties": {
|
|
261
261
|
"manifest": {
|
|
262
262
|
"default": ".eminiar/docs.json",
|
|
263
|
-
"type": "string"
|
|
263
|
+
"type": "string",
|
|
264
|
+
"pattern": "^(?![/\\\\])(?![A-Za-z]:)(?!(?:[\\s\\S]*[/\\\\])?\\.\\.[. ]*(?:[/\\\\]|$))[^\\p{Cc}]+$"
|
|
264
265
|
},
|
|
265
266
|
"ttlHours": {
|
|
266
267
|
"default": 168,
|
|
@@ -489,6 +490,454 @@
|
|
|
489
490
|
"type": "boolean"
|
|
490
491
|
}
|
|
491
492
|
}
|
|
493
|
+
},
|
|
494
|
+
"adjudicator": {
|
|
495
|
+
"default": {},
|
|
496
|
+
"type": "object",
|
|
497
|
+
"properties": {
|
|
498
|
+
"enabled": {
|
|
499
|
+
"default": false,
|
|
500
|
+
"type": "boolean"
|
|
501
|
+
},
|
|
502
|
+
"provider": {
|
|
503
|
+
"default": "heuristic",
|
|
504
|
+
"type": "string",
|
|
505
|
+
"enum": [
|
|
506
|
+
"heuristic",
|
|
507
|
+
"typesafe",
|
|
508
|
+
"openai-compatible",
|
|
509
|
+
"embedding"
|
|
510
|
+
]
|
|
511
|
+
},
|
|
512
|
+
"mode": {
|
|
513
|
+
"default": "advise",
|
|
514
|
+
"type": "string",
|
|
515
|
+
"enum": [
|
|
516
|
+
"advise",
|
|
517
|
+
"apply"
|
|
518
|
+
]
|
|
519
|
+
},
|
|
520
|
+
"surfaces": {
|
|
521
|
+
"default": {},
|
|
522
|
+
"type": "object",
|
|
523
|
+
"properties": {
|
|
524
|
+
"prompt": {
|
|
525
|
+
"default": true,
|
|
526
|
+
"type": "boolean"
|
|
527
|
+
},
|
|
528
|
+
"agent": {
|
|
529
|
+
"default": true,
|
|
530
|
+
"type": "boolean"
|
|
531
|
+
},
|
|
532
|
+
"plan": {
|
|
533
|
+
"default": true,
|
|
534
|
+
"type": "boolean"
|
|
535
|
+
},
|
|
536
|
+
"tools": {
|
|
537
|
+
"default": false,
|
|
538
|
+
"type": "boolean"
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
"promptMode": {
|
|
543
|
+
"default": "async",
|
|
544
|
+
"type": "string",
|
|
545
|
+
"enum": [
|
|
546
|
+
"heuristic",
|
|
547
|
+
"async",
|
|
548
|
+
"blocking"
|
|
549
|
+
]
|
|
550
|
+
},
|
|
551
|
+
"typesafe": {
|
|
552
|
+
"default": {},
|
|
553
|
+
"type": "object",
|
|
554
|
+
"properties": {
|
|
555
|
+
"model": {
|
|
556
|
+
"default": "jev-1.14.0",
|
|
557
|
+
"type": "string"
|
|
558
|
+
},
|
|
559
|
+
"baseUrl": {
|
|
560
|
+
"default": "https://api.typesafe.ai/v1",
|
|
561
|
+
"type": "string",
|
|
562
|
+
"format": "uri"
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
"openai": {
|
|
567
|
+
"default": {},
|
|
568
|
+
"type": "object",
|
|
569
|
+
"properties": {
|
|
570
|
+
"preset": {
|
|
571
|
+
"default": "groq",
|
|
572
|
+
"type": "string",
|
|
573
|
+
"enum": [
|
|
574
|
+
"groq",
|
|
575
|
+
"cerebras",
|
|
576
|
+
"ollama",
|
|
577
|
+
"lmstudio",
|
|
578
|
+
"llamacpp",
|
|
579
|
+
"custom"
|
|
580
|
+
]
|
|
581
|
+
},
|
|
582
|
+
"baseUrl": {
|
|
583
|
+
"type": "string",
|
|
584
|
+
"format": "uri"
|
|
585
|
+
},
|
|
586
|
+
"model": {
|
|
587
|
+
"type": "string"
|
|
588
|
+
},
|
|
589
|
+
"json": {
|
|
590
|
+
"default": "auto",
|
|
591
|
+
"type": "string",
|
|
592
|
+
"enum": [
|
|
593
|
+
"schema",
|
|
594
|
+
"object",
|
|
595
|
+
"auto"
|
|
596
|
+
]
|
|
597
|
+
},
|
|
598
|
+
"price": {
|
|
599
|
+
"type": "object",
|
|
600
|
+
"properties": {
|
|
601
|
+
"inPerM": {
|
|
602
|
+
"type": "number",
|
|
603
|
+
"minimum": 0
|
|
604
|
+
},
|
|
605
|
+
"outPerM": {
|
|
606
|
+
"type": "number",
|
|
607
|
+
"minimum": 0
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
"required": [
|
|
611
|
+
"inPerM",
|
|
612
|
+
"outPerM"
|
|
613
|
+
]
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
"embedding": {
|
|
618
|
+
"default": {},
|
|
619
|
+
"type": "object",
|
|
620
|
+
"properties": {
|
|
621
|
+
"k": {
|
|
622
|
+
"default": 5,
|
|
623
|
+
"type": "integer",
|
|
624
|
+
"exclusiveMinimum": 0,
|
|
625
|
+
"maximum": 9007199254740991
|
|
626
|
+
},
|
|
627
|
+
"minSimilarity": {
|
|
628
|
+
"default": 0.55,
|
|
629
|
+
"type": "number",
|
|
630
|
+
"minimum": 0,
|
|
631
|
+
"maximum": 1
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
"keyEnv": {
|
|
636
|
+
"type": "string",
|
|
637
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
|
|
638
|
+
},
|
|
639
|
+
"remoteConsent": {
|
|
640
|
+
"default": false,
|
|
641
|
+
"type": "boolean"
|
|
642
|
+
},
|
|
643
|
+
"remoteConsentOrigins": {
|
|
644
|
+
"maxItems": 64,
|
|
645
|
+
"type": "array",
|
|
646
|
+
"items": {
|
|
647
|
+
"type": "string",
|
|
648
|
+
"maxLength": 512
|
|
649
|
+
}
|
|
650
|
+
},
|
|
651
|
+
"timeouts": {
|
|
652
|
+
"default": {},
|
|
653
|
+
"type": "object",
|
|
654
|
+
"properties": {
|
|
655
|
+
"promptMs": {
|
|
656
|
+
"default": 1200,
|
|
657
|
+
"type": "integer",
|
|
658
|
+
"exclusiveMinimum": 0,
|
|
659
|
+
"maximum": 9007199254740991
|
|
660
|
+
},
|
|
661
|
+
"agentMs": {
|
|
662
|
+
"default": 800,
|
|
663
|
+
"type": "integer",
|
|
664
|
+
"exclusiveMinimum": 0,
|
|
665
|
+
"maximum": 9007199254740991
|
|
666
|
+
},
|
|
667
|
+
"planMs": {
|
|
668
|
+
"default": 3000,
|
|
669
|
+
"type": "integer",
|
|
670
|
+
"exclusiveMinimum": 0,
|
|
671
|
+
"maximum": 9007199254740991
|
|
672
|
+
},
|
|
673
|
+
"localMs": {
|
|
674
|
+
"default": 600,
|
|
675
|
+
"type": "integer",
|
|
676
|
+
"exclusiveMinimum": 0,
|
|
677
|
+
"maximum": 9007199254740991
|
|
678
|
+
},
|
|
679
|
+
"connectMs": {
|
|
680
|
+
"default": 150,
|
|
681
|
+
"type": "integer",
|
|
682
|
+
"exclusiveMinimum": 0,
|
|
683
|
+
"maximum": 9007199254740991
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
"minPromptChars": {
|
|
688
|
+
"default": 12,
|
|
689
|
+
"type": "integer",
|
|
690
|
+
"minimum": 0,
|
|
691
|
+
"maximum": 9007199254740991
|
|
692
|
+
},
|
|
693
|
+
"tiers": {
|
|
694
|
+
"default": [
|
|
695
|
+
"haiku",
|
|
696
|
+
"sonnet",
|
|
697
|
+
"opus"
|
|
698
|
+
],
|
|
699
|
+
"minItems": 1,
|
|
700
|
+
"maxItems": 4,
|
|
701
|
+
"type": "array",
|
|
702
|
+
"items": {
|
|
703
|
+
"type": "string",
|
|
704
|
+
"enum": [
|
|
705
|
+
"haiku",
|
|
706
|
+
"sonnet",
|
|
707
|
+
"opus",
|
|
708
|
+
"fable"
|
|
709
|
+
]
|
|
710
|
+
},
|
|
711
|
+
"uniqueItems": true
|
|
712
|
+
},
|
|
713
|
+
"weights": {
|
|
714
|
+
"default": {},
|
|
715
|
+
"type": "object",
|
|
716
|
+
"properties": {
|
|
717
|
+
"providerMax": {
|
|
718
|
+
"default": 0.7,
|
|
719
|
+
"type": "number",
|
|
720
|
+
"minimum": 0,
|
|
721
|
+
"maximum": 1
|
|
722
|
+
},
|
|
723
|
+
"embeddingMax": {
|
|
724
|
+
"default": 0.4,
|
|
725
|
+
"type": "number",
|
|
726
|
+
"minimum": 0,
|
|
727
|
+
"maximum": 1
|
|
728
|
+
},
|
|
729
|
+
"selfReportScale": {
|
|
730
|
+
"default": 0.6,
|
|
731
|
+
"type": "number",
|
|
732
|
+
"minimum": 0,
|
|
733
|
+
"maximum": 1
|
|
734
|
+
},
|
|
735
|
+
"lowConfidence": {
|
|
736
|
+
"default": 0.55,
|
|
737
|
+
"type": "number",
|
|
738
|
+
"minimum": 0,
|
|
739
|
+
"maximum": 1
|
|
740
|
+
},
|
|
741
|
+
"tierCenters": {
|
|
742
|
+
"default": {
|
|
743
|
+
"haiku": 0.6,
|
|
744
|
+
"sonnet": 2,
|
|
745
|
+
"opus": 3.4
|
|
746
|
+
},
|
|
747
|
+
"type": "object",
|
|
748
|
+
"propertyNames": {
|
|
749
|
+
"type": "string",
|
|
750
|
+
"maxLength": 32
|
|
751
|
+
},
|
|
752
|
+
"additionalProperties": {
|
|
753
|
+
"type": "number"
|
|
754
|
+
},
|
|
755
|
+
"maxProperties": 16
|
|
756
|
+
},
|
|
757
|
+
"features": {
|
|
758
|
+
"default": {},
|
|
759
|
+
"type": "object",
|
|
760
|
+
"propertyNames": {
|
|
761
|
+
"type": "string",
|
|
762
|
+
"maxLength": 64
|
|
763
|
+
},
|
|
764
|
+
"additionalProperties": {
|
|
765
|
+
"type": "number"
|
|
766
|
+
},
|
|
767
|
+
"maxProperties": 64
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
},
|
|
771
|
+
"apply": {
|
|
772
|
+
"default": {},
|
|
773
|
+
"type": "object",
|
|
774
|
+
"properties": {
|
|
775
|
+
"scope": {
|
|
776
|
+
"default": "swarm",
|
|
777
|
+
"type": "string",
|
|
778
|
+
"enum": [
|
|
779
|
+
"swarm",
|
|
780
|
+
"all"
|
|
781
|
+
]
|
|
782
|
+
},
|
|
783
|
+
"minConfidence": {
|
|
784
|
+
"default": 0.7,
|
|
785
|
+
"type": "number",
|
|
786
|
+
"minimum": 0,
|
|
787
|
+
"maximum": 1
|
|
788
|
+
},
|
|
789
|
+
"floor": {
|
|
790
|
+
"default": "haiku",
|
|
791
|
+
"type": "string",
|
|
792
|
+
"enum": [
|
|
793
|
+
"haiku",
|
|
794
|
+
"sonnet",
|
|
795
|
+
"opus",
|
|
796
|
+
"fable"
|
|
797
|
+
]
|
|
798
|
+
},
|
|
799
|
+
"ceiling": {
|
|
800
|
+
"default": "opus",
|
|
801
|
+
"type": "string",
|
|
802
|
+
"enum": [
|
|
803
|
+
"haiku",
|
|
804
|
+
"sonnet",
|
|
805
|
+
"opus",
|
|
806
|
+
"fable"
|
|
807
|
+
]
|
|
808
|
+
},
|
|
809
|
+
"respectFrontmatter": {
|
|
810
|
+
"default": true,
|
|
811
|
+
"type": "boolean"
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
},
|
|
815
|
+
"advice": {
|
|
816
|
+
"default": {},
|
|
817
|
+
"type": "object",
|
|
818
|
+
"properties": {
|
|
819
|
+
"mainSession": {
|
|
820
|
+
"default": "user",
|
|
821
|
+
"type": "string",
|
|
822
|
+
"enum": [
|
|
823
|
+
"off",
|
|
824
|
+
"user",
|
|
825
|
+
"context"
|
|
826
|
+
]
|
|
827
|
+
},
|
|
828
|
+
"cooldownPrompts": {
|
|
829
|
+
"default": 8,
|
|
830
|
+
"type": "integer",
|
|
831
|
+
"minimum": 0,
|
|
832
|
+
"maximum": 9007199254740991
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
"learning": {
|
|
837
|
+
"default": {},
|
|
838
|
+
"type": "object",
|
|
839
|
+
"properties": {
|
|
840
|
+
"enabled": {
|
|
841
|
+
"default": true,
|
|
842
|
+
"type": "boolean"
|
|
843
|
+
},
|
|
844
|
+
"maxBias": {
|
|
845
|
+
"default": 0.3,
|
|
846
|
+
"type": "number",
|
|
847
|
+
"minimum": 0,
|
|
848
|
+
"maximum": 1
|
|
849
|
+
},
|
|
850
|
+
"minSamples": {
|
|
851
|
+
"default": 5,
|
|
852
|
+
"type": "integer",
|
|
853
|
+
"minimum": 0,
|
|
854
|
+
"maximum": 9007199254740991
|
|
855
|
+
},
|
|
856
|
+
"halfLife": {
|
|
857
|
+
"default": 50,
|
|
858
|
+
"type": "number",
|
|
859
|
+
"exclusiveMinimum": 0
|
|
860
|
+
},
|
|
861
|
+
"costWeight": {
|
|
862
|
+
"default": 0.05,
|
|
863
|
+
"type": "number",
|
|
864
|
+
"minimum": 0
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
"cache": {
|
|
869
|
+
"default": {},
|
|
870
|
+
"type": "object",
|
|
871
|
+
"properties": {
|
|
872
|
+
"ttlHours": {
|
|
873
|
+
"default": 24,
|
|
874
|
+
"type": "number",
|
|
875
|
+
"exclusiveMinimum": 0
|
|
876
|
+
},
|
|
877
|
+
"maxEntries": {
|
|
878
|
+
"default": 2000,
|
|
879
|
+
"type": "integer",
|
|
880
|
+
"exclusiveMinimum": 0,
|
|
881
|
+
"maximum": 9007199254740991
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
},
|
|
885
|
+
"breaker": {
|
|
886
|
+
"default": {},
|
|
887
|
+
"type": "object",
|
|
888
|
+
"properties": {
|
|
889
|
+
"failures": {
|
|
890
|
+
"default": 2,
|
|
891
|
+
"type": "integer",
|
|
892
|
+
"exclusiveMinimum": 0,
|
|
893
|
+
"maximum": 9007199254740991
|
|
894
|
+
},
|
|
895
|
+
"cooldownSec": {
|
|
896
|
+
"default": 120,
|
|
897
|
+
"type": "integer",
|
|
898
|
+
"exclusiveMinimum": 0,
|
|
899
|
+
"maximum": 9007199254740991
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
},
|
|
903
|
+
"budget": {
|
|
904
|
+
"default": {},
|
|
905
|
+
"type": "object",
|
|
906
|
+
"properties": {
|
|
907
|
+
"dailyUsd": {
|
|
908
|
+
"default": 0.5,
|
|
909
|
+
"type": "number",
|
|
910
|
+
"minimum": 0
|
|
911
|
+
},
|
|
912
|
+
"dailyCalls": {
|
|
913
|
+
"default": 2000,
|
|
914
|
+
"type": "integer",
|
|
915
|
+
"minimum": 0,
|
|
916
|
+
"maximum": 9007199254740991
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
},
|
|
920
|
+
"privacy": {
|
|
921
|
+
"default": {},
|
|
922
|
+
"type": "object",
|
|
923
|
+
"properties": {
|
|
924
|
+
"maxChars": {
|
|
925
|
+
"default": 2000,
|
|
926
|
+
"type": "integer",
|
|
927
|
+
"exclusiveMinimum": 0,
|
|
928
|
+
"maximum": 9007199254740991
|
|
929
|
+
},
|
|
930
|
+
"storeHead": {
|
|
931
|
+
"default": true,
|
|
932
|
+
"type": "boolean"
|
|
933
|
+
},
|
|
934
|
+
"captureExchanges": {
|
|
935
|
+
"default": false,
|
|
936
|
+
"type": "boolean"
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
492
941
|
}
|
|
493
942
|
},
|
|
494
943
|
"title": "eminiar.config.json",
|
package/hooks/hooks.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
],
|
|
17
17
|
"PreToolUse": [
|
|
18
18
|
{
|
|
19
|
-
"matcher": "Bash|Read|Edit|MultiEdit|Write|Grep|Glob|WebFetch|WebSearch|Agent|Task",
|
|
19
|
+
"matcher": "^(Bash|Read|Edit|MultiEdit|Write|Grep|Glob|WebFetch|WebSearch|Agent|Task|mcp__.*__em_swarm)$",
|
|
20
20
|
"hooks": [
|
|
21
21
|
{ "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}/bin/em-hook\"", "timeout": 5 }
|
|
22
22
|
]
|
|
@@ -41,6 +41,14 @@
|
|
|
41
41
|
]
|
|
42
42
|
}
|
|
43
43
|
],
|
|
44
|
+
"SubagentStart": [
|
|
45
|
+
{
|
|
46
|
+
"matcher": "^swarm-",
|
|
47
|
+
"hooks": [
|
|
48
|
+
{ "type": "command", "command": "\"${CLAUDE_PLUGIN_ROOT}/bin/em-hook\"", "timeout": 10 }
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
],
|
|
44
52
|
"SubagentStop": [
|
|
45
53
|
{
|
|
46
54
|
"hooks": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eminiar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Local-first context, memory and knowledge-graph plugin for Claude Code and Cursor. Sandboxed execution, FTS5 + vector search, session continuity, and a code graph — nothing leaves your machine.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"LICENSE"
|
|
50
50
|
],
|
|
51
51
|
"scripts": {
|
|
52
|
-
"build": "tsup && tsup --config tsup.web.config.ts && node scripts/copy-grammars.mjs && tsx scripts/gen-schema.ts",
|
|
52
|
+
"build": "tsup && node scripts/check-bundle.mjs && tsup --config tsup.web.config.ts && node scripts/copy-grammars.mjs && tsx scripts/gen-schema.ts",
|
|
53
53
|
"dev": "tsup --watch",
|
|
54
54
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
|
|
55
55
|
"test": "vitest run",
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: em-doctor
|
|
3
|
-
description: Diagnose the eminiar installation — node, SQLite FTS5, sqlite-vec, embedding model, sandbox languages, routing mode, context-mode coexistence, project root.
|
|
3
|
+
description: Diagnose the eminiar installation — node, SQLite FTS5, sqlite-vec, embedding model, sandbox languages, routing mode, context-mode coexistence, project root, and the opt-in adjudicator (provider, key, consent, health).
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools: mcp__plugin_eminiar_eminiar__em_doctor
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
Call `em_doctor` and show the checklist verbatim. For any failed check, suggest the fix in one
|
|
9
9
|
line (usually `npx eminiar install` or `eminiar doctor --fix` from a terminal).
|
|
10
|
+
|
|
11
|
+
When the adjudicator is on, the `adjudicator*` checks cover: the config is valid; the
|
|
12
|
+
configured provider is the one that runs (or why the heuristic runs instead: no key, no
|
|
13
|
+
consent, an API key rejected, misconfigured); the key is present and `~/.eminiar/adjudicator.key`
|
|
14
|
+
is mode 0600; consent for a remote provider; breaker state and p95 latency against the budget;
|
|
15
|
+
the last 24 h fallback rate; `CLAUDE_CODE_SUBAGENT_MODEL_FORCE` set while mode is apply; in
|
|
16
|
+
apply mode, `adjudicator swarm pins` (information, not a failure) when every role of a swarm
|
|
17
|
+
pins a model without a range, so apply mode cannot change any of its workers; and, for the
|
|
18
|
+
embedding provider, whether the exemplar vectors are cached. Fixes are
|
|
19
|
+
`eminiar adjudicator key set`, `eminiar adjudicator enable --accept-remote`, `chmod 600
|
|
20
|
+
~/.eminiar/adjudicator.key`, `eminiar adjudicator status`, or for swarm pins a `model_range` on
|
|
21
|
+
the roles in `.eminiar/swarm.yaml` followed by `eminiar swarm sync`. `eminiar doctor` (terminal) also
|
|
22
|
+
probes the provider live with a 2 s timeout.
|
|
@@ -42,6 +42,38 @@ Then write, via `em_remember {kind: "onboarding", name: …, content: …}`:
|
|
|
42
42
|
are, which local specs exist, and the rule: `em_docs {action: "lookup", query}` before
|
|
43
43
|
WebFetch/WebSearch for anything the project depends on.
|
|
44
44
|
|
|
45
|
+
Then ask about the adjudicator (optional; it is off by default and is never turned on
|
|
46
|
+
without a yes). Skip this step if the user asked for a non-interactive or default onboarding,
|
|
47
|
+
or if `eminiar adjudicator status --json` (run with `em_execute`, language shell; use
|
|
48
|
+
`npx eminiar` if `eminiar` is not on PATH) shows it is already on.
|
|
49
|
+
|
|
50
|
+
1. Explain in two sentences: the adjudicator scores how complex each prompt, subagent task
|
|
51
|
+
and swarm task is and suggests the eminiar tool, the Claude model size (haiku / sonnet /
|
|
52
|
+
opus) and the swarm agent role for it, to save tokens. Then ask exactly:
|
|
53
|
+
**"Use the adjudicator for tool, model and agent selection? (default: no)"**
|
|
54
|
+
Anything but a clear yes means no: say `eminiar adjudicator enable` turns it on later, and stop.
|
|
55
|
+
2. On yes, ask which provider, and say for each whether text leaves the machine:
|
|
56
|
+
- **heuristic** (default): built-in rules; offline, nothing leaves this machine.
|
|
57
|
+
- **embedding**: nearest examples with the local embedding model; offline.
|
|
58
|
+
- **Jev** (TypeSafe, api.typesafe.ai): hosted; sends prompt text off this machine; needs an API key.
|
|
59
|
+
- **OpenAI-compatible**: a local server (Ollama on 11434, LM Studio on 1234, llama.cpp on
|
|
60
|
+
8080; nothing leaves the machine) or a hosted one (Groq, Cerebras; sends prompt text off
|
|
61
|
+
this machine; needs an API key). `eminiar adjudicator provider --detect` finds local servers.
|
|
62
|
+
3. For a choice that sends text off the machine, quote this and get an explicit yes before
|
|
63
|
+
continuing: "The text of your prompts and subagent tasks (redacted, at most 2000 chars) is
|
|
64
|
+
sent to <host> to score them." Without that yes, fall back to the heuristic.
|
|
65
|
+
4. Turn it on with `em_execute` (shell), adding `--accept-remote` only after that explicit yes:
|
|
66
|
+
`eminiar adjudicator enable --provider <heuristic|embedding|typesafe|ollama|lmstudio|llamacpp|groq|cerebras> [--accept-remote]`
|
|
67
|
+
5. For Jev or a hosted preset the key goes into the local key file `~/.eminiar/adjudicator.key`
|
|
68
|
+
(mode 0600), never into the chat, a config file or a command line. Ask the user to run, in
|
|
69
|
+
their own terminal: `eminiar adjudicator key set typesafe` (or `groq` / `cerebras`), which
|
|
70
|
+
reads the key at a hidden prompt. If the key is already in an environment variable,
|
|
71
|
+
`eminiar adjudicator key set --from-env NAME` stores only the variable's name. If the user
|
|
72
|
+
pastes a key into the chat anyway, do not repeat it or put it in a command; tell them to
|
|
73
|
+
rotate it and use the hidden prompt.
|
|
74
|
+
6. Finish with `eminiar adjudicator status` and tell the user to run `/mcp reconnect` so the
|
|
75
|
+
`em_adjudicate` tool loads (hooks pick the change up on the next prompt).
|
|
76
|
+
|
|
45
77
|
Finish with one line listing the five names; mention that the files live under
|
|
46
78
|
`.eminiar/memories/onboarding/` and the manifest at `.eminiar/docs.json`, and that both
|
|
47
|
-
should be committed.
|
|
79
|
+
should be committed. Add whether the adjudicator was turned on, and with which provider.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: em-swarm
|
|
3
|
+
description: Coordinate an eminiar agent swarm from the main session — start a run of a swarm defined in .eminiar/swarm.yaml, plan small tasks, fan out worker subagents (swarm-<swarm>-<role>) in parallel, watch the task board, review the results and finish the run with a memory. Use when the user asks to run a swarm, use the X swarm, fan out workers, or parallelise a review across roles.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: <swarm> <goal>
|
|
6
|
+
allowed-tools: mcp__plugin_eminiar_eminiar__em_swarm, mcp__plugin_eminiar_eminiar__em_recall, mcp__plugin_eminiar_eminiar__em_history, mcp__plugin_eminiar_eminiar__em_graph_impact, mcp__plugin_eminiar_eminiar__em_architecture, mcp__plugin_eminiar_eminiar__em_symbols, mcp__plugin_eminiar_eminiar__em_remember, Agent
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Arguments: $ARGUMENTS (first word: the swarm; the rest: the goal)
|
|
10
|
+
|
|
11
|
+
You are the **coordinator**. Subagents cannot spawn subagents, so only you plan, spawn and
|
|
12
|
+
review; workers are leaves that claim tasks and report back through `em_swarm`.
|
|
13
|
+
|
|
14
|
+
**Use a swarm when** the goal splits into 3 or more pieces of work that can run independently
|
|
15
|
+
(separate files or modules), or when you want several reviewers to look at the same change
|
|
16
|
+
from different angles at once.
|
|
17
|
+
|
|
18
|
+
**Skip it when** the change is a single-file edit, a quick fix, or tightly coupled sequential
|
|
19
|
+
work where each step needs the previous step's exact output. Do the work directly instead.
|
|
20
|
+
|
|
21
|
+
## 0. Check the swarm exists
|
|
22
|
+
|
|
23
|
+
Call `em_swarm {action:"list"}`. If it says swarms are opt-in or disabled, stop and tell the user
|
|
24
|
+
how to opt in: `eminiar swarm init` (starter `.eminiar/swarm.yaml` plus generated agents), the
|
|
25
|
+
"Create starter swarm.yaml" button on the dashboard's Swarms tab (`eminiar ui`), or writing the
|
|
26
|
+
file by hand (https://github.com/rydn/eminiar/blob/main/docs/swarms.md). Do not improvise a swarm with ad-hoc subagents. If the file has
|
|
27
|
+
validation errors, show them and stop. If it says the call was not stamped by eminiar's hook,
|
|
28
|
+
stop and tell the user to run `eminiar upgrade` (or `eminiar install`) and check `/hooks`:
|
|
29
|
+
without the stamp every change is refused. If no swarm was named, pick the one whose description
|
|
30
|
+
fits the goal and say which.
|
|
31
|
+
|
|
32
|
+
## 1. Start the run
|
|
33
|
+
|
|
34
|
+
`em_swarm {action:"start", swarm, goal}` returns your brief: the topology's rules, the roles with
|
|
35
|
+
their `subagent_type`, model and `count`, the capacity (`max_agents`), the swarm's own
|
|
36
|
+
instructions, and what eminiar knows (memories, bug-prone files, hot files, project brief).
|
|
37
|
+
Read it before planning. Check `em_recall` / `em_architecture` / `em_graph_impact` for anything
|
|
38
|
+
the brief leaves open.
|
|
39
|
+
|
|
40
|
+
If it warns that the swarm already has an active run in this session, either finish the old run
|
|
41
|
+
(`em_swarm {action:"finish", run, status:"cancelled"}`) or pass `run` on every later call: while
|
|
42
|
+
several runs are active, calls without `run` are refused with the list of runs.
|
|
43
|
+
|
|
44
|
+
## 2. Plan small tasks
|
|
45
|
+
|
|
46
|
+
`em_swarm {action:"plan", tasks:[{key, title, detail, role, deps, files}]}`
|
|
47
|
+
|
|
48
|
+
- One task = what one worker can finish in one go. Name the files it touches in `files`.
|
|
49
|
+
- Only those six keys; put anything else in `detail` (other keys are refused).
|
|
50
|
+
- `role` must be a role of the swarm. `deps` take task ids or the `key` of an earlier task in the
|
|
51
|
+
same call. Avoid two parallel tasks editing the same file.
|
|
52
|
+
- Hierarchical: you assign every task to a role. Mesh: seed tasks; workers claim any.
|
|
53
|
+
Pipeline: a stage opens only when every task of the earlier stages is done. In every topology
|
|
54
|
+
workers may plan follow-up tasks (a reviewer adds fixes for the coder).
|
|
55
|
+
|
|
56
|
+
## 3. Spawn workers
|
|
57
|
+
|
|
58
|
+
For each claimable task (the plan reply lists them), call the **Agent** tool with
|
|
59
|
+
`subagent_type: "swarm-<swarm>-<role>"` and a prompt that names the task as **"task #N"** plus
|
|
60
|
+
anything the worker needs beyond the task text. The worker claims that task itself as its first
|
|
61
|
+
step; eminiar briefs it with the project knowledge when it starts and with the task when it
|
|
62
|
+
claims.
|
|
63
|
+
|
|
64
|
+
- Use `run_in_background: true` to run independent tasks in parallel.
|
|
65
|
+
- `max_agents` caps the swarm's running workers across all its runs, and `count` caps each role.
|
|
66
|
+
eminiar denies spawns over capacity; if that happens, wait for a worker to finish or release a
|
|
67
|
+
stuck one (step 4).
|
|
68
|
+
- Spawn a task only once its deps are done.
|
|
69
|
+
|
|
70
|
+
## 4. Watch
|
|
71
|
+
|
|
72
|
+
`em_swarm {action:"status"}` starts with the next step, then shows tasks by status, workers,
|
|
73
|
+
blackboard keys and recent events. For long runs, run `eminiar swarm watch` under the
|
|
74
|
+
**Monitor** tool. Its first line is `swarm.snapshot` (or `swarm.finished` if the run is already
|
|
75
|
+
closed); after that it prints one JSON line per change: `swarm.changed` while work is in flight,
|
|
76
|
+
`swarm.idle` when no worker is running and no task is active except ones held by quiet workers
|
|
77
|
+
(`stale_held`), which means it is your turn, and `swarm.finished` at the end. Workers' tool calls
|
|
78
|
+
never produce a line. Read shared findings with `em_swarm {action:"read"}`. Spawn the next
|
|
79
|
+
workers as deps complete.
|
|
80
|
+
|
|
81
|
+
A task line flagged **holder quiet Nm** belongs to a worker silent for 15 minutes or more,
|
|
82
|
+
usually one that crashed. Free it with `em_swarm {action:"release", agent}` (with no `agent`,
|
|
83
|
+
every quiet worker is released); the task goes back to pending, so spawn a new worker for it.
|
|
84
|
+
|
|
85
|
+
## 5. Review
|
|
86
|
+
|
|
87
|
+
- Read every result. A task flagged **auto-closed** was closed from the worker's last message
|
|
88
|
+
because it never reported: check that the work is really done.
|
|
89
|
+
- Reopen unfinished work with `em_swarm {action:"update", task, status:"pending"}` or plan
|
|
90
|
+
follow-up tasks; `blocked` tasks need an answer or a re-plan.
|
|
91
|
+
- If the swarm has a reviewer role, run it **last**, on the full diff, as an adversarial
|
|
92
|
+
review. Turn each confirmed finding into a task and repeat until none are left.
|
|
93
|
+
- Run the tests yourself before you call the goal met.
|
|
94
|
+
|
|
95
|
+
## 6. Finish
|
|
96
|
+
|
|
97
|
+
`em_swarm {action:"finish", status:"done"|"failed"|"cancelled", summary, remember:true}` closes
|
|
98
|
+
the run and its running workers, and writes the outcome as a memory (`swarm/run-<date>-<slug>`). Record durable decisions
|
|
99
|
+
and constraints the run produced with `em_remember`. Then report to the user: what changed,
|
|
100
|
+
which files, what was verified, and anything left open.
|