eminiar 0.12.0 → 0.13.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.
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eminiar",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
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.