@vpxa/kb 0.1.12 → 0.1.13
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 +48 -37
- package/package.json +1 -1
- package/packages/analyzers/dist/entry-point-analyzer.d.ts +18 -0
- package/packages/analyzers/dist/entry-point-analyzer.js +6 -5
- package/packages/analyzers/dist/pattern-analyzer.js +1 -1
- package/packages/analyzers/dist/types.d.ts +1 -1
- package/packages/cli/dist/commands/init.d.ts +2 -1
- package/packages/cli/dist/commands/init.js +242 -183
- package/packages/cli/dist/commands/knowledge.js +1 -1
- package/packages/cli/dist/commands/system.js +6 -3
- package/packages/cli/dist/helpers.js +5 -3
- package/packages/core/dist/content-detector.d.ts +5 -1
- package/packages/core/dist/content-detector.js +1 -1
- package/packages/core/dist/index.d.ts +1 -1
- package/packages/core/dist/index.js +1 -1
- package/packages/core/dist/types.d.ts +2 -0
- package/packages/server/dist/server.js +1 -1
- package/packages/server/dist/tools/analyze.tools.js +3 -1
- package/packages/server/dist/tools/audit.tool.d.ts +5 -0
- package/packages/server/dist/tools/audit.tool.js +4 -0
- package/packages/server/dist/tools/replay.tool.js +4 -4
- package/packages/server/dist/tools/search.tool.js +18 -14
- package/packages/server/dist/tools/status.tool.js +3 -3
- package/packages/server/dist/tools/toolkit.tools.d.ts +1 -1
- package/packages/server/dist/tools/toolkit.tools.js +23 -20
- package/packages/store/dist/lance-store.js +1 -1
- package/packages/store/dist/store.interface.d.ts +2 -0
- package/packages/tools/dist/audit.d.ts +66 -0
- package/packages/tools/dist/audit.js +7 -0
- package/packages/tools/dist/check.d.ts +19 -0
- package/packages/tools/dist/check.js +2 -2
- package/packages/tools/dist/compact.d.ts +4 -2
- package/packages/tools/dist/compact.js +2 -2
- package/packages/tools/dist/dead-symbols.d.ts +9 -1
- package/packages/tools/dist/dead-symbols.js +2 -2
- package/packages/tools/dist/forge-classify.js +1 -1
- package/packages/tools/dist/guide.d.ts +23 -0
- package/packages/tools/dist/guide.js +1 -0
- package/packages/tools/dist/health.js +2 -1
- package/packages/tools/dist/index.d.ts +6 -2
- package/packages/tools/dist/index.js +1 -1
- package/packages/tools/dist/path-resolver.d.ts +12 -0
- package/packages/tools/dist/path-resolver.js +1 -0
- package/packages/tools/dist/replay.d.ts +1 -1
- package/packages/tools/dist/response-envelope.d.ts +41 -0
- package/packages/tools/dist/response-envelope.js +1 -0
- package/packages/tools/dist/scope-map.d.ts +2 -0
- package/packages/tools/dist/scope-map.js +1 -1
- package/packages/tools/dist/truncation.d.ts +9 -0
- package/packages/tools/dist/truncation.js +8 -8
- package/packages/tui/dist/App.js +109 -109
- package/packages/tui/dist/index.js +116 -116
- package/packages/tui/dist/panels/LogPanel.js +100 -100
- package/skills/knowledge-base/SKILL.md +19 -19
|
@@ -1,147 +1,92 @@
|
|
|
1
|
-
import{appendFileSync as
|
|
2
|
-
|
|
3
|
-
This project uses **@vpxa/kb** as an MCP knowledge base server.
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
|
39
|
-
|
|
40
|
-
| \`
|
|
41
|
-
| \`
|
|
42
|
-
| \`
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
| \`kb_parse_output\` | Parse build tool output (tsc, vitest, biome, git) into structured JSON. |
|
|
91
|
-
|
|
92
|
-
### FORGE & Context Compression
|
|
93
|
-
| Tool | Purpose |
|
|
94
|
-
|------|---------|
|
|
95
|
-
| \`kb_forge_ground\` | Full FORGE Ground phase (classify + scope + constraints + evidence). |
|
|
96
|
-
| \`kb_forge_classify\` | Quick FORGE tier classification (Floor/Standard/Critical). |
|
|
97
|
-
| \`kb_evidence_map\` | Track critical-path claims as Verified/Assumed/Unknown with receipts. |
|
|
98
|
-
| \`kb_digest\` | Compress multiple text blocks into token-budgeted digest. |
|
|
99
|
-
| \`kb_stratum_card\` | Generate T1/T2 context cards (10-100x token reduction). |
|
|
100
|
-
|
|
101
|
-
### Web & Network
|
|
102
|
-
| Tool | Purpose |
|
|
103
|
-
|------|---------|
|
|
104
|
-
| \`kb_web_fetch\` | Fetch web page \u2192 LLM-optimized markdown. CSS selectors, 4 modes, smart truncation. |
|
|
105
|
-
| \`kb_web_search\` | Search the web via DuckDuckGo (no API key needed). |
|
|
106
|
-
| \`kb_http\` | HTTP requests (GET/POST/PUT/PATCH/DELETE) for API testing with timing. |
|
|
107
|
-
|
|
108
|
-
### Verified Lanes
|
|
109
|
-
| Tool | Purpose |
|
|
110
|
-
|------|---------|
|
|
111
|
-
| \`kb_lane\` | Manage isolated file copies for parallel exploration. Actions: \`create\`, \`list\`, \`status\`, \`diff\`, \`merge\`, \`discard\`. |
|
|
112
|
-
|
|
113
|
-
### Git & Environment
|
|
114
|
-
| Tool | Purpose |
|
|
115
|
-
|------|---------|
|
|
116
|
-
| \`kb_git_context\` | Branch, status, recent commits, optional diff stats. |
|
|
117
|
-
| \`kb_process\` | Process supervisor (start/stop/logs). |
|
|
118
|
-
| \`kb_watch\` | Filesystem watcher for auto-triggered workflows. |
|
|
119
|
-
| \`kb_delegate\` | Delegate subtask to a local Ollama model. |
|
|
120
|
-
|
|
121
|
-
### Developer Utilities
|
|
122
|
-
| Tool | Purpose |
|
|
123
|
-
|------|---------|
|
|
124
|
-
| \`kb_regex_test\` | Test regex patterns with match/replace/split modes. |
|
|
125
|
-
| \`kb_encode\` | Base64, URL, SHA-256, MD5, hex encode/decode, JWT decode. |
|
|
126
|
-
| \`kb_measure\` | Code complexity metrics (cyclomatic complexity, line counts). |
|
|
127
|
-
| \`kb_changelog\` | Generate changelog from git history (conventional commits). |
|
|
128
|
-
| \`kb_schema_validate\` | Validate JSON data against JSON Schema. |
|
|
129
|
-
| \`kb_snippet\` | Save/get/search/delete persistent code snippets. |
|
|
130
|
-
| \`kb_env\` | System and runtime environment info (sensitive values redacted). |
|
|
131
|
-
| \`kb_time\` | Date parsing, timezone conversion, duration math. |
|
|
132
|
-
|
|
133
|
-
### System
|
|
134
|
-
| Tool | Purpose |
|
|
135
|
-
|------|---------|
|
|
136
|
-
| \`kb_status\` | Index statistics (record count, file count, content types). |
|
|
137
|
-
| \`kb_reindex\` | Rebuild the vector index from configured sources. |
|
|
138
|
-
| \`kb_health\` | Project health checks (package.json, tsconfig, lockfile, etc.). |
|
|
139
|
-
| \`kb_onboard\` | First-time codebase onboarding \u2014 runs all analyses, auto-persists results. |
|
|
140
|
-
| \`kb_graph\` | Knowledge graph queries (find_nodes, find_edges, neighbors, traverse, stats). |
|
|
141
|
-
| \`kb_queue\` | Task queue for sequential agent operations. |
|
|
142
|
-
| \`kb_replay_list\` | View audit trail of tool invocations. |
|
|
143
|
-
| \`kb_replay_clear\` | Clear the replay audit trail. |
|
|
144
|
-
`}function w(e){return`# ${e} \u2014 Agent Instructions
|
|
1
|
+
import{appendFileSync as h,copyFileSync as y,existsSync as t,mkdirSync as n,readFileSync as v,writeFileSync as r}from"node:fs";import{basename as w,dirname as S,resolve as e}from"node:path";import{fileURLToPath as x}from"node:url";const C={sources:[{path:".",excludePatterns:["**/node_modules/**","**/dist/**","**/build/**","**/.git/**","**/.kb-data/**","**/coverage/**","**/*.min.js","**/package-lock.json","**/pnpm-lock.yaml"]}],indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:"mixedbread-ai/mxbai-embed-large-v1",dimensions:1024},store:{backend:"lancedb",path:".kb-data/lance"},curated:{path:"curated"}};function A(o){return{servers:{[`${o}-kb`]:{type:"stdio",command:"npx",args:["@vpxa/kb","serve"]}}}}function T(o){return`# ${o} \u2014 Copilot Instructions
|
|
2
|
+
|
|
3
|
+
This project uses **@vpxa/kb** as an MCP knowledge base server. The KB provides search, context compression, persistent memory, and validation tools that **MUST** be used to maintain quality and performance.
|
|
4
|
+
|
|
5
|
+
## Mandatory Rules
|
|
6
|
+
|
|
7
|
+
### 1. ALWAYS search before acting
|
|
8
|
+
Before writing or modifying code, you MUST recall prior decisions and understand the affected area:
|
|
9
|
+
\`\`\`
|
|
10
|
+
kb_search({ query: "<task keywords>" })
|
|
11
|
+
kb_scope_map({ task: "<what you are doing>" })
|
|
12
|
+
\`\`\`
|
|
13
|
+
|
|
14
|
+
### 2. ALWAYS compress context before reading large files
|
|
15
|
+
Do NOT read entire files into context. Use these tools to reduce tokens and focus on what matters:
|
|
16
|
+
|
|
17
|
+
| Situation | Tool | Why |
|
|
18
|
+
|-----------|------|-----|
|
|
19
|
+
| Need relevant sections of a large file | \`kb_compact\` | Extracts only semantically relevant chunks \u2014 5-20x reduction |
|
|
20
|
+
| Need to summarize multiple sources | \`kb_digest\` | Compresses multiple text blocks into a token-budgeted summary |
|
|
21
|
+
| Need a quick structural overview of a file | \`kb_file_summary\` | Returns exports, imports, functions without reading the full file |
|
|
22
|
+
| Need a reusable context card | \`kb_stratum_card\` | Generates T1/T2 cards \u2014 10-100x token reduction |
|
|
23
|
+
|
|
24
|
+
**Example \u2014 reading a 400-line file:**
|
|
25
|
+
\`\`\`
|
|
26
|
+
# BAD: read_file entire file (wastes ~3000 tokens)
|
|
27
|
+
# GOOD: get structure first, then compact only what you need
|
|
28
|
+
kb_file_summary({ path: "src/http-client.ts" })
|
|
29
|
+
kb_compact({ path: "src/http-client.ts", query: "retry logic" })
|
|
30
|
+
\`\`\`
|
|
31
|
+
|
|
32
|
+
### 3. ALWAYS use persistent memory
|
|
33
|
+
- **Start of session**: Read prior knowledge with \`kb_list()\` and \`kb_search({ query: "SESSION CHECKPOINT", origin: "curated" })\`
|
|
34
|
+
- **During session**: Use \`kb_stash\` for temporary working data, \`kb_checkpoint\` to save progress
|
|
35
|
+
- **End of session**: MUST call \`kb_remember\` to persist decisions, patterns, and lessons learned
|
|
36
|
+
- **Before proposing a new approach**: MUST \`kb_search\` to check if a decision already exists
|
|
37
|
+
|
|
38
|
+
| Tool | When | Persistence |
|
|
39
|
+
|------|------|-------------|
|
|
40
|
+
| \`kb_stash\` | Temporary data within a session (intermediate results, scratch notes) | Session only |
|
|
41
|
+
| \`kb_checkpoint\` | Save/restore session progress (resumable work) | Session only |
|
|
42
|
+
| \`kb_remember\` | Architecture decisions, conventions, patterns, troubleshooting | Permanent (survives reindex) |
|
|
43
|
+
|
|
44
|
+
### 4. ALWAYS validate before committing
|
|
45
|
+
\`\`\`
|
|
46
|
+
kb_check({}) # Typecheck + lint (returns summary by default)
|
|
47
|
+
kb_test_run({}) # Run tests
|
|
48
|
+
kb_blast_radius({ changed_files: ["..."] }) # Impact analysis
|
|
49
|
+
kb_audit({}) # Unified project audit with score and recommendations
|
|
50
|
+
\`\`\`
|
|
51
|
+
|
|
52
|
+
### 5. Use FORGE for complex tasks
|
|
53
|
+
For tasks involving multiple files or architectural decisions:
|
|
54
|
+
\`\`\`
|
|
55
|
+
kb_forge_classify({ task: "<description>" }) # Classify complexity tier
|
|
56
|
+
kb_forge_ground({ task: "<description>" }) # Full analysis: scope + constraints + evidence
|
|
57
|
+
kb_evidence_map({ claims: [...] }) # Track verified vs assumed claims
|
|
58
|
+
\`\`\`
|
|
59
|
+
|
|
60
|
+
## Quick Workflow
|
|
61
|
+
|
|
62
|
+
\`\`\`
|
|
63
|
+
# 1. Orient
|
|
64
|
+
kb_search({ query: "task keywords" })
|
|
65
|
+
kb_scope_map({ task: "what you are doing" })
|
|
66
|
+
|
|
67
|
+
# 2. Read efficiently (NEVER raw-read large files)
|
|
68
|
+
kb_file_summary({ path: "relevant-file.ts" })
|
|
69
|
+
kb_compact({ path: "relevant-file.ts", query: "specific concern" })
|
|
70
|
+
|
|
71
|
+
# 3. Do the work
|
|
72
|
+
|
|
73
|
+
# 4. Validate
|
|
74
|
+
kb_check({})
|
|
75
|
+
kb_test_run({})
|
|
76
|
+
|
|
77
|
+
# 5. Persist
|
|
78
|
+
kb_remember({ title: "What I learned", content: "...", category: "decisions" })
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
## Context Budget Rules
|
|
82
|
+
|
|
83
|
+
- **Prefer \`kb_file_summary\` over \`read_file\`** for understanding file structure
|
|
84
|
+
- **Prefer \`kb_compact\` over full file reads** when you need specific sections (use \`path\` param to avoid read_file round-trip)
|
|
85
|
+
- **Prefer \`kb_search\` over \`grep_search\`** for semantic/conceptual queries
|
|
86
|
+
- **Prefer \`kb_symbol\` over manual grep** for finding definitions and references
|
|
87
|
+
- **Use \`kb_digest\`** when combining information from 3+ sources
|
|
88
|
+
- **Use \`kb_stratum_card\`** to create reusable compressed context for repeated reference
|
|
89
|
+
`}function P(o){return`# ${o} \u2014 Agent Instructions
|
|
145
90
|
|
|
146
91
|
## KB Knowledge Base
|
|
147
92
|
|
|
@@ -157,50 +102,140 @@ This project has a **@vpxa/kb** MCP server providing search, analysis, memory, a
|
|
|
157
102
|
|
|
158
103
|
| Category | Tools | Purpose |
|
|
159
104
|
|----------|-------|---------|
|
|
160
|
-
| Search & Discovery | \`kb_search\`, \`kb_find\`, \`kb_symbol\`, \`kb_trace\`, \`kb_scope_map\`, \`kb_lookup\`, \`
|
|
105
|
+
| Search & Discovery | \`kb_search\`, \`kb_find\`, \`kb_symbol\`, \`kb_trace\`, \`kb_scope_map\`, \`kb_lookup\`, \`kb_dead_symbols\`, \`kb_file_summary\` | Find code, symbols, data flow, reading plans |
|
|
161
106
|
| Code Analysis | \`kb_analyze_structure\`, \`kb_analyze_dependencies\`, \`kb_analyze_symbols\`, \`kb_analyze_patterns\`, \`kb_analyze_entry_points\`, \`kb_analyze_diagram\`, \`kb_blast_radius\` | Structure, deps, patterns, impact, diagrams |
|
|
162
107
|
| Knowledge | \`kb_remember\`, \`kb_read\`, \`kb_update\`, \`kb_forget\`, \`kb_list\`, \`kb_produce_knowledge\` | Persistent cross-session memory |
|
|
163
|
-
| Execution | \`kb_check\`, \`kb_test_run\`, \`kb_eval\`, \`kb_batch\` | Typecheck, lint, test, run code |
|
|
108
|
+
| Execution | \`kb_check\`, \`kb_test_run\`, \`kb_eval\`, \`kb_batch\`, \`kb_audit\` | Typecheck, lint, test, run code, unified audit. \`check\` defaults to summary output (~300 tokens) |
|
|
164
109
|
| Code Manipulation | \`kb_rename\`, \`kb_codemod\`, \`kb_diff_parse\`, \`kb_data_transform\` | Safe renames, transforms, diff parsing |
|
|
165
|
-
| Context | \`kb_compact\`, \`kb_workset\`, \`kb_stash\`, \`kb_checkpoint\`, \`kb_parse_output\` | Manage working sets, save progress |
|
|
110
|
+
| Context | \`kb_compact\`, \`kb_workset\`, \`kb_stash\`, \`kb_checkpoint\`, \`kb_parse_output\` | Manage working sets, save progress. \`compact\` accepts \`path\` for server-side file read |
|
|
166
111
|
| FORGE | \`kb_forge_ground\`, \`kb_forge_classify\`, \`kb_evidence_map\`, \`kb_digest\`, \`kb_stratum_card\` | Quality gates, context compression |
|
|
167
112
|
| Web & API | \`kb_web_fetch\`, \`kb_web_search\`, \`kb_http\` | Fetch pages, search web, test APIs |
|
|
168
113
|
| Lanes | \`kb_lane\` | Isolated file copies for parallel exploration (create/list/status/diff/merge/discard) |
|
|
169
114
|
| Git & Environment | \`kb_git_context\`, \`kb_process\`, \`kb_watch\`, \`kb_delegate\` | Git info, process management |
|
|
170
115
|
| Utilities | \`kb_regex_test\`, \`kb_encode\`, \`kb_measure\`, \`kb_changelog\`, \`kb_schema_validate\`, \`kb_snippet\`, \`kb_env\`, \`kb_time\` | Regex, encoding, metrics, validation |
|
|
171
|
-
| System | \`kb_status\`, \`kb_reindex\`, \`kb_health\`, \`kb_onboard\`, \`kb_graph\`, \`kb_queue\`, \`
|
|
116
|
+
| System | \`kb_status\`, \`kb_reindex\`, \`kb_health\`, \`kb_guide\`, \`kb_onboard\`, \`kb_graph\`, \`kb_queue\`, \`kb_replay\` | Index management, health checks, tool discovery, knowledge graph |
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## MANDATORY: Context Reduction Protocol
|
|
172
121
|
|
|
173
|
-
|
|
122
|
+
**Every agent interaction MUST minimize context window usage.** Raw file reads waste tokens and degrade LLM output quality. Use these tools instead:
|
|
174
123
|
|
|
175
|
-
|
|
124
|
+
### Decision Tree \u2014 How to Read Code
|
|
176
125
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
126
|
+
\`\`\`
|
|
127
|
+
Need to understand a file?
|
|
128
|
+
\u251C\u2500 Just structure? \u2192 kb_file_summary (exports, imports, functions \u2014 ~50 tokens)
|
|
129
|
+
\u251C\u2500 Specific section? \u2192 kb_compact({ path: "file.ts", query: "topic" }) \u2014 5-20x reduction
|
|
130
|
+
\u251C\u2500 Multiple files? \u2192 kb_digest (multi-source compression \u2014 token-budgeted)
|
|
131
|
+
\u251C\u2500 Repeated reference? \u2192 kb_stratum_card (T1/T2 card \u2014 10-100x reduction)
|
|
132
|
+
\u2514\u2500 Full file needed? \u2192 ONLY as last resort, and compact it after reading
|
|
133
|
+
\`\`\`
|
|
134
|
+
|
|
135
|
+
### Rules
|
|
136
|
+
1. **NEVER read a file >100 lines without compressing it first**
|
|
137
|
+
2. **ALWAYS use \`kb_file_summary\` before \`read_file\`** \u2014 often the summary is sufficient
|
|
138
|
+
3. **ALWAYS use \`kb_compact\` when you only need specific sections** of a file (use \`path\` param to read server-side)
|
|
139
|
+
4. **Use \`kb_digest\` when synthesizing from 3+ sources** \u2014 don't accumulate raw text
|
|
140
|
+
5. **Use \`kb_stratum_card\` for files you'll reference repeatedly** in a session
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## MANDATORY: Memory Protocol
|
|
145
|
+
|
|
146
|
+
**Every session MUST read and write persistent memory.** Without this, every conversation starts from zero.
|
|
147
|
+
|
|
148
|
+
### Session Start (MUST do ALL of these)
|
|
149
|
+
\`\`\`
|
|
150
|
+
kb_status({}) # Verify KB is ready
|
|
151
|
+
kb_list() # See what knowledge exists
|
|
152
|
+
kb_search({ query: "SESSION CHECKPOINT", origin: "curated" }) # Resume prior work
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
### During Session
|
|
156
|
+
| Situation | Action |
|
|
157
|
+
|-----------|--------|
|
|
158
|
+
| Found a useful intermediate result | \`kb_stash({ key: "name", value: "data" })\` |
|
|
159
|
+
| Completed a milestone | \`kb_checkpoint({ action: "save", name: "milestone" })\` |
|
|
160
|
+
| Made an architecture decision | \`kb_remember({ title: "...", category: "decisions" })\` |
|
|
161
|
+
| Discovered a pattern or convention | \`kb_remember({ title: "...", category: "patterns" })\` |
|
|
162
|
+
| Found a non-obvious solution | \`kb_remember({ title: "...", category: "troubleshooting" })\` |
|
|
163
|
+
| About to propose a new approach | \`kb_search({ query: "..." })\` \u2014 check if decided before |
|
|
164
|
+
|
|
165
|
+
### Session End (MUST do this)
|
|
166
|
+
\`\`\`
|
|
167
|
+
kb_remember({
|
|
168
|
+
title: "Session checkpoint: <topic>",
|
|
169
|
+
content: "<what was done, decisions made, blockers, next steps>",
|
|
170
|
+
category: "conventions"
|
|
171
|
+
})
|
|
172
|
+
\`\`\`
|
|
173
|
+
|
|
174
|
+
### Memory Decision Tree
|
|
175
|
+
\`\`\`
|
|
176
|
+
Is this data temporary (scratch, intermediate)?
|
|
177
|
+
\u251C\u2500 Yes \u2192 kb_stash (session-scoped key-value)
|
|
178
|
+
\u2514\u2500 No \u2192 Is it resumable progress?
|
|
179
|
+
\u251C\u2500 Yes \u2192 kb_checkpoint (session-scoped snapshot)
|
|
180
|
+
\u2514\u2500 No \u2192 kb_remember (permanent, survives reindex)
|
|
181
|
+
Categories: decisions | patterns | conventions | troubleshooting
|
|
182
|
+
\`\`\`
|
|
180
183
|
|
|
181
|
-
|
|
184
|
+
---
|
|
182
185
|
|
|
183
|
-
|
|
186
|
+
## MANDATORY: Search-Before-Act Protocol
|
|
187
|
+
|
|
188
|
+
**NEVER write or modify code without first searching for context.**
|
|
184
189
|
|
|
185
|
-
**Start of session:**
|
|
186
190
|
\`\`\`
|
|
187
|
-
|
|
188
|
-
kb_search({ query: "
|
|
191
|
+
# Before ANY code change:
|
|
192
|
+
kb_search({ query: "<what you're about to change>" }) # Prior decisions?
|
|
193
|
+
kb_scope_map({ task: "<description>" }) # What files to read?
|
|
194
|
+
kb_symbol({ name: "<key symbol>" }) # Where is it defined/used?
|
|
189
195
|
\`\`\`
|
|
190
196
|
|
|
191
|
-
|
|
197
|
+
If \`kb_search\` returns a prior decision about the topic, you MUST follow it or explicitly explain why you're deviating.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## MANDATORY: Validation Protocol
|
|
202
|
+
|
|
203
|
+
**NEVER commit or present code without validation.**
|
|
204
|
+
|
|
192
205
|
\`\`\`
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
206
|
+
kb_check({}) # Typecheck + lint (tsc + biome)
|
|
207
|
+
kb_test_run({}) # Run tests
|
|
208
|
+
kb_blast_radius({ changed_files: ["..."] }) # Impact analysis
|
|
209
|
+
kb_audit({}) # Unified project audit (structure, deps, patterns, health, dead symbols, entry points)
|
|
196
210
|
\`\`\`
|
|
197
211
|
|
|
198
|
-
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## FORGE Protocol (for complex tasks)
|
|
215
|
+
|
|
216
|
+
For tasks touching 3+ files or involving architectural decisions:
|
|
217
|
+
|
|
199
218
|
\`\`\`
|
|
200
|
-
|
|
219
|
+
kb_forge_classify({ task: "<description>" }) # Quick: Floor/Standard/Critical tier
|
|
220
|
+
kb_forge_ground({ task: "<description>" }) # Full: scope + constraints + evidence
|
|
221
|
+
kb_evidence_map({ claims: ["claim1", "claim2"] }) # Track verified vs assumed
|
|
201
222
|
\`\`\`
|
|
202
223
|
|
|
203
|
-
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Search Modes
|
|
227
|
+
|
|
228
|
+
| Mode | When | Example |
|
|
229
|
+
|------|------|---------|
|
|
230
|
+
| \`hybrid\` (default) | General queries | \`kb_search({ query: "error handling" })\` |
|
|
231
|
+
| \`semantic\` | Conceptual/meaning-based | \`kb_search({ query: "retry with backoff", search_mode: "semantic" })\` |
|
|
232
|
+
| \`keyword\` | Exact identifiers | \`kb_search({ query: "CircuitBreaker", search_mode: "keyword" })\` |
|
|
233
|
+
|
|
234
|
+
Filters: \`origin\` (\`indexed\`/\`curated\`/\`produced\`), \`category\`, \`content_type\`, \`tags\`, \`min_score\`.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Workflow Chains
|
|
204
239
|
|
|
205
240
|
**Codebase onboarding:**
|
|
206
241
|
\`\`\`
|
|
@@ -209,41 +244,65 @@ kb_onboard({ path: "." }) \u2192 kb_produce_knowledge({ path: "src/" }) \u2192 k
|
|
|
209
244
|
|
|
210
245
|
**Planning a task:**
|
|
211
246
|
\`\`\`
|
|
212
|
-
kb_search({ query: "task keywords" })
|
|
247
|
+
kb_search({ query: "task keywords" })
|
|
248
|
+
\u2192 kb_scope_map({ task: "description" })
|
|
249
|
+
\u2192 kb_file_summary for each file in scope
|
|
250
|
+
\u2192 kb_compact({ path: "relevant-file.ts", query: "detail needed" }) for files needing detail
|
|
251
|
+
\u2192 kb_workset({ action: "save", name: "task", files: [...] })
|
|
213
252
|
\`\`\`
|
|
214
253
|
|
|
215
254
|
**Bug investigation:**
|
|
216
255
|
\`\`\`
|
|
217
|
-
kb_parse_output({ output: "<error>" })
|
|
256
|
+
kb_parse_output({ output: "<error>" })
|
|
257
|
+
\u2192 kb_symbol({ name: "failingFn" })
|
|
258
|
+
\u2192 kb_trace({ symbol: "failingFn", direction: "backward" })
|
|
259
|
+
\u2192 kb_blast_radius({ changed_files: ["suspect.ts"] })
|
|
218
260
|
\`\`\`
|
|
219
261
|
|
|
220
262
|
**Safe refactor with lanes:**
|
|
221
263
|
\`\`\`
|
|
222
|
-
kb_lane({ action: "create", name: "refactor", files: [...] })
|
|
264
|
+
kb_lane({ action: "create", name: "refactor", files: [...] })
|
|
265
|
+
\u2192 [make changes]
|
|
266
|
+
\u2192 kb_lane({ action: "diff", name: "refactor" })
|
|
267
|
+
\u2192 kb_check({}) \u2192 kb_test_run({})
|
|
268
|
+
\u2192 kb_lane({ action: "merge", name: "refactor" })
|
|
223
269
|
\`\`\`
|
|
224
270
|
|
|
225
271
|
**After making changes:**
|
|
226
272
|
\`\`\`
|
|
227
|
-
kb_blast_radius({ changed_files: ["src/file.ts"] })
|
|
273
|
+
kb_blast_radius({ changed_files: ["src/file.ts"] })
|
|
274
|
+
\u2192 kb_check({}) \u2192 kb_test_run({})
|
|
275
|
+
\u2192 kb_reindex({})
|
|
276
|
+
\u2192 kb_remember(...)
|
|
228
277
|
\`\`\`
|
|
229
278
|
|
|
230
|
-
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Knowledge Categories
|
|
282
|
+
|
|
283
|
+
| Category | What to store |
|
|
284
|
+
|----------|---------------|
|
|
285
|
+
| \`decisions\` | Architecture choices, trade-offs, rejected alternatives |
|
|
286
|
+
| \`patterns\` | Code patterns, naming conventions, structural patterns |
|
|
287
|
+
| \`conventions\` | Session checkpoints, workflow conventions, team agreements |
|
|
288
|
+
| \`troubleshooting\` | Non-obvious fixes, debugging strategies, workarounds |
|
|
231
289
|
|
|
232
|
-
|
|
290
|
+
---
|
|
233
291
|
|
|
234
|
-
|
|
292
|
+
## Core Rules Summary
|
|
235
293
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
294
|
+
1. **Search KB before proposing anything new** \u2014 prior decisions exist
|
|
295
|
+
2. **Compress context aggressively** \u2014 \`file_summary\` \u2192 \`compact\` \u2192 \`digest\`
|
|
296
|
+
3. **Use persistent memory** \u2014 \`remember\` decisions, \`stash\` temporary data
|
|
297
|
+
4. **Validate before committing** \u2014 \`check\` + \`test_run\` + \`blast_radius\`
|
|
298
|
+
5. **Follow \`_Next:\` hints** in tool responses for guided workflow
|
|
299
|
+
6. **Use FORGE for complex tasks** \u2014 \`forge_classify\` \u2192 \`forge_ground\` \u2192 \`evidence_map\`
|
|
300
|
+
`}async function R(o){const s=process.cwd(),c=e(s,"kb.config.json");if(t(c)&&!o.force){console.log("kb.config.json already exists. Use --force to overwrite.");return}r(c,`${JSON.stringify(C,null,2)}
|
|
301
|
+
`,"utf-8"),console.log(" Created kb.config.json");const d=e(s,"curated");t(d)||(n(d,{recursive:!0}),console.log(" Created curated/"));const a=e(s,".gitignore");t(a)?v(a,"utf-8").includes(".kb-data")||(h(a,`
|
|
243
302
|
# Knowledge base vector store
|
|
244
303
|
.kb-data/
|
|
245
|
-
`,"utf-8"),console.log(" Added .kb-data/ to .gitignore")):(a
|
|
304
|
+
`,"utf-8"),console.log(" Added .kb-data/ to .gitignore")):(r(a,`# Knowledge base vector store
|
|
246
305
|
.kb-data/
|
|
247
|
-
`,"utf-8"),console.log(" Created .gitignore with .kb-data/"));const
|
|
248
|
-
`,"utf-8"),console.log(" Created .vscode/mcp.json"));const
|
|
249
|
-
Knowledge base initialized! Next steps:`),console.log(" kb reindex Index your codebase"),console.log(" kb search Search indexed content"),console.log(" kb serve Start MCP server for IDE integration")}export{
|
|
306
|
+
`,"utf-8"),console.log(" Created .gitignore with .kb-data/"));const i=w(s),l=e(s,".vscode"),k=e(l,"mcp.json");t(l)&&!t(k)&&(r(k,`${JSON.stringify(A(i),null,2)}
|
|
307
|
+
`,"utf-8"),console.log(" Created .vscode/mcp.json"));const u=e(s,".github"),b=e(u,"copilot-instructions.md");t(b)||(n(u,{recursive:!0}),r(b,T(i),"utf-8"),console.log(" Created .github/copilot-instructions.md"));const m=e(s,"AGENTS.md");t(m)||(r(m,P(i),"utf-8"),console.log(" Created AGENTS.md"));const _=e(s,"skills","knowledge-base"),p=e(_,"SKILL.md");if(!t(p)){const f=S(x(import.meta.url)),g=e(f,"..","..","..","skills","knowledge-base","SKILL.md");t(g)&&(n(_,{recursive:!0}),y(g,p),console.log(" Created skills/knowledge-base/SKILL.md"))}console.log(`
|
|
308
|
+
Knowledge base initialized! Next steps:`),console.log(" kb reindex Index your codebase"),console.log(" kb search Search indexed content"),console.log(" kb serve Start MCP server for IDE integration")}export{R as initProject};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{compact as m}from"../../../tools/dist/index.js";import{ctx as
|
|
1
|
+
import{compact as m}from"../../../tools/dist/index.js";import{ctx as l}from"../context.js";import{extractNumFlag as p,extractStrFlag as c,readStdin as g,splitCsv as d}from"../helpers.js";const y=[{name:"remember",description:"Store curated knowledge",usage:"kb remember <title> --category <cat> [--tags tag1,tag2]",run:async e=>{const a=c(e,"--category","").trim(),o=d(c(e,"--tags","")),t=e.shift()?.trim()??"",r=await g(),n=r.trim().length>0?r:e.join(" ").trim();(!t||!a||!n.trim())&&(console.error("Usage: kb remember <title> --category <cat> [--tags tag1,tag2]"),process.exit(1));const{curated:i}=await l(),s=await i.remember(t,n,a,o);console.log("Stored curated entry"),console.log(` Path: ${s.path}`),console.log(` Category: ${a}`),o.length>0&&console.log(` Tags: ${o.join(", ")}`)}},{name:"forget",description:"Remove a curated entry",usage:"kb forget <path> --reason <reason>",run:async e=>{const a=c(e,"--reason","").trim(),o=e.shift()?.trim()??"";(!o||!a)&&(console.error("Usage: kb forget <path> --reason <reason>"),process.exit(1));const{curated:t}=await l(),r=await t.forget(o,a);console.log(`Removed curated entry: ${r.path}`)}},{name:"read",description:"Read a curated entry",usage:"kb read <path>",run:async e=>{const a=e.shift()?.trim()??"";a||(console.error("Usage: kb read <path>"),process.exit(1));const{curated:o}=await l(),t=await o.read(a);console.log(t.title),console.log("\u2500".repeat(60)),console.log(`Path: ${t.path}`),console.log(`Category: ${t.category}`),console.log(`Version: ${t.version}`),console.log(`Tags: ${t.tags.length>0?t.tags.join(", "):"None"}`),console.log(""),console.log(t.content)}},{name:"list",description:"List curated entries",usage:"kb list [--category <cat>] [--tag <tag>]",run:async e=>{const a=c(e,"--category","").trim()||void 0,o=c(e,"--tag","").trim()||void 0,{curated:t}=await l(),r=await t.list({category:a,tag:o});if(r.length===0){console.log("No curated entries found.");return}console.log(`Curated entries (${r.length})`),console.log("\u2500".repeat(60));for(const n of r){console.log(n.path),console.log(` ${n.title}`),console.log(` Category: ${n.category} | Version: ${n.version}`),console.log(` Tags: ${n.tags.length>0?n.tags.join(", "):"None"}`);const i=n.contentPreview.replace(/\s+/g," ").trim();i&&console.log(` Preview: ${i}`),console.log("")}}},{name:"update",description:"Update a curated entry",usage:"kb update <path> --reason <reason>",run:async e=>{const a=c(e,"--reason","").trim(),o=e.shift()?.trim()??"",t=await g();(!o||!a||!t.trim())&&(console.error("Usage: kb update <path> --reason <reason>"),process.exit(1));const{curated:r}=await l(),n=await r.update(o,t,a);console.log("Updated curated entry"),console.log(` Path: ${n.path}`),console.log(` Version: ${n.version}`)}},{name:"compact",description:"Compress text for context",usage:"kb compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]",run:async e=>{const a=p(e,"--max-chars",3e3),o=c(e,"--path","").trim()||void 0,t=c(e,"--segmentation","paragraph"),r=e.join(" ").trim(),n=o?void 0:await g();(!r||!o&&!n?.trim())&&(console.error("Usage: kb compact <query> --path <file> OR cat file | kb compact <query>"),process.exit(1));const{embedder:i}=await l(),s=await m(i,{text:n,path:o,query:r,maxChars:a,segmentation:t});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(""),console.log(s.text)}}];export{y as knowledgeCommands};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import{fork as
|
|
2
|
-
`)};let
|
|
3
|
-
|
|
1
|
+
import{fork as m}from"node:child_process";import{dirname as f,resolve as g}from"node:path";import{fileURLToPath as h}from"node:url";import{audit as y,batch as x,check as k,guide as w,health as $,replayClear as b,replayList as N,replayTrim as R}from"../../../tools/dist/index.js";import{ctx as u}from"../context.js";import{executeCliBatchOperation as I,extractStrFlag as d,parseBatchPayload as v,printCheckResult as C,readInput as T}from"../helpers.js";const S=f(h(import.meta.url)),E=[{name:"status",description:"Show knowledge base index status and statistics",run:async()=>{const{store:e}=await u(),s=await e.getStats(),t=await e.listSourcePaths();console.log("Knowledge Base Status"),console.log("\u2500".repeat(40)),console.log(` Records: ${s.totalRecords}`),console.log(` Files: ${s.totalFiles}`),console.log(` Indexed: ${s.lastIndexedAt??"Never"}`),console.log(` Backend: ${s.storeBackend}`),console.log(` Model: ${s.embeddingModel}`),console.log(""),console.log("Content Types:");for(const[n,o]of Object.entries(s.contentTypeBreakdown))console.log(` ${n}: ${o}`);if(t.length>0){console.log(""),console.log(`Files (${t.length} total):`);for(const n of t.slice(0,20))console.log(` ${n}`);t.length>20&&console.log(` ... and ${t.length-20} more`)}}},{name:"reindex",description:"Re-index the knowledge base from configured sources",usage:"kb reindex [--full]",run:async e=>{const s=e.includes("--full"),{store:t,indexer:n,curated:o,config:i}=await u();console.log("Indexing sources...");const l=c=>{c.phase==="chunking"&&c.currentFile&&process.stdout.write(`\r [${c.filesProcessed+1}/${c.filesTotal}] ${c.currentFile}`),c.phase==="done"&&process.stdout.write(`
|
|
2
|
+
`)};let r;s?(console.log("Dropping existing index for full reindex..."),r=await n.reindexAll(i,l)):r=await n.index(i,l),console.log(`Done: ${r.filesProcessed} files, ${r.chunksCreated} chunks in ${(r.durationMs/1e3).toFixed(1)}s`),console.log("Building FTS index..."),await t.createFtsIndex(),console.log("Re-indexing curated entries...");const a=await o.reindexAll();console.log(`Curated: ${a.indexed} entries restored`)}},{name:"serve",description:"Start the MCP server (stdio or HTTP)",usage:"kb serve [--transport stdio|http] [--port N]",run:async e=>{const s=g(S,"..","..","..","server","dist","index.js"),t=d(e,"--transport","stdio"),n=d(e,"--port","3210"),o=m(s,[],{stdio:t==="stdio"?["pipe","pipe","inherit","ipc"]:"inherit",env:{...process.env,KB_TRANSPORT:t,KB_PORT:n}});t==="stdio"&&o.stdin&&o.stdout&&(process.stdin.pipe(o.stdin),o.stdout.pipe(process.stdout)),o.on("exit",i=>process.exit(i??0)),process.on("SIGINT",()=>o.kill("SIGINT")),process.on("SIGTERM",()=>o.kill("SIGTERM")),await new Promise(()=>{})}},{name:"init",description:"Initialize a knowledge base in the current directory",usage:"kb init [--force]",run:async e=>{const s=e.includes("--force"),{initProject:t}=await import("./init.js");await t({force:s})}},{name:"check",description:"Run incremental typecheck and lint",usage:"kb check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail summary|errors|full]",run:async e=>{const s=d(e,"--cwd","").trim()||void 0,t=d(e,"--files",""),n=d(e,"--detail","full")||"full",o=t.split(",").map(a=>a.trim()).filter(Boolean);let i=!1;e.includes("--skip-types")&&(e.splice(e.indexOf("--skip-types"),1),i=!0);let l=!1;e.includes("--skip-lint")&&(e.splice(e.indexOf("--skip-lint"),1),l=!0);const r=await k({cwd:s,files:o.length>0?o:void 0,skipTypes:i,skipLint:l,detail:n});C(r),r.passed||(process.exitCode=1)}},{name:"batch",description:"Execute built-in operations from JSON input",usage:"kb batch [--file path] [--concurrency N]",run:async e=>{const s=d(e,"--file","").trim()||void 0,t=(()=>{const c=e.indexOf("--concurrency");if(c===-1||c+1>=e.length)return 0;const p=Number.parseInt(e.splice(c,2)[1],10);return Number.isNaN(p)?0:p})(),n=await T(s);n.trim()||(console.error("Usage: kb batch [--file path] [--concurrency N]"),process.exit(1));const o=v(n),i=t>0?t:o.concurrency,r=o.operations.some(c=>c.type!=="check")?await u():null,a=await x(o.operations,async c=>I(c,r),{concurrency:i});console.log(JSON.stringify(a,null,2)),a.some(c=>c.status==="error")&&(process.exitCode=1)}},{name:"health",description:"Run project health checks on the current directory",usage:"kb health [path]",run:async e=>{const s=e.shift(),t=$(s);console.log(`Project Health: ${t.path}`),console.log("\u2500".repeat(50));for(const n of t.checks){const o=n.status==="pass"?"+":n.status==="warn"?"~":"X";console.log(` [${o}] ${n.name}: ${n.message}`)}console.log("\u2500".repeat(50)),console.log(`Score: ${t.score}% \u2014 ${t.summary}`)}},{name:"audit",description:"Run a unified project audit (structure, deps, patterns, health, dead symbols, check)",usage:"kb audit [path] [--checks structure,dependencies,patterns,health,dead_symbols,check,entry_points] [--detail summary|full]",run:async e=>{const{store:s,embedder:t}=await u(),n=d(e,"--detail","summary")||"summary",o=d(e,"--checks",""),i=o?o.split(",").map(a=>a.trim()):void 0,l=e.shift()||".",r=await y(s,t,{path:l,checks:i,detail:n});if(r.ok){if(console.log(r.summary),r.next&&r.next.length>0){console.log(`
|
|
3
|
+
Suggested next steps:`);for(const a of r.next)console.log(` \u2192 ${a.tool}: ${a.reason}`)}}else console.error(r.error?.message??"Audit failed"),process.exitCode=1}},{name:"guide",description:"Tool discovery \u2014 recommend KB tools for a given goal",usage:"kb guide <goal> [--max N]",run:async e=>{const s=e.indexOf("--max");let t=5;s!==-1&&s+1<e.length&&(t=Number.parseInt(e.splice(s,2)[1],10)||5);const n=e.join(" ").trim();n||(console.error("Usage: kb guide <goal> [--max N]"),console.error('Example: kb guide "audit this project"'),process.exit(1));const o=w(n,t);console.log(`Workflow: ${o.workflow}`),console.log(` ${o.description}
|
|
4
|
+
`),console.log("Recommended tools:");for(const i of o.tools){const l=i.suggestedArgs?` ${JSON.stringify(i.suggestedArgs)}`:"";console.log(` ${i.order}. ${i.tool} \u2014 ${i.reason}${l}`)}o.alternativeWorkflows.length>0&&console.log(`
|
|
5
|
+
Alternatives: ${o.alternativeWorkflows.join(", ")}`)}},{name:"replay",description:"Show recent tool invocation audit trail",usage:"kb replay [--last N] [--tool <name>] [--source mcp|cli]",run:async e=>{const s=Number.parseInt(e[e.indexOf("--last")+1],10)||20,t=e.includes("--tool")?e[e.indexOf("--tool")+1]:void 0,n=e.includes("--source")?e[e.indexOf("--source")+1]:void 0,o=N({last:s,tool:t,source:n});if(o.length===0){console.log("No replay entries. Activity is logged when tools are invoked.");return}console.log(`Replay Log (${o.length} entries)
|
|
6
|
+
`);for(const i of o){const l=i.ts.split("T")[1]?.split(".")[0]??i.ts,r=i.status==="ok"?"\u2713":"\u2717";console.log(`${l} ${r} ${i.tool} (${i.durationMs}ms) [${i.source}]`),console.log(` in: ${i.input}`),console.log(` out: ${i.output}`)}R()}},{name:"replay-clear",description:"Clear the replay audit trail",run:async()=>{b(),console.log("Replay log cleared.")}},{name:"tui",description:"Launch interactive terminal dashboard (human monitoring)",run:async()=>{try{const{launch:e}=await import("../../../tui/dist/index.js"),{store:s,embedder:t,config:n}=await u();e({store:s,embedder:t,config:n})}catch(e){throw e.code==="ERR_MODULE_NOT_FOUND"&&(console.error(`TUI requires ink and react. Install them with:
|
|
4
7
|
pnpm add -D ink react @types/react`),process.exit(1)),e}}}];export{E as systemCommands};
|