@mainahq/core 1.0.3 → 1.1.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/package.json +1 -1
- package/src/ai/__tests__/delegation.test.ts +55 -1
- package/src/ai/delegation.ts +5 -3
- package/src/context/__tests__/budget.test.ts +29 -6
- package/src/context/__tests__/engine.test.ts +1 -0
- package/src/context/__tests__/selector.test.ts +23 -3
- package/src/context/__tests__/wiki.test.ts +349 -0
- package/src/context/budget.ts +12 -8
- package/src/context/engine.ts +37 -0
- package/src/context/selector.ts +30 -4
- package/src/context/wiki.ts +296 -0
- package/src/db/index.ts +12 -0
- package/src/feedback/__tests__/capture.test.ts +166 -0
- package/src/feedback/__tests__/signals.test.ts +144 -0
- package/src/feedback/__tests__/tmp-capture-1775575256633-lah0etnzlj/feedback.db +0 -0
- package/src/feedback/__tests__/tmp-capture-1775575256640-2xmjme4qraa/feedback.db +0 -0
- package/src/feedback/capture.ts +102 -0
- package/src/feedback/signals.ts +68 -0
- package/src/index.ts +104 -0
- package/src/init/__tests__/init.test.ts +400 -3
- package/src/init/index.ts +368 -12
- package/src/language/__tests__/__fixtures__/detect/composer.lock +1 -0
- package/src/prompts/defaults/index.ts +3 -1
- package/src/prompts/defaults/wiki-compile.md +20 -0
- package/src/prompts/defaults/wiki-query.md +18 -0
- package/src/stats/__tests__/tool-usage.test.ts +133 -0
- package/src/stats/tracker.ts +92 -0
- package/src/verify/__tests__/pipeline.test.ts +11 -8
- package/src/verify/pipeline.ts +13 -1
- package/src/verify/tools/__tests__/wiki-lint.test.ts +784 -0
- package/src/verify/tools/wiki-lint-runner.ts +38 -0
- package/src/verify/tools/wiki-lint.ts +898 -0
- package/src/wiki/__tests__/compiler.test.ts +389 -0
- package/src/wiki/__tests__/extractors/code.test.ts +99 -0
- package/src/wiki/__tests__/extractors/decision.test.ts +323 -0
- package/src/wiki/__tests__/extractors/feature.test.ts +186 -0
- package/src/wiki/__tests__/extractors/workflow.test.ts +131 -0
- package/src/wiki/__tests__/graph.test.ts +344 -0
- package/src/wiki/__tests__/hooks.test.ts +119 -0
- package/src/wiki/__tests__/indexer.test.ts +285 -0
- package/src/wiki/__tests__/linker.test.ts +230 -0
- package/src/wiki/__tests__/louvain.test.ts +229 -0
- package/src/wiki/__tests__/query.test.ts +316 -0
- package/src/wiki/__tests__/schema.test.ts +114 -0
- package/src/wiki/__tests__/signals.test.ts +474 -0
- package/src/wiki/__tests__/state.test.ts +168 -0
- package/src/wiki/__tests__/tracking.test.ts +118 -0
- package/src/wiki/__tests__/types.test.ts +387 -0
- package/src/wiki/compiler.ts +1075 -0
- package/src/wiki/extractors/code.ts +90 -0
- package/src/wiki/extractors/decision.ts +217 -0
- package/src/wiki/extractors/feature.ts +206 -0
- package/src/wiki/extractors/workflow.ts +112 -0
- package/src/wiki/graph.ts +445 -0
- package/src/wiki/hooks.ts +49 -0
- package/src/wiki/indexer.ts +105 -0
- package/src/wiki/linker.ts +117 -0
- package/src/wiki/louvain.ts +190 -0
- package/src/wiki/prompts/compile-architecture.md +59 -0
- package/src/wiki/prompts/compile-decision.md +66 -0
- package/src/wiki/prompts/compile-entity.md +56 -0
- package/src/wiki/prompts/compile-feature.md +60 -0
- package/src/wiki/prompts/compile-module.md +42 -0
- package/src/wiki/prompts/wiki-query.md +25 -0
- package/src/wiki/query.ts +338 -0
- package/src/wiki/schema.ts +111 -0
- package/src/wiki/signals.ts +368 -0
- package/src/wiki/state.ts +89 -0
- package/src/wiki/tracking.ts +30 -0
- package/src/wiki/types.ts +169 -0
- package/src/workflow/context.ts +26 -0
package/src/init/index.ts
CHANGED
|
@@ -332,7 +332,9 @@ const MCP_TOOLS_TABLE = `| Tool | When to use |
|
|
|
332
332
|
| \`suggestTests\` | When implementing — generate TDD test stubs |
|
|
333
333
|
| \`getConventions\` | Understand project coding conventions |
|
|
334
334
|
| \`explainModule\` | Understand a module's purpose and dependencies |
|
|
335
|
-
| \`analyzeFeature\` | Analyze a feature directory for consistency
|
|
335
|
+
| \`analyzeFeature\` | Analyze a feature directory for consistency |
|
|
336
|
+
| \`wikiQuery\` | Search wiki for codebase knowledge — "how does auth work?" |
|
|
337
|
+
| \`wikiStatus\` | Wiki health check — article counts, staleness, coverage |`;
|
|
336
338
|
|
|
337
339
|
// ── Templates ────────────────────────────────────────────────────────────────
|
|
338
340
|
|
|
@@ -465,6 +467,13 @@ maina commit # verify + commit
|
|
|
465
467
|
|
|
466
468
|
${MCP_TOOLS_TABLE}
|
|
467
469
|
|
|
470
|
+
## Wiki
|
|
471
|
+
|
|
472
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
473
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
474
|
+
- \`wikiStatus\` to check health
|
|
475
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
476
|
+
|
|
468
477
|
## Config Files
|
|
469
478
|
| File | Purpose | Who Edits |
|
|
470
479
|
|------|---------|-----------|
|
|
@@ -474,6 +483,13 @@ ${MCP_TOOLS_TABLE}
|
|
|
474
483
|
| \`CLAUDE.md\` | Claude Code specific instructions | Optional, Claude Code users |
|
|
475
484
|
| \`GEMINI.md\` | Gemini CLI specific instructions | Optional, Gemini CLI users |
|
|
476
485
|
| \`.cursorrules\` | Cursor specific instructions | Optional, Cursor users |
|
|
486
|
+
| \`.windsurfrules\` | Windsurf specific instructions | Optional, Windsurf users |
|
|
487
|
+
| \`.clinerules\` | Cline specific instructions | Optional, Cline users |
|
|
488
|
+
| \`.continue/\` | Continue.dev config + MCP | Optional, Continue.dev users |
|
|
489
|
+
| \`.roo/\` | Roo Code MCP config + rules | Optional, Roo Code users |
|
|
490
|
+
| \`.amazonq/mcp.json\` | Amazon Q MCP config | Optional, Amazon Q users |
|
|
491
|
+
| \`.aider.conf.yml\` | Aider config | Optional, Aider users |
|
|
492
|
+
| \`CONVENTIONS.md\` | Project conventions (Aider, generic) | Team |
|
|
477
493
|
| \`.mcp.json\` | MCP server configuration | Team |
|
|
478
494
|
| \`.maina/prompts/*.md\` | Prompt overrides for review/commit/etc | Maina (via \`maina learn\`) |
|
|
479
495
|
|
|
@@ -506,6 +522,13 @@ Follow this order for every feature:
|
|
|
506
522
|
|
|
507
523
|
${MCP_TOOLS_TABLE}
|
|
508
524
|
|
|
525
|
+
## Wiki
|
|
526
|
+
|
|
527
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
528
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
529
|
+
- \`wikiStatus\` to check health
|
|
530
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
531
|
+
|
|
509
532
|
## Conventions
|
|
510
533
|
|
|
511
534
|
- Runtime: ${stack.runtime}
|
|
@@ -529,6 +552,10 @@ const MERGEABLE_AGENT_FILES = [
|
|
|
529
552
|
"GEMINI.md",
|
|
530
553
|
".cursorrules",
|
|
531
554
|
".github/copilot-instructions.md",
|
|
555
|
+
".windsurfrules",
|
|
556
|
+
".clinerules",
|
|
557
|
+
".roo/rules/maina.md",
|
|
558
|
+
"CONVENTIONS.md",
|
|
532
559
|
];
|
|
533
560
|
|
|
534
561
|
/**
|
|
@@ -551,13 +578,32 @@ ${MCP_TOOLS_TABLE}
|
|
|
551
578
|
|
|
552
579
|
// ── .mcp.json ───────────────────────────────────────────────────────────────
|
|
553
580
|
|
|
554
|
-
function buildMcpJson(): string {
|
|
581
|
+
function buildMcpJson(stack: DetectedStack): string {
|
|
582
|
+
const command = stack.runtime === "bun" ? "bunx" : "npx";
|
|
555
583
|
return JSON.stringify(
|
|
556
584
|
{
|
|
557
585
|
mcpServers: {
|
|
558
586
|
maina: {
|
|
559
|
-
command
|
|
560
|
-
args: ["--mcp"],
|
|
587
|
+
command,
|
|
588
|
+
args: ["@mainahq/cli", "--mcp"],
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
null,
|
|
593
|
+
2,
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// ── .claude/settings.json (Claude Code MCP config) ─────────────────────────
|
|
598
|
+
|
|
599
|
+
function buildClaudeSettings(stack: DetectedStack): string {
|
|
600
|
+
const command = stack.runtime === "bun" ? "bunx" : "npx";
|
|
601
|
+
return JSON.stringify(
|
|
602
|
+
{
|
|
603
|
+
mcpServers: {
|
|
604
|
+
maina: {
|
|
605
|
+
command,
|
|
606
|
+
args: ["@mainahq/cli", "--mcp"],
|
|
561
607
|
},
|
|
562
608
|
},
|
|
563
609
|
},
|
|
@@ -586,16 +632,42 @@ Maina exposes MCP tools — use them in every session:
|
|
|
586
632
|
|
|
587
633
|
${MCP_TOOLS_TABLE}
|
|
588
634
|
|
|
635
|
+
## Wiki
|
|
636
|
+
|
|
637
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
638
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
639
|
+
- \`wikiStatus\` to check health
|
|
640
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
641
|
+
|
|
589
642
|
## Commands
|
|
590
643
|
|
|
591
644
|
\`\`\`bash
|
|
592
|
-
|
|
593
|
-
maina
|
|
594
|
-
maina
|
|
595
|
-
maina
|
|
596
|
-
maina
|
|
597
|
-
maina
|
|
598
|
-
|
|
645
|
+
# Workflow
|
|
646
|
+
maina brainstorm # explore ideas interactively
|
|
647
|
+
maina ticket # create GitHub issue with module tagging
|
|
648
|
+
maina plan <name> # scaffold feature branch + directory
|
|
649
|
+
maina design # create ADR (architecture decision record)
|
|
650
|
+
maina spec # generate TDD test stubs from plan
|
|
651
|
+
|
|
652
|
+
# Verify & Review
|
|
653
|
+
maina verify # run full verification pipeline (12+ tools)
|
|
654
|
+
maina review # two-stage code review
|
|
655
|
+
maina slop # detect AI-generated slop patterns
|
|
656
|
+
maina commit # verify + commit staged changes
|
|
657
|
+
|
|
658
|
+
# Wiki (codebase knowledge)
|
|
659
|
+
maina wiki init # compile codebase knowledge wiki
|
|
660
|
+
maina wiki query # ask questions about the codebase
|
|
661
|
+
maina wiki compile # recompile wiki (incremental)
|
|
662
|
+
maina wiki status # wiki health dashboard
|
|
663
|
+
maina wiki lint # check wiki for issues
|
|
664
|
+
|
|
665
|
+
# Context & Info
|
|
666
|
+
maina context # generate focused codebase context
|
|
667
|
+
maina explain # explain a module with wiki context
|
|
668
|
+
maina doctor # check tool health
|
|
669
|
+
maina stats # verification metrics
|
|
670
|
+
maina status # branch health overview
|
|
599
671
|
\`\`\`
|
|
600
672
|
|
|
601
673
|
## Conventions
|
|
@@ -629,6 +701,13 @@ Maina exposes MCP tools via \`.mcp.json\`. Use them:
|
|
|
629
701
|
|
|
630
702
|
${MCP_TOOLS_TABLE}
|
|
631
703
|
|
|
704
|
+
## Wiki
|
|
705
|
+
|
|
706
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
707
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
708
|
+
- \`wikiStatus\` to check health
|
|
709
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
710
|
+
|
|
632
711
|
## Key Commands
|
|
633
712
|
|
|
634
713
|
- \`maina verify\` — run full verification pipeline
|
|
@@ -661,6 +740,89 @@ ${WORKFLOW_ORDER}
|
|
|
661
740
|
## MCP Tools (via .mcp.json)
|
|
662
741
|
${MCP_TOOLS_TABLE}
|
|
663
742
|
|
|
743
|
+
## Wiki
|
|
744
|
+
|
|
745
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
746
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
747
|
+
- \`wikiStatus\` to check health
|
|
748
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
749
|
+
|
|
750
|
+
## Commands
|
|
751
|
+
- maina verify — run full verification pipeline
|
|
752
|
+
- maina commit — verify + commit
|
|
753
|
+
- maina review — two-stage code review
|
|
754
|
+
- maina context — generate focused codebase context
|
|
755
|
+
|
|
756
|
+
## Conventions
|
|
757
|
+
- Runtime: ${stack.runtime}
|
|
758
|
+
- Test: ${runCmd} test
|
|
759
|
+
- Conventional commits
|
|
760
|
+
- No console.log in production
|
|
761
|
+
- Diff-only: only report findings on changed lines
|
|
762
|
+
- TDD: write tests first, then implement
|
|
763
|
+
`;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// ── Windsurf ────────────────────────────────────────────────────────────────
|
|
767
|
+
|
|
768
|
+
function buildWindsurfRules(stack: DetectedStack): string {
|
|
769
|
+
const runCmd = stack.runtime === "bun" ? "bun" : "npm";
|
|
770
|
+
return `# Windsurf Rules
|
|
771
|
+
|
|
772
|
+
This repo uses Maina for verification-first development.
|
|
773
|
+
Read \`.maina/constitution.md\` for project DNA.
|
|
774
|
+
|
|
775
|
+
## Workflow Order
|
|
776
|
+
${WORKFLOW_ORDER}
|
|
777
|
+
|
|
778
|
+
## MCP Tools (via .mcp.json)
|
|
779
|
+
${MCP_TOOLS_TABLE}
|
|
780
|
+
|
|
781
|
+
## Wiki
|
|
782
|
+
|
|
783
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
784
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
785
|
+
- \`wikiStatus\` to check health
|
|
786
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
787
|
+
|
|
788
|
+
## Commands
|
|
789
|
+
- maina verify — run full verification pipeline
|
|
790
|
+
- maina commit — verify + commit
|
|
791
|
+
- maina review — two-stage code review
|
|
792
|
+
- maina context — generate focused codebase context
|
|
793
|
+
|
|
794
|
+
## Conventions
|
|
795
|
+
- Runtime: ${stack.runtime}
|
|
796
|
+
- Test: ${runCmd} test
|
|
797
|
+
- Conventional commits
|
|
798
|
+
- No console.log in production
|
|
799
|
+
- Diff-only: only report findings on changed lines
|
|
800
|
+
- TDD: write tests first, then implement
|
|
801
|
+
`;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// ── Cline ───────────────────────────────────────────────────────────────────
|
|
805
|
+
|
|
806
|
+
function buildClineRules(stack: DetectedStack): string {
|
|
807
|
+
const runCmd = stack.runtime === "bun" ? "bun" : "npm";
|
|
808
|
+
return `# Cline Rules
|
|
809
|
+
|
|
810
|
+
This repo uses Maina for verification-first development.
|
|
811
|
+
Read \`.maina/constitution.md\` for project DNA.
|
|
812
|
+
|
|
813
|
+
## Workflow Order
|
|
814
|
+
${WORKFLOW_ORDER}
|
|
815
|
+
|
|
816
|
+
## MCP Tools (via .mcp.json)
|
|
817
|
+
${MCP_TOOLS_TABLE}
|
|
818
|
+
|
|
819
|
+
## Wiki
|
|
820
|
+
|
|
821
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
822
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
823
|
+
- \`wikiStatus\` to check health
|
|
824
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
825
|
+
|
|
664
826
|
## Commands
|
|
665
827
|
- maina verify — run full verification pipeline
|
|
666
828
|
- maina commit — verify + commit
|
|
@@ -677,6 +839,160 @@ ${MCP_TOOLS_TABLE}
|
|
|
677
839
|
`;
|
|
678
840
|
}
|
|
679
841
|
|
|
842
|
+
// ── Continue.dev ─────────────────────────────────────────────────────────────
|
|
843
|
+
|
|
844
|
+
function buildContinueConfig(_stack: DetectedStack): string {
|
|
845
|
+
return `# Continue.dev configuration — auto-generated by maina init
|
|
846
|
+
# See https://docs.continue.dev/reference/config
|
|
847
|
+
|
|
848
|
+
customInstructions: |
|
|
849
|
+
This repo uses Maina for verification-first development.
|
|
850
|
+
Read .maina/constitution.md for project DNA.
|
|
851
|
+
Workflow: ${WORKFLOW_ORDER}
|
|
852
|
+
Always run maina verify before committing.
|
|
853
|
+
Use MCP tools: getContext, verify, checkSlop, reviewCode, suggestTests.
|
|
854
|
+
`;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function buildContinueMcpJson(stack: DetectedStack): string {
|
|
858
|
+
const command = stack.runtime === "bun" ? "bunx" : "npx";
|
|
859
|
+
return JSON.stringify(
|
|
860
|
+
{
|
|
861
|
+
maina: {
|
|
862
|
+
command,
|
|
863
|
+
args: ["@mainahq/cli", "--mcp"],
|
|
864
|
+
},
|
|
865
|
+
},
|
|
866
|
+
null,
|
|
867
|
+
2,
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// ── Roo Code ────────────────────────────────────────────────────────────────
|
|
872
|
+
|
|
873
|
+
function buildRooMcpJson(stack: DetectedStack): string {
|
|
874
|
+
const command = stack.runtime === "bun" ? "bunx" : "npx";
|
|
875
|
+
return JSON.stringify(
|
|
876
|
+
{
|
|
877
|
+
mcpServers: {
|
|
878
|
+
maina: {
|
|
879
|
+
command,
|
|
880
|
+
args: ["@mainahq/cli", "--mcp"],
|
|
881
|
+
},
|
|
882
|
+
},
|
|
883
|
+
},
|
|
884
|
+
null,
|
|
885
|
+
2,
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
function buildRooRules(stack: DetectedStack): string {
|
|
890
|
+
const runCmd = stack.runtime === "bun" ? "bun" : "npm";
|
|
891
|
+
return `# Maina
|
|
892
|
+
|
|
893
|
+
This repo uses [Maina](https://mainahq.com) for verification-first development.
|
|
894
|
+
Read \`.maina/constitution.md\` for project DNA.
|
|
895
|
+
|
|
896
|
+
## Workflow Order
|
|
897
|
+
${WORKFLOW_ORDER}
|
|
898
|
+
|
|
899
|
+
## MCP Tools
|
|
900
|
+
${MCP_TOOLS_TABLE}
|
|
901
|
+
|
|
902
|
+
## Wiki
|
|
903
|
+
|
|
904
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
905
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
906
|
+
- \`wikiStatus\` to check health
|
|
907
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
908
|
+
|
|
909
|
+
## Commands
|
|
910
|
+
- maina verify — run full verification pipeline
|
|
911
|
+
- maina commit — verify + commit
|
|
912
|
+
- maina review — two-stage code review
|
|
913
|
+
- maina context — generate focused codebase context
|
|
914
|
+
|
|
915
|
+
## Conventions
|
|
916
|
+
- Runtime: ${stack.runtime}
|
|
917
|
+
- Test: ${runCmd} test
|
|
918
|
+
- Conventional commits
|
|
919
|
+
- No console.log in production
|
|
920
|
+
- Diff-only: only report findings on changed lines
|
|
921
|
+
- TDD: write tests first, then implement
|
|
922
|
+
`;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// ── Amazon Q ────────────────────────────────────────────────────────────────
|
|
926
|
+
|
|
927
|
+
function buildAmazonQMcpJson(stack: DetectedStack): string {
|
|
928
|
+
const command = stack.runtime === "bun" ? "bunx" : "npx";
|
|
929
|
+
return JSON.stringify(
|
|
930
|
+
{
|
|
931
|
+
mcpServers: {
|
|
932
|
+
maina: {
|
|
933
|
+
command,
|
|
934
|
+
args: ["@mainahq/cli", "--mcp"],
|
|
935
|
+
},
|
|
936
|
+
},
|
|
937
|
+
},
|
|
938
|
+
null,
|
|
939
|
+
2,
|
|
940
|
+
);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// ── Aider ───────────────────────────────────────────────────────────────────
|
|
944
|
+
|
|
945
|
+
function buildAiderConfig(_stack: DetectedStack): string {
|
|
946
|
+
return `# Maina conventions — auto-generated by maina init
|
|
947
|
+
read: [CONVENTIONS.md, .maina/constitution.md]
|
|
948
|
+
auto-commits: false
|
|
949
|
+
`;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
function buildConventionsMd(stack: DetectedStack): string {
|
|
953
|
+
const runCmd = stack.runtime === "bun" ? "bun" : "npm";
|
|
954
|
+
return `# Conventions
|
|
955
|
+
|
|
956
|
+
This repo uses [Maina](https://mainahq.com) for verification-first development.
|
|
957
|
+
Read \`.maina/constitution.md\` for project DNA — stack rules, conventions, and gates.
|
|
958
|
+
|
|
959
|
+
## Maina Workflow
|
|
960
|
+
|
|
961
|
+
Follow this order for every feature:
|
|
962
|
+
\`${WORKFLOW_ORDER}\`
|
|
963
|
+
|
|
964
|
+
## MCP Tools
|
|
965
|
+
|
|
966
|
+
Maina exposes MCP tools — use them in every session:
|
|
967
|
+
|
|
968
|
+
${MCP_TOOLS_TABLE}
|
|
969
|
+
|
|
970
|
+
## Wiki
|
|
971
|
+
|
|
972
|
+
If \`.maina/wiki/\` exists, use wiki tools for context:
|
|
973
|
+
- \`wikiQuery\` before coding — understand existing patterns and decisions
|
|
974
|
+
- \`wikiStatus\` to check health
|
|
975
|
+
- Wiki articles are loaded automatically as Context Engine Layer 5
|
|
976
|
+
|
|
977
|
+
## Key Commands
|
|
978
|
+
|
|
979
|
+
- \`maina verify\` — run full verification pipeline
|
|
980
|
+
- \`maina commit\` — verify + commit
|
|
981
|
+
- \`maina review\` — two-stage code review
|
|
982
|
+
- \`maina context\` — generate focused codebase context
|
|
983
|
+
- \`maina doctor\` — check tool health
|
|
984
|
+
|
|
985
|
+
## Conventions
|
|
986
|
+
|
|
987
|
+
- Runtime: ${stack.runtime}
|
|
988
|
+
- Test: \`${runCmd} test\`
|
|
989
|
+
- Conventional commits (feat, fix, refactor, test, docs, chore)
|
|
990
|
+
- No \`console.log\` in production code
|
|
991
|
+
- Diff-only: only report findings on changed lines
|
|
992
|
+
- TDD always — write tests first
|
|
993
|
+
`;
|
|
994
|
+
}
|
|
995
|
+
|
|
680
996
|
// ── AI-Generated Constitution ───────────────────────────────────────────────
|
|
681
997
|
|
|
682
998
|
function buildProjectSummary(repoRoot: string, stack: DetectedStack): string {
|
|
@@ -869,7 +1185,11 @@ function getFileManifest(
|
|
|
869
1185
|
},
|
|
870
1186
|
{
|
|
871
1187
|
relativePath: ".mcp.json",
|
|
872
|
-
content: buildMcpJson(),
|
|
1188
|
+
content: buildMcpJson(stack),
|
|
1189
|
+
},
|
|
1190
|
+
{
|
|
1191
|
+
relativePath: ".claude/settings.json",
|
|
1192
|
+
content: buildClaudeSettings(stack),
|
|
873
1193
|
},
|
|
874
1194
|
{
|
|
875
1195
|
relativePath: "CLAUDE.md",
|
|
@@ -883,6 +1203,42 @@ function getFileManifest(
|
|
|
883
1203
|
relativePath: ".cursorrules",
|
|
884
1204
|
content: buildCursorRules(stack),
|
|
885
1205
|
},
|
|
1206
|
+
{
|
|
1207
|
+
relativePath: ".windsurfrules",
|
|
1208
|
+
content: buildWindsurfRules(stack),
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
relativePath: ".clinerules",
|
|
1212
|
+
content: buildClineRules(stack),
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
relativePath: ".continue/config.yaml",
|
|
1216
|
+
content: buildContinueConfig(stack),
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
relativePath: ".continue/mcpServers/maina.json",
|
|
1220
|
+
content: buildContinueMcpJson(stack),
|
|
1221
|
+
},
|
|
1222
|
+
{
|
|
1223
|
+
relativePath: ".roo/mcp.json",
|
|
1224
|
+
content: buildRooMcpJson(stack),
|
|
1225
|
+
},
|
|
1226
|
+
{
|
|
1227
|
+
relativePath: ".roo/rules/maina.md",
|
|
1228
|
+
content: buildRooRules(stack),
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
relativePath: ".amazonq/mcp.json",
|
|
1232
|
+
content: buildAmazonQMcpJson(stack),
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
relativePath: ".aider.conf.yml",
|
|
1236
|
+
content: buildAiderConfig(stack),
|
|
1237
|
+
},
|
|
1238
|
+
{
|
|
1239
|
+
relativePath: "CONVENTIONS.md",
|
|
1240
|
+
content: buildConventionsMd(stack),
|
|
1241
|
+
},
|
|
886
1242
|
];
|
|
887
1243
|
}
|
|
888
1244
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"packages": []}
|
|
@@ -11,7 +11,9 @@ export type PromptTask =
|
|
|
11
11
|
| "spec-questions"
|
|
12
12
|
| "design-approaches"
|
|
13
13
|
| "ai-review"
|
|
14
|
-
| "design-hld-lld"
|
|
14
|
+
| "design-hld-lld"
|
|
15
|
+
| "wiki-query"
|
|
16
|
+
| "wiki-compile";
|
|
15
17
|
|
|
16
18
|
const FALLBACK_TEMPLATE = `You are a helpful AI assistant completing the "{{task}}" task.
|
|
17
19
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
You are enhancing a wiki article with natural language descriptions.
|
|
2
|
+
|
|
3
|
+
## Constitution (non-negotiable)
|
|
4
|
+
{{constitution}}
|
|
5
|
+
|
|
6
|
+
## Instructions
|
|
7
|
+
Enhance this wiki article with natural language descriptions. Keep all existing structured data.
|
|
8
|
+
Add a brief overview paragraph and usage context. Do not remove any existing content.
|
|
9
|
+
|
|
10
|
+
Rules:
|
|
11
|
+
1. Preserve ALL existing markdown structure, headings, lists, and wikilinks
|
|
12
|
+
2. Add a concise overview paragraph after the title heading
|
|
13
|
+
3. Add natural language descriptions to sections that are purely data-driven
|
|
14
|
+
4. Infer relationships not visible from code structure alone where possible
|
|
15
|
+
5. Add brief usage examples if the context provides enough information
|
|
16
|
+
6. Keep the tone technical and factual — do not add filler or marketing language
|
|
17
|
+
7. If anything is ambiguous, use [NEEDS CLARIFICATION: specific question]
|
|
18
|
+
|
|
19
|
+
## Input
|
|
20
|
+
{{input}}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
You are answering a question about a codebase using wiki documentation.
|
|
2
|
+
|
|
3
|
+
## Constitution (non-negotiable)
|
|
4
|
+
{{constitution}}
|
|
5
|
+
|
|
6
|
+
## Instructions
|
|
7
|
+
Answer the user's question based on the provided wiki articles.
|
|
8
|
+
|
|
9
|
+
Rules:
|
|
10
|
+
1. Provide a clear, concise answer that directly addresses the question
|
|
11
|
+
2. Cite relevant articles using [[article_path]] notation (e.g., [[modules/core.md]])
|
|
12
|
+
3. If the articles don't contain enough information, say so explicitly
|
|
13
|
+
4. Do NOT guess or hallucinate information not present in the articles
|
|
14
|
+
5. If anything is ambiguous, use [NEEDS CLARIFICATION: specific question]
|
|
15
|
+
6. Prioritize accuracy over completeness
|
|
16
|
+
|
|
17
|
+
## Input
|
|
18
|
+
{{input}}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { mkdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { getStatsDb } from "../../db/index";
|
|
5
|
+
import { getToolUsageStats, trackToolUsage } from "../tracker";
|
|
6
|
+
|
|
7
|
+
let tmpDir: string;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
tmpDir = join(
|
|
11
|
+
import.meta.dir,
|
|
12
|
+
`tmp-tool-usage-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
13
|
+
);
|
|
14
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
try {
|
|
19
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
20
|
+
} catch {
|
|
21
|
+
/* ignore */
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("tool_usage table", () => {
|
|
26
|
+
test("getStatsDb creates tool_usage table", () => {
|
|
27
|
+
const result = getStatsDb(tmpDir);
|
|
28
|
+
expect(result.ok).toBe(true);
|
|
29
|
+
if (!result.ok) return;
|
|
30
|
+
const { db } = result.value;
|
|
31
|
+
const tables = db
|
|
32
|
+
.query(
|
|
33
|
+
"SELECT name FROM sqlite_master WHERE type='table' AND name='tool_usage'",
|
|
34
|
+
)
|
|
35
|
+
.all();
|
|
36
|
+
expect(tables).toHaveLength(1);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("trackToolUsage", () => {
|
|
41
|
+
test("inserts a tool usage row", () => {
|
|
42
|
+
trackToolUsage(tmpDir, {
|
|
43
|
+
tool: "reviewCode",
|
|
44
|
+
inputHash: "abc123",
|
|
45
|
+
durationMs: 150,
|
|
46
|
+
cacheHit: false,
|
|
47
|
+
});
|
|
48
|
+
const result = getStatsDb(tmpDir);
|
|
49
|
+
expect(result.ok).toBe(true);
|
|
50
|
+
if (!result.ok) return;
|
|
51
|
+
const { db } = result.value;
|
|
52
|
+
const rows = db.query("SELECT * FROM tool_usage").all() as Array<{
|
|
53
|
+
tool: string;
|
|
54
|
+
duration_ms: number;
|
|
55
|
+
cache_hit: number;
|
|
56
|
+
}>;
|
|
57
|
+
expect(rows).toHaveLength(1);
|
|
58
|
+
const row = rows[0];
|
|
59
|
+
expect(row).toBeDefined();
|
|
60
|
+
expect(row?.tool).toBe("reviewCode");
|
|
61
|
+
expect(row?.duration_ms).toBe(150);
|
|
62
|
+
expect(row?.cache_hit).toBe(0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("tracks cache hit", () => {
|
|
66
|
+
trackToolUsage(tmpDir, {
|
|
67
|
+
tool: "reviewCode",
|
|
68
|
+
inputHash: "abc123",
|
|
69
|
+
durationMs: 0,
|
|
70
|
+
cacheHit: true,
|
|
71
|
+
});
|
|
72
|
+
const result = getStatsDb(tmpDir);
|
|
73
|
+
if (!result.ok) return;
|
|
74
|
+
const { db } = result.value;
|
|
75
|
+
const rows = db.query("SELECT * FROM tool_usage WHERE cache_hit = 1").all();
|
|
76
|
+
expect(rows).toHaveLength(1);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("stores workflow_id when provided", () => {
|
|
80
|
+
trackToolUsage(tmpDir, {
|
|
81
|
+
tool: "verify",
|
|
82
|
+
inputHash: "def456",
|
|
83
|
+
durationMs: 200,
|
|
84
|
+
cacheHit: false,
|
|
85
|
+
workflowId: "wf-123",
|
|
86
|
+
});
|
|
87
|
+
const result = getStatsDb(tmpDir);
|
|
88
|
+
if (!result.ok) return;
|
|
89
|
+
const { db } = result.value;
|
|
90
|
+
const row = db.query("SELECT workflow_id FROM tool_usage").get() as {
|
|
91
|
+
workflow_id: string;
|
|
92
|
+
} | null;
|
|
93
|
+
expect(row?.workflow_id).toBe("wf-123");
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe("getToolUsageStats", () => {
|
|
98
|
+
test("returns stats across multiple tool calls", () => {
|
|
99
|
+
trackToolUsage(tmpDir, {
|
|
100
|
+
tool: "reviewCode",
|
|
101
|
+
inputHash: "a",
|
|
102
|
+
durationMs: 100,
|
|
103
|
+
cacheHit: false,
|
|
104
|
+
});
|
|
105
|
+
trackToolUsage(tmpDir, {
|
|
106
|
+
tool: "reviewCode",
|
|
107
|
+
inputHash: "b",
|
|
108
|
+
durationMs: 200,
|
|
109
|
+
cacheHit: true,
|
|
110
|
+
});
|
|
111
|
+
trackToolUsage(tmpDir, {
|
|
112
|
+
tool: "verify",
|
|
113
|
+
inputHash: "c",
|
|
114
|
+
durationMs: 50,
|
|
115
|
+
cacheHit: false,
|
|
116
|
+
});
|
|
117
|
+
const stats = getToolUsageStats(tmpDir);
|
|
118
|
+
expect(stats.totalCalls).toBe(3);
|
|
119
|
+
expect(stats.cacheHits).toBe(1);
|
|
120
|
+
expect(stats.cacheHitRate).toBeCloseTo(1 / 3, 2);
|
|
121
|
+
expect(stats.byTool.reviewCode).toBeDefined();
|
|
122
|
+
expect(stats.byTool.reviewCode?.calls).toBe(2);
|
|
123
|
+
expect(stats.byTool.reviewCode?.cacheHits).toBe(1);
|
|
124
|
+
expect(stats.byTool.verify).toBeDefined();
|
|
125
|
+
expect(stats.byTool.verify?.calls).toBe(1);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("returns empty stats when no data", () => {
|
|
129
|
+
const stats = getToolUsageStats(tmpDir);
|
|
130
|
+
expect(stats.totalCalls).toBe(0);
|
|
131
|
+
expect(stats.cacheHitRate).toBe(0);
|
|
132
|
+
});
|
|
133
|
+
});
|