kevlar-4u 1.0.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/README.md +357 -0
- package/config/mcp-config.json +9 -0
- package/dist/__tests__/configureWizard.test.d.ts +2 -0
- package/dist/__tests__/configureWizard.test.d.ts.map +1 -0
- package/dist/__tests__/configureWizard.test.js +89 -0
- package/dist/__tests__/configureWizard.test.js.map +1 -0
- package/dist/__tests__/createPersonaTool.test.d.ts +2 -0
- package/dist/__tests__/createPersonaTool.test.d.ts.map +1 -0
- package/dist/__tests__/createPersonaTool.test.js +292 -0
- package/dist/__tests__/createPersonaTool.test.js.map +1 -0
- package/dist/__tests__/createPersonaWizard.test.d.ts +2 -0
- package/dist/__tests__/createPersonaWizard.test.d.ts.map +1 -0
- package/dist/__tests__/createPersonaWizard.test.js +138 -0
- package/dist/__tests__/createPersonaWizard.test.js.map +1 -0
- package/dist/__tests__/deletePersonaWizard.test.d.ts +2 -0
- package/dist/__tests__/deletePersonaWizard.test.d.ts.map +1 -0
- package/dist/__tests__/deletePersonaWizard.test.js +78 -0
- package/dist/__tests__/deletePersonaWizard.test.js.map +1 -0
- package/dist/__tests__/e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e.test.js +121 -0
- package/dist/__tests__/e2e.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +86 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/execution.test.d.ts +2 -0
- package/dist/__tests__/execution.test.d.ts.map +1 -0
- package/dist/__tests__/execution.test.js +792 -0
- package/dist/__tests__/execution.test.js.map +1 -0
- package/dist/__tests__/getModesTool.test.d.ts +2 -0
- package/dist/__tests__/getModesTool.test.d.ts.map +1 -0
- package/dist/__tests__/getModesTool.test.js +47 -0
- package/dist/__tests__/getModesTool.test.js.map +1 -0
- package/dist/__tests__/helpTool.test.d.ts +2 -0
- package/dist/__tests__/helpTool.test.d.ts.map +1 -0
- package/dist/__tests__/helpTool.test.js +18 -0
- package/dist/__tests__/helpTool.test.js.map +1 -0
- package/dist/__tests__/listPersonasTool.test.d.ts +2 -0
- package/dist/__tests__/listPersonasTool.test.d.ts.map +1 -0
- package/dist/__tests__/listPersonasTool.test.js +110 -0
- package/dist/__tests__/listPersonasTool.test.js.map +1 -0
- package/dist/__tests__/logger.test.d.ts +2 -0
- package/dist/__tests__/logger.test.d.ts.map +1 -0
- package/dist/__tests__/logger.test.js +56 -0
- package/dist/__tests__/logger.test.js.map +1 -0
- package/dist/__tests__/observability.test.d.ts +2 -0
- package/dist/__tests__/observability.test.d.ts.map +1 -0
- package/dist/__tests__/observability.test.js +60 -0
- package/dist/__tests__/observability.test.js.map +1 -0
- package/dist/__tests__/parser.test.d.ts +2 -0
- package/dist/__tests__/parser.test.d.ts.map +1 -0
- package/dist/__tests__/parser.test.js +259 -0
- package/dist/__tests__/parser.test.js.map +1 -0
- package/dist/__tests__/persona_creation_debug.test.d.ts +2 -0
- package/dist/__tests__/persona_creation_debug.test.d.ts.map +1 -0
- package/dist/__tests__/persona_creation_debug.test.js +56 -0
- package/dist/__tests__/persona_creation_debug.test.js.map +1 -0
- package/dist/__tests__/resetPersonasWizard.test.d.ts +2 -0
- package/dist/__tests__/resetPersonasWizard.test.d.ts.map +1 -0
- package/dist/__tests__/resetPersonasWizard.test.js +74 -0
- package/dist/__tests__/resetPersonasWizard.test.js.map +1 -0
- package/dist/__tests__/reviewContentWizard.test.d.ts +2 -0
- package/dist/__tests__/reviewContentWizard.test.d.ts.map +1 -0
- package/dist/__tests__/reviewContentWizard.test.js +148 -0
- package/dist/__tests__/reviewContentWizard.test.js.map +1 -0
- package/dist/__tests__/sanitize.test.d.ts +2 -0
- package/dist/__tests__/sanitize.test.d.ts.map +1 -0
- package/dist/__tests__/sanitize.test.js +138 -0
- package/dist/__tests__/sanitize.test.js.map +1 -0
- package/dist/__tests__/server.test.d.ts +2 -0
- package/dist/__tests__/server.test.d.ts.map +1 -0
- package/dist/__tests__/server.test.js +49 -0
- package/dist/__tests__/server.test.js.map +1 -0
- package/dist/execution/aggregator.d.ts +43 -0
- package/dist/execution/aggregator.d.ts.map +1 -0
- package/dist/execution/aggregator.js +132 -0
- package/dist/execution/aggregator.js.map +1 -0
- package/dist/execution/base.d.ts +62 -0
- package/dist/execution/base.d.ts.map +1 -0
- package/dist/execution/base.js +5 -0
- package/dist/execution/base.js.map +1 -0
- package/dist/execution/client.d.ts +9 -0
- package/dist/execution/client.d.ts.map +1 -0
- package/dist/execution/client.js +30 -0
- package/dist/execution/client.js.map +1 -0
- package/dist/execution/config.d.ts +30 -0
- package/dist/execution/config.d.ts.map +1 -0
- package/dist/execution/config.js +95 -0
- package/dist/execution/config.js.map +1 -0
- package/dist/execution/index.d.ts +19 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/index.js +151 -0
- package/dist/execution/index.js.map +1 -0
- package/dist/execution/limiter.d.ts +32 -0
- package/dist/execution/limiter.d.ts.map +1 -0
- package/dist/execution/limiter.js +147 -0
- package/dist/execution/limiter.js.map +1 -0
- package/dist/execution/lock.d.ts +17 -0
- package/dist/execution/lock.d.ts.map +1 -0
- package/dist/execution/lock.js +37 -0
- package/dist/execution/lock.js.map +1 -0
- package/dist/execution/modes/direct_api.d.ts +11 -0
- package/dist/execution/modes/direct_api.d.ts.map +1 -0
- package/dist/execution/modes/direct_api.js +213 -0
- package/dist/execution/modes/direct_api.js.map +1 -0
- package/dist/execution/modes/index.d.ts +7 -0
- package/dist/execution/modes/index.d.ts.map +1 -0
- package/dist/execution/modes/index.js +7 -0
- package/dist/execution/modes/index.js.map +1 -0
- package/dist/execution/modes/orchestration.d.ts +11 -0
- package/dist/execution/modes/orchestration.d.ts.map +1 -0
- package/dist/execution/modes/orchestration.js +110 -0
- package/dist/execution/modes/orchestration.js.map +1 -0
- package/dist/execution/modes/sampling.d.ts +9 -0
- package/dist/execution/modes/sampling.d.ts.map +1 -0
- package/dist/execution/modes/sampling.js +66 -0
- package/dist/execution/modes/sampling.js.map +1 -0
- package/dist/execution/parallel.d.ts +16 -0
- package/dist/execution/parallel.d.ts.map +1 -0
- package/dist/execution/parallel.js +90 -0
- package/dist/execution/parallel.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/reviewDispatcherPrompt.d.ts +2 -0
- package/dist/prompts/reviewDispatcherPrompt.d.ts.map +1 -0
- package/dist/prompts/reviewDispatcherPrompt.js +67 -0
- package/dist/prompts/reviewDispatcherPrompt.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +156 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/configureTool.d.ts +17 -0
- package/dist/tools/configureTool.d.ts.map +1 -0
- package/dist/tools/configureTool.js +104 -0
- package/dist/tools/configureTool.js.map +1 -0
- package/dist/tools/configureWizardTool.d.ts +11 -0
- package/dist/tools/configureWizardTool.d.ts.map +1 -0
- package/dist/tools/configureWizardTool.js +205 -0
- package/dist/tools/configureWizardTool.js.map +1 -0
- package/dist/tools/createPersonaTool.d.ts +37 -0
- package/dist/tools/createPersonaTool.d.ts.map +1 -0
- package/dist/tools/createPersonaTool.js +353 -0
- package/dist/tools/createPersonaTool.js.map +1 -0
- package/dist/tools/createPersonaWizardTool.d.ts +13 -0
- package/dist/tools/createPersonaWizardTool.d.ts.map +1 -0
- package/dist/tools/createPersonaWizardTool.js +713 -0
- package/dist/tools/createPersonaWizardTool.js.map +1 -0
- package/dist/tools/deletePersonaTool.d.ts +10 -0
- package/dist/tools/deletePersonaTool.d.ts.map +1 -0
- package/dist/tools/deletePersonaTool.js +75 -0
- package/dist/tools/deletePersonaTool.js.map +1 -0
- package/dist/tools/deletePersonaWizardTool.d.ts +11 -0
- package/dist/tools/deletePersonaWizardTool.d.ts.map +1 -0
- package/dist/tools/deletePersonaWizardTool.js +184 -0
- package/dist/tools/deletePersonaWizardTool.js.map +1 -0
- package/dist/tools/getModesTool.d.ts +12 -0
- package/dist/tools/getModesTool.d.ts.map +1 -0
- package/dist/tools/getModesTool.js +78 -0
- package/dist/tools/getModesTool.js.map +1 -0
- package/dist/tools/helpTool.d.ts +7 -0
- package/dist/tools/helpTool.d.ts.map +1 -0
- package/dist/tools/helpTool.js +65 -0
- package/dist/tools/helpTool.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +30 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/listPersonasTool.d.ts +7 -0
- package/dist/tools/listPersonasTool.d.ts.map +1 -0
- package/dist/tools/listPersonasTool.js +118 -0
- package/dist/tools/listPersonasTool.js.map +1 -0
- package/dist/tools/resetPersonasTool.d.ts +7 -0
- package/dist/tools/resetPersonasTool.d.ts.map +1 -0
- package/dist/tools/resetPersonasTool.js +447 -0
- package/dist/tools/resetPersonasTool.js.map +1 -0
- package/dist/tools/resetPersonasWizardTool.d.ts +9 -0
- package/dist/tools/resetPersonasWizardTool.d.ts.map +1 -0
- package/dist/tools/resetPersonasWizardTool.js +125 -0
- package/dist/tools/resetPersonasWizardTool.js.map +1 -0
- package/dist/tools/reviewContentWizardTool.d.ts +13 -0
- package/dist/tools/reviewContentWizardTool.d.ts.map +1 -0
- package/dist/tools/reviewContentWizardTool.js +411 -0
- package/dist/tools/reviewContentWizardTool.js.map +1 -0
- package/dist/tools/reviewTool.d.ts +10 -0
- package/dist/tools/reviewTool.d.ts.map +1 -0
- package/dist/tools/reviewTool.js +133 -0
- package/dist/tools/reviewTool.js.map +1 -0
- package/dist/tools/types.d.ts +14 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/utils/errors.d.ts +30 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +47 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +18 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/observability.d.ts +61 -0
- package/dist/utils/observability.d.ts.map +1 -0
- package/dist/utils/observability.js +69 -0
- package/dist/utils/observability.js.map +1 -0
- package/dist/utils/parser.d.ts +27 -0
- package/dist/utils/parser.d.ts.map +1 -0
- package/dist/utils/parser.js +178 -0
- package/dist/utils/parser.js.map +1 -0
- package/dist/utils/personaIdMaps.d.ts +7 -0
- package/dist/utils/personaIdMaps.d.ts.map +1 -0
- package/dist/utils/personaIdMaps.js +51 -0
- package/dist/utils/personaIdMaps.js.map +1 -0
- package/dist/utils/sanitize.d.ts +4 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +49 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/dist/utils/types.d.ts +8 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +42 -0
- package/skills/_template.md +66 -0
- package/skills/tmp/wizard-create-cwzrrpim_draft.json +26 -0
- package/skills/tmp/wizard-create-cwzrrpim_wizard.json +26 -0
- package/skills/tmp/wizard-create-d81intme_draft.json +26 -0
- package/skills/tmp/wizard-create-d81intme_wizard.json +26 -0
- package/skills/tmp/wizard-create-g50jqzmh_draft.json +8 -0
- package/skills/tmp/wizard-create-g50jqzmh_wizard.json +8 -0
- package/skills/tmp/wizard-create-onupu9wb_draft.json +8 -0
- package/skills/tmp/wizard-create-onupu9wb_wizard.json +8 -0
- package/skills/tmp/wizard-review-fwbxe3d2_review_wizard.json +9 -0
- package/skills/tmp/wizard-review-sypg5e9d_review_wizard.json +9 -0
- package/skills/wechat_official/wechat_official.md +26 -0
- package/skills/wechat_official/wechat_official_1.md +31 -0
- package/skills/xiaohongshu/xiaohongshu.md +26 -0
- package/skills/xiaohongshu/xiaohongshu_1.md +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# Kevlar — Feedback Simulator Before You Hit Publish
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
🌐 [English](README.md) · [中文](docs/README.zh.md) · [日本語](docs/README.ja.md) · [한국어](docs/README.ko.md)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **It simulates real reactions from different audiences — casual users, picky netizens, technical users, media perspectives — helping you spot expression issues, misunderstandings, and communication risks before you publish.**
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Drop any content you're about to publish — **articles, tweets, video scripts, product intros, press releases, announcements, Reddit posts, V2EX posts, Hacker News headlines** — directly into Kevlar. It won't just say "looks good." Instead, it'll **question, misinterpret, roast, nitpick, and comprehension-test** your content, just like the real internet.
|
|
17
|
+
|
|
18
|
+
Writers often suffer from the **"curse of knowledge"**:
|
|
19
|
+
You think you've made it clear, but others don't get it.
|
|
20
|
+
You think the key point stands out, but readers can't tell what you're trying to say.
|
|
21
|
+
|
|
22
|
+
And most platforms don't offer a real **A/B test**. Once content goes live, by the time the **first wave of organic traffic** passes, it's usually too late to revise.
|
|
23
|
+
|
|
24
|
+
**Kevlar helps you surface these problems before you hit publish.**
|
|
25
|
+
|
|
26
|
+
## Who needs Kevlar
|
|
27
|
+
|
|
28
|
+
**Indie developers** / **Content creators** / **Product teams** / **PR teams** / Heavy users of X, Reddit, V2EX, Hacker News / Anyone who wants to improve content quality and reach
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Core Features
|
|
33
|
+
|
|
34
|
+
### 1. Highly Customizable Virtual Commentators (Persona Customization)
|
|
35
|
+
|
|
36
|
+
Break out of the single-AI perspective with comprehensive persona customization:
|
|
37
|
+
|
|
38
|
+
- **Core attributes**: Age, interests, personality, stance.
|
|
39
|
+
- **Cognition & relationship**: Define blind spots (e.g., domain-specific biases) and social relationship with the author (e.g., a strict mentor, a radical opponent).
|
|
40
|
+
- **Cultural adaptation**: The system automatically detects the language of input content and infers a matching localized cultural context.
|
|
41
|
+
|
|
42
|
+
### 2. Fully Automated Feedback Pipeline
|
|
43
|
+
|
|
44
|
+
- **Smart dispatch**: Paste your work and the AI dispatcher automatically analyzes the content's characteristics.
|
|
45
|
+
- **Precise matching**: Dynamically filters and schedules the most relevant virtual commentators.
|
|
46
|
+
- **Multi-dimensional collision**: Triggers differentiated comments and feedback from diverse stances and professional perspectives.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
Requires **Node.js 20+**.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install # Install dependencies
|
|
56
|
+
npm run build # Compile TypeScript
|
|
57
|
+
npm run setup # Zero-config setup (auto-detect MCP client and write config)
|
|
58
|
+
npm run kevlar-mcp # Interactive install CLI (manually select client)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Once installed, restart your AI client to start using Kevlar. Supports auto-configuration for:
|
|
62
|
+
|
|
63
|
+
**Claude Desktop** / **Cursor** / **Windsurf** / **OpenCode** / **Codex** / **Antigravity** / **CodeBuddy CN** / **WorkBuddy**
|
|
64
|
+
|
|
65
|
+
Local development:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm run dev
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Production start:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm start
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Usage Guide
|
|
80
|
+
|
|
81
|
+
### Core Workflow
|
|
82
|
+
|
|
83
|
+
All core operations in Kevlar are handled through Wizard tools — just tell the AI what you want in natural language, and Kevlar takes care of the rest.
|
|
84
|
+
|
|
85
|
+
### Recommended Tool Flow
|
|
86
|
+
|
|
87
|
+
| Wizard Tool | Purpose | Key Behavior |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| `review_content_wizard` | Review content | Submit content → Select platform → Pick commentators → Confirm → Multi-dimensional feedback |
|
|
90
|
+
| `create_persona_wizard` | Create a persona | Describe the role → Fill 6 attributes (age/interests/traits/tone/platform/relation) → Preview → Confirm → Save persona |
|
|
91
|
+
| `delete_persona_wizard` | Delete a persona | Select target → Reply `确认删除{persona name}` → Done |
|
|
92
|
+
| `configure_wizard` | Modify config | Preview changes → Reply `确认修改配置` → Write |
|
|
93
|
+
|
|
94
|
+
Low-level direct tools (suitable for automation scripts):
|
|
95
|
+
|
|
96
|
+
| Tool | Purpose |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `delete_persona` | Delete persona directly (requires `confirm: true`) |
|
|
99
|
+
| `configure` | Write config directly |
|
|
100
|
+
| `get_execution_modes` | Check current mode and availability |
|
|
101
|
+
| `list_personas` | List local personas |
|
|
102
|
+
| `kevlar_help` | View help |
|
|
103
|
+
|
|
104
|
+
### Content Review Flow
|
|
105
|
+
|
|
106
|
+
`review_content_wizard` chains "save content, select commentators, confirm execution" into a stable flow.
|
|
107
|
+
|
|
108
|
+
```mermaid
|
|
109
|
+
flowchart TD
|
|
110
|
+
A["Submit content for review"] --> B{"Any personas?"}
|
|
111
|
+
B -->|No| C["Prompt to create persona, save state"]
|
|
112
|
+
C -.->|"Same sessionId"| B
|
|
113
|
+
B -->|Yes| D["Collect target platform"]
|
|
114
|
+
D --> E["Filter personas by platform"]
|
|
115
|
+
E --> F{"Count matched"}
|
|
116
|
+
F -->|"≤2"| G["Show matched personas"]
|
|
117
|
+
F -->|"3+"| H["AI recommend 1-3 personas"]
|
|
118
|
+
G --> I["Confirm selection"]
|
|
119
|
+
H --> I
|
|
120
|
+
I --> J["Token cost estimate"]
|
|
121
|
+
J --> K{"Confirm?"}
|
|
122
|
+
K -->|Yes| L["Execute review"]
|
|
123
|
+
K -->|No| I
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Creating a Commentator Persona
|
|
127
|
+
|
|
128
|
+
`create_persona_wizard` guides you through persona creation step by step.
|
|
129
|
+
|
|
130
|
+
```mermaid
|
|
131
|
+
flowchart LR
|
|
132
|
+
A["Age range"] --> B["Interests"]
|
|
133
|
+
B --> C["Personality traits"]
|
|
134
|
+
C --> D["Tone of voice"]
|
|
135
|
+
D --> E["Platforms"]
|
|
136
|
+
E --> F["Author relation"]
|
|
137
|
+
F --> G["Final confirmation & preview"]
|
|
138
|
+
G -->|Confirm| H["Save persona"]
|
|
139
|
+
G -->|Edit| G
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
After creation, Kevlar automatically infers the cultural background, relationship with author, stance, and blind spots, saving them to `skills/*.md`.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Execution Modes
|
|
147
|
+
|
|
148
|
+
Kevlar supports three execution modes. The default `auto` selects the best mode based on your environment.
|
|
149
|
+
|
|
150
|
+
| Mode | Identifier | Description | Best for |
|
|
151
|
+
| --- | --- | --- | --- |
|
|
152
|
+
| MCP Sampling | `mcp_sampling` | Each commentator gets an independent sampling request, maximum isolation | Clients that support Sampling, pursuing authentic multi-perspective review |
|
|
153
|
+
| Direct API | `direct_api` | Directly calls external model API | Clients without Sampling, or script automation |
|
|
154
|
+
| Orchestration (Host-assisted fallback) | `orchestration` | Host AI assists completion, low-isolation fallback | Last resort when neither Sampling nor API Key is available |
|
|
155
|
+
|
|
156
|
+
`auto` mode resolution order:
|
|
157
|
+
|
|
158
|
+
1. Uses the mode specified in `skills/kevlar-config.json` (if set)
|
|
159
|
+
2. Otherwise reads the `KEVLAR_MODE` environment variable
|
|
160
|
+
3. Otherwise auto-selects by availability: `mcp_sampling` → `direct_api` → `orchestration`
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Configuration
|
|
165
|
+
|
|
166
|
+
### Runtime Configuration
|
|
167
|
+
|
|
168
|
+
Use `configure_wizard` to modify runtime preferences. Configuration is written to `skills/kevlar-config.json` (local only, not committed to the repository).
|
|
169
|
+
|
|
170
|
+
```json
|
|
171
|
+
{
|
|
172
|
+
"mode": "auto",
|
|
173
|
+
"multiAgent": {
|
|
174
|
+
"maxConcurrency": 3
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Environment Variables
|
|
180
|
+
|
|
181
|
+
| Variable | Default | Description |
|
|
182
|
+
| --- | --- | --- |
|
|
183
|
+
| `KEVLAR_MODE` | `auto` | `auto`, `orchestration`, `mcp_sampling`, `direct_api` |
|
|
184
|
+
| `KEVLAR_MAX_CONCURRENT` | `3` | Max concurrent commentators |
|
|
185
|
+
| `KEVLAR_TOKEN_BUDGET_PER_TASK` | `50000` | Token budget per review task |
|
|
186
|
+
| `KEVLAR_MIN_DELAY_MS` | `1000` | Minimum delay between requests |
|
|
187
|
+
| `KEVLAR_SKILLS_DIR` | `<repo>/skills` | Custom persona and config directory |
|
|
188
|
+
| `KEVLAR_API_KEY` | — | Preferred Direct API key |
|
|
189
|
+
| `ANTHROPIC_API_KEY` | — | Anthropic API key |
|
|
190
|
+
| `OPENAI_API_KEY` | — | OpenAI API key |
|
|
191
|
+
| `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error` |
|
|
192
|
+
|
|
193
|
+
> API keys are read from environment variables only — they are never written to config files.
|
|
194
|
+
|
|
195
|
+
### Manual MCP Client Configuration
|
|
196
|
+
|
|
197
|
+
Claude Desktop example:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"mcpServers": {
|
|
202
|
+
"kevlar": {
|
|
203
|
+
"command": "node",
|
|
204
|
+
"args": ["/ABSOLUTE/PATH/TO/kevlar/dist/index.js"],
|
|
205
|
+
"env": {
|
|
206
|
+
"KEVLAR_MODE": "auto",
|
|
207
|
+
"KEVLAR_MAX_CONCURRENT": "3"
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Custom persona directory:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"env": {
|
|
219
|
+
"KEVLAR_SKILLS_DIR": "/ABSOLUTE/PATH/TO/skills"
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Security Boundaries
|
|
227
|
+
|
|
228
|
+
- `sessionId` only allows `[a-z0-9-]`.
|
|
229
|
+
- Persona write and delete operations are restricted to the `skills/` directory via path validation.
|
|
230
|
+
- Runtime drafts and wizard states are stored in `skills/tmp/`, with expired drafts cleaned up on startup.
|
|
231
|
+
- Deleting a persona requires selecting a target and replying with the full confirmation phrase.
|
|
232
|
+
- Config changes require preview before confirmation.
|
|
233
|
+
- API keys are never passed via tool parameters or written to local config.
|
|
234
|
+
- Non-`orchestration` modes use a review lock to prevent resource contention between multiple external model tasks.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Architecture Overview
|
|
239
|
+
|
|
240
|
+
Kevlar uses a **Server-side Workflow + Execution Layer** architecture.
|
|
241
|
+
|
|
242
|
+
```mermaid
|
|
243
|
+
flowchart TD
|
|
244
|
+
User["User"] --> Client["MCP Client / Host AI"]
|
|
245
|
+
Client --> Tools["Kevlar MCP Tools"]
|
|
246
|
+
Tools --> Wizards["Server-side State Machine Wizards"]
|
|
247
|
+
Tools --> Execution["Multi-mode Execution Layer"]
|
|
248
|
+
Wizards --> Tmp["skills/tmp Session State"]
|
|
249
|
+
Execution --> Personas["skills/*.md Commentator Personas"]
|
|
250
|
+
Execution --> Report["Structured Review Report"]
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Design principles:
|
|
254
|
+
|
|
255
|
+
- **State machine-driven workflows**: Key flows are maintained by tool state machines, not dependent on the host AI remembering long prompts.
|
|
256
|
+
- **AI handles understanding & expression**: AI handles natural language extraction, refinement, and recommendations, while results are written to Kevlar-verifiable state.
|
|
257
|
+
- **Adaptive execution**: When MCP Sampling is available, use it for field extraction and commentator recommendations; otherwise, fall back to heuristic logic or host-assisted orchestration.
|
|
258
|
+
- **Safe confirmation**: High-risk operations like deletion, reset, and config writes all go through confirmation wizards.
|
|
259
|
+
|
|
260
|
+
### Directory Structure
|
|
261
|
+
|
|
262
|
+
```text
|
|
263
|
+
kevlar/
|
|
264
|
+
├── config/
|
|
265
|
+
│ └── mcp-config.json # MCP client config template
|
|
266
|
+
├── docs/ # Architecture design, audit reports
|
|
267
|
+
├── scripts/ # Install & config scripts
|
|
268
|
+
│ ├── cli.ts # Interactive install CLI
|
|
269
|
+
│ ├── registry.ts # MCP client detection
|
|
270
|
+
│ └── setup.ts # Zero-config setup script
|
|
271
|
+
├── skills/ # Commentator persona library
|
|
272
|
+
│ ├── _template.md # Persona template
|
|
273
|
+
│ └── tmp/ # Runtime wizard session state
|
|
274
|
+
├── src/
|
|
275
|
+
│ ├── index.ts # stdio server entry
|
|
276
|
+
│ ├── server.ts # MCP server, DI, tool registration
|
|
277
|
+
│ ├── __tests__/ # Test suite
|
|
278
|
+
│ ├── execution/ # Multi-mode execution layer
|
|
279
|
+
│ │ ├── index.ts # Execution entry, mode resolution
|
|
280
|
+
│ │ ├── base.ts # Type definitions & interfaces
|
|
281
|
+
│ │ ├── client.ts # Client capability detection
|
|
282
|
+
│ │ ├── config.ts # Config read/write
|
|
283
|
+
│ │ ├── aggregator.ts # Review report aggregation
|
|
284
|
+
│ │ ├── limiter.ts # Concurrency limiting & retry
|
|
285
|
+
│ │ ├── lock.ts # Review lock
|
|
286
|
+
│ │ ├── parallel.ts # Shared parallel execution
|
|
287
|
+
│ │ └── modes/
|
|
288
|
+
│ │ ├── orchestration.ts
|
|
289
|
+
│ │ ├── sampling.ts
|
|
290
|
+
│ │ └── direct_api.ts
|
|
291
|
+
│ ├── tools/ # MCP tools
|
|
292
|
+
│ │ ├── index.ts # Tool registry
|
|
293
|
+
│ │ ├── listPersonasTool.ts
|
|
294
|
+
│ │ ├── createPersonaTool.ts # Create persona + draft management
|
|
295
|
+
│ │ ├── createPersonaWizardTool.ts
|
|
296
|
+
│ │ ├── deletePersonaTool.ts
|
|
297
|
+
│ │ ├── deletePersonaWizardTool.ts
|
|
298
|
+
│ │ ├── reviewTool.ts
|
|
299
|
+
│ │ ├── reviewContentWizardTool.ts
|
|
300
|
+
│ │ ├── configureTool.ts
|
|
301
|
+
│ │ ├── configureWizardTool.ts
|
|
302
|
+
│ │ ├── getModesTool.ts
|
|
303
|
+
│ │ └── helpTool.ts
|
|
304
|
+
│ ├── prompts/
|
|
305
|
+
│ │ └── reviewDispatcherPrompt.ts # Internal design reference
|
|
306
|
+
│ └── utils/
|
|
307
|
+
│ ├── errors.ts # Error codes & formatting
|
|
308
|
+
│ ├── logger.ts # Structured logging
|
|
309
|
+
│ ├── parser.ts # Persona file parsing & writing
|
|
310
|
+
│ ├── sanitize.ts # Credential scanning, prompt boundary handling
|
|
311
|
+
│ └── ...
|
|
312
|
+
└── package.json
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Contributing Commentator Personas
|
|
318
|
+
|
|
319
|
+
Add a subdirectory and `.md` file under `skills/` by platform (or place it directly in the `skills/` root). Custom persona files are excluded by `.gitignore` by default and will not be committed to the repository.
|
|
320
|
+
|
|
321
|
+
Refer to the template `skills/_template.md`:
|
|
322
|
+
|
|
323
|
+
```markdown
|
|
324
|
+
---
|
|
325
|
+
id: your_persona_id
|
|
326
|
+
name: Display name
|
|
327
|
+
description: One-line description of what this commentator focuses on
|
|
328
|
+
tags:
|
|
329
|
+
- Platform
|
|
330
|
+
- Interest
|
|
331
|
+
author: custom
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
Age range:
|
|
335
|
+
Interests:
|
|
336
|
+
Platforms:
|
|
337
|
+
Personality traits:
|
|
338
|
+
- Trait → Behavior
|
|
339
|
+
|
|
340
|
+
Cultural background:
|
|
341
|
+
Relationship with author:
|
|
342
|
+
Stance:
|
|
343
|
+
Blind spots:
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Custom personas undergo field completeness validation before participating in reviews. At minimum, platforms, personality traits, blind spots, and similar information must be parseable or present in the description.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Pre-Release Checklist
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
npm run build
|
|
354
|
+
npm test
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Before release, it is recommended to hand [docs/PRE_RELEASE_AUDIT_REQUEST.md](docs/PRE_RELEASE_AUDIT_REQUEST.md) to your local AI for an independent audit.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configureWizard.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/configureWizard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as os from "os";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import { setConfigPath, readConfig } from "../execution/config.js";
|
|
7
|
+
import { handleConfigureWizard } from "../tools/configureWizardTool.js";
|
|
8
|
+
import { handleConfigure } from "../tools/configureTool.js";
|
|
9
|
+
let skillsDir;
|
|
10
|
+
let tmpDir;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
skillsDir = fs.mkdtempSync(path.join(os.tmpdir(), "kevlar-config-wizard-"));
|
|
13
|
+
tmpDir = path.join(skillsDir, "tmp");
|
|
14
|
+
setConfigPath(skillsDir);
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
fs.rmSync(skillsDir, { recursive: true, force: true });
|
|
18
|
+
});
|
|
19
|
+
function textOf(result) {
|
|
20
|
+
return result.content.map((c) => c.text).join("\n");
|
|
21
|
+
}
|
|
22
|
+
function extractSessionId(text) {
|
|
23
|
+
const match = text.match(/sessionId:\s*([a-z0-9-]+)/);
|
|
24
|
+
assert.ok(match, `expected sessionId in response: ${text}`);
|
|
25
|
+
return match[1];
|
|
26
|
+
}
|
|
27
|
+
describe("handleConfigureWizard", () => {
|
|
28
|
+
it("previews config changes without writing until confirmation", async () => {
|
|
29
|
+
const result = await handleConfigureWizard(tmpDir, {
|
|
30
|
+
userMessage: "切换到 direct api,并发 4",
|
|
31
|
+
});
|
|
32
|
+
const text = textOf(result);
|
|
33
|
+
assert.ok(text.includes("准备修改配置"));
|
|
34
|
+
assert.ok(text.includes("执行模式:直接 API 模式"));
|
|
35
|
+
assert.ok(text.includes("并发数:4"));
|
|
36
|
+
assert.ok(text.includes("currentStep: confirmConfigure"));
|
|
37
|
+
const config = readConfig();
|
|
38
|
+
assert.equal(config.mode, "auto");
|
|
39
|
+
assert.equal(config.multiAgent.maxConcurrency, 3);
|
|
40
|
+
});
|
|
41
|
+
it("writes config only after exact confirmation phrase", async () => {
|
|
42
|
+
const started = await handleConfigureWizard(tmpDir, {
|
|
43
|
+
userMessage: "切换到 mcp sampling,并发 5",
|
|
44
|
+
});
|
|
45
|
+
const sessionId = extractSessionId(textOf(started));
|
|
46
|
+
const wrong = await handleConfigureWizard(tmpDir, {
|
|
47
|
+
sessionId,
|
|
48
|
+
userMessage: "确认",
|
|
49
|
+
});
|
|
50
|
+
assert.ok(textOf(wrong).includes("请回复完整确认语"));
|
|
51
|
+
assert.equal(readConfig().mode, "auto");
|
|
52
|
+
const applied = await handleConfigureWizard(tmpDir, {
|
|
53
|
+
sessionId,
|
|
54
|
+
userMessage: "确认修改配置",
|
|
55
|
+
});
|
|
56
|
+
assert.ok(textOf(applied).includes("配置已更新"));
|
|
57
|
+
assert.equal(readConfig().mode, "mcp_sampling");
|
|
58
|
+
assert.equal(readConfig().multiAgent.maxConcurrency, 5);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("handleConfigure (direct tool)", () => {
|
|
62
|
+
it("rejects invalid mode", async () => {
|
|
63
|
+
const result = await handleConfigure({ mode: "invalid_mode" });
|
|
64
|
+
assert.ok(result.isError);
|
|
65
|
+
assert.ok(result.content[0]?.text.includes("无效的执行模式"));
|
|
66
|
+
});
|
|
67
|
+
it("rejects invalid concurrency out of range", async () => {
|
|
68
|
+
const resultLow = await handleConfigure({ maxConcurrency: 0 });
|
|
69
|
+
assert.ok(resultLow.isError);
|
|
70
|
+
assert.ok(resultLow.content[0]?.text.includes("并发数必须在 1-10"));
|
|
71
|
+
const resultHigh = await handleConfigure({ maxConcurrency: 11 });
|
|
72
|
+
assert.ok(resultHigh.isError);
|
|
73
|
+
assert.ok(resultHigh.content[0]?.text.includes("并发数必须在 1-10"));
|
|
74
|
+
});
|
|
75
|
+
it("writes mode and preserves existing config", async () => {
|
|
76
|
+
await handleConfigure({ mode: "orchestration" });
|
|
77
|
+
assert.equal(readConfig().mode, "orchestration");
|
|
78
|
+
// Partial update preserves previous value
|
|
79
|
+
await handleConfigure({ maxConcurrency: 7 });
|
|
80
|
+
assert.equal(readConfig().mode, "orchestration");
|
|
81
|
+
assert.equal(readConfig().multiAgent.maxConcurrency, 7);
|
|
82
|
+
});
|
|
83
|
+
it("returns success message for valid config", async () => {
|
|
84
|
+
const result = await handleConfigure({ mode: "mcp_sampling", maxConcurrency: 5 });
|
|
85
|
+
assert.ok(!result.isError);
|
|
86
|
+
assert.ok(result.content[0]?.text.includes("配置已更新"));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=configureWizard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configureWizard.test.js","sourceRoot":"","sources":["../../src/__tests__/configureWizard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createPersonaTool.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/createPersonaTool.test.ts"],"names":[],"mappings":""}
|