kemdicode-mcp 1.20.1 → 1.21.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 +27 -44
- package/dist/thinking/index.d.ts +20 -0
- package/dist/thinking/index.d.ts.map +1 -0
- package/dist/thinking/index.js +12 -0
- package/dist/thinking/index.js.map +1 -0
- package/dist/thinking/thinking-store.d.ts +79 -0
- package/dist/thinking/thinking-store.d.ts.map +1 -0
- package/dist/thinking/thinking-store.js +304 -0
- package/dist/thinking/thinking-store.js.map +1 -0
- package/dist/thinking/types.d.ts +91 -0
- package/dist/thinking/types.d.ts.map +1 -0
- package/dist/thinking/types.js +31 -0
- package/dist/thinking/types.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/thinking/index.d.ts +11 -0
- package/dist/tools/thinking/index.d.ts.map +1 -0
- package/dist/tools/thinking/index.js +11 -0
- package/dist/tools/thinking/index.js.map +1 -0
- package/dist/tools/thinking/thinking-chain.tool.d.ts +20 -0
- package/dist/tools/thinking/thinking-chain.tool.d.ts.map +1 -0
- package/dist/tools/thinking/thinking-chain.tool.js +378 -0
- package/dist/tools/thinking/thinking-chain.tool.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<h3 align="center">Model Context Protocol Server for AI-Powered Development</h3>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
|
|
8
|
+
120 tools • 7 LLM providers • multi-agent orchestration • kanban • project memory
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://www.npmjs.com/package/kemdicode-mcp"><img src="https://img.shields.io/badge/npm-kemdicode--mcp-CB3837?style=flat-square&logo=npm&logoColor=white" alt="npm" /></a>
|
|
13
|
-
<a href="https://github.com/kemdi-pl/kemdicode-mcp/releases"><img src="https://img.shields.io/badge/version-1.
|
|
13
|
+
<a href="https://github.com/kemdi-pl/kemdicode-mcp/releases"><img src="https://img.shields.io/badge/version-1.21.0-blue?style=flat-square" alt="Version" /></a>
|
|
14
14
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-GPL--3.0-green?style=flat-square" alt="License" /></a>
|
|
15
15
|
</p>
|
|
16
16
|
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
-
**kemdiCode MCP** is a [Model Context Protocol](https://modelcontextprotocol.io/) server that gives AI agents and IDE assistants access to **
|
|
26
|
+
**kemdiCode MCP** is a [Model Context Protocol](https://modelcontextprotocol.io/) server that gives AI agents and IDE assistants access to **120 specialized tools** for code analysis, generation, git operations, file management, AST-aware editing, project memory, multi-board kanban, task comments, and multi-agent coordination.
|
|
27
27
|
|
|
28
28
|
<details>
|
|
29
29
|
<summary><strong>Table of Contents</strong></summary>
|
|
30
30
|
|
|
31
|
-
- [What's New in 1.
|
|
31
|
+
- [What's New in 1.21.0](#whats-new-in-1210)
|
|
32
32
|
- [Usage Examples](#usage-examples)
|
|
33
33
|
- [Highlights](#highlights)
|
|
34
34
|
- [Compatibility](#compatibility)
|
|
@@ -50,49 +50,29 @@
|
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
53
|
-
## What's New in 1.
|
|
53
|
+
## What's New in 1.21.0
|
|
54
54
|
|
|
55
|
-
###
|
|
55
|
+
### Thinking Chain Tool
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
- **Kanban CRUD** — `task-get` (full task details), `task-delete` (batch 1-20), `task-comment` (append-only notes with author tracking), `board-delete` (cascade option), `workspace-delete` (ownership verification)
|
|
59
|
-
- **File operations** — `file-delete` (security checks, critical file protection, dry-run), `file-move` (cross-filesystem), `file-copy` (overwrite protection), `file-backup-restore` (list/restore `.bak` files)
|
|
60
|
-
- **Orchestration** — `pipeline` (sequential tool execution with `{{stepId.result}}` interpolation, max 10 steps), `checkpoint-diff` (compare current files with saved checkpoint)
|
|
57
|
+
New `thinking-chain` tool for structured reasoning with forward-only constraint:
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
- **7 actions** — `start`, `think`, `branch`, `revise`, `conclude`, `get`, `list`
|
|
60
|
+
- **Forward-only** — thoughts are appended sequentially; backtracking is blocked until the latest thought reaches **≥90% confidence** or you revise the last thought
|
|
61
|
+
- **Branching** — fork a new chain from any thought to explore alternative hypotheses without modifying the original chain
|
|
62
|
+
- **Revision tracking** — revisions are appended as new thoughts with `revisedFrom` reference, preserving the full reasoning history
|
|
63
|
+
- **Confidence tracking** — every thought has a 0-100% confidence score with optional reasoning
|
|
64
|
+
- **Visual display** — `get` action renders the chain with box-drawing UI showing thought flow, branches, revisions, and conclusion
|
|
65
|
+
- **Redis-backed** — 7-day TTL, indexed by session and agent
|
|
63
66
|
|
|
64
|
-
New
|
|
65
|
-
- `TaskNote` type: `id`, `author`, `content`, `createdAt`
|
|
66
|
-
- `task-comment` tool: batch 1-20 comments, shorthand mode `{ taskId, author, content }`
|
|
67
|
-
- `task-get` returns `notes` array and `noteCount`
|
|
67
|
+
New `thinking` tool category added to the registry.
|
|
68
68
|
|
|
69
|
-
###
|
|
69
|
+
### What was in 1.20.0
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- **
|
|
76
|
-
- **Name lookup** — use board/workspace names instead of UUIDs (`"name:My Board"` or just `"My Board"`)
|
|
77
|
-
- **Shorthand mode** — `file-read` and `write-memory` accept single-item format without array wrapper
|
|
78
|
-
- **git-status / git-diff** — new `format` parameter (`text` / `json`)
|
|
79
|
-
- **batch tool** — configurable `maxResultLength` (up to 50,000 chars, default 5,000)
|
|
80
|
-
- **help tool** — rewritten with categorized tool listing from registry
|
|
81
|
-
- **Progress reporting** — fixed in `run-lint`
|
|
82
|
-
- **Cross-references** — `auto-fix` ↔ `replace-content` descriptions link to each other
|
|
83
|
-
|
|
84
|
-
### Bug Fixes
|
|
85
|
-
|
|
86
|
-
- Race condition in `task-comment` when multiple comments target the same task (Promise.all → sequential)
|
|
87
|
-
- Emoji fix: raw priority/status in data fields, separate `priorityIcon`/`statusIcon` fields
|
|
88
|
-
|
|
89
|
-
### What was in 1.19.0
|
|
90
|
-
|
|
91
|
-
- **Batch/Multi-Item Support for 14 Tools** — all single-item tools now accept arrays for parallel batch operations (1-20 items each). All return per-item success/failure with structured results.
|
|
92
|
-
- **Memory Tools: Redis Pipeline Optimization** — `read-memory` and `delete-memory` use Redis pipelines, eliminating N+1 issues.
|
|
93
|
-
- **5 Critical Bug Fixes** — memory leak in `sessionHistory`, recursion context restoration, Pub/Sub handler leak, Redis connection leak, race condition in `claimTask`.
|
|
94
|
-
- **5 Performance Improvements** — session write-back throttling, kanban/context N+1 → pipeline, rate-limit cleanup, shared Redis pooling.
|
|
95
|
-
- **Security** — hardcoded salt removed, command injection fix, template injection prevention, ANSI escape protection, input validation hardening.
|
|
71
|
+
- **14 New Tools** — `git-add`, `git-commit`, `git-stash`, `task-get`, `task-delete`, `task-comment`, `board-delete`, `workspace-delete`, `file-delete`, `file-move`, `file-copy`, `file-backup-restore`, `pipeline`, `checkpoint-diff`
|
|
72
|
+
- **Task Comments System** — append-only notes for kanban tasks with `TaskNote` type, batch 1-20 comments, `task-get` returns notes
|
|
73
|
+
- **Metadata for All Tools** — every tool now has `category`, `tags`, `examples`, `relatedTools`. 4 new categories: `loci`, `mpc`, `session`, `rl`
|
|
74
|
+
- **UX Improvements** — auto-sessionId, board/workspace name lookup, shorthand mode, `format` param for git tools, configurable batch `maxResultLength`, rewritten `help` tool
|
|
75
|
+
- **Bug Fixes** — race condition in `task-comment` (Promise.all → sequential), emoji fix in priority/status fields
|
|
96
76
|
|
|
97
77
|
---
|
|
98
78
|
|
|
@@ -373,7 +353,7 @@ ai-config --action test
|
|
|
373
353
|
|
|
374
354
|
## Tool Reference
|
|
375
355
|
|
|
376
|
-
> **
|
|
356
|
+
> **120 tools** across 21 categories.
|
|
377
357
|
|
|
378
358
|
| Category | # | Tools |
|
|
379
359
|
|:---------|:-:|:------|
|
|
@@ -396,6 +376,7 @@ ai-config --action test
|
|
|
396
376
|
| **Session** | 5 | `session-list` `session-info` `session-create` `session-switch` `session-delete` |
|
|
397
377
|
| **MPC Security** | 4 | `mpc-split` `mpc-distribute` `mpc-reconstruct` `mpc-status` |
|
|
398
378
|
| **RL Learning** | 2 | `rl-reward-stats` `rl-dopamine-log` |
|
|
379
|
+
| **Thinking Chain** | 1 | `thinking-chain` |
|
|
399
380
|
| **Knowledge Graph** | 4 | `graph-query` `graph-find-path` `loci-recall` `sequence-recommend` |
|
|
400
381
|
| **System** | 10 | `shell-exec` `process-list` `env-info` `memory-usage` `ai-config` `ai-models` `config` `ping` `help` `timeout-test` |
|
|
401
382
|
|
|
@@ -410,7 +391,7 @@ ai-config --action test
|
|
|
410
391
|
| **Clients** | Claude Code, Cursor, KiroCode, RooCode | Connect via SSE + JSON-RPC (MCP Protocol) |
|
|
411
392
|
| **HTTP Server** | `:3100` (Bun or Node.js) | Routes: `/sse`, `/message`, `/resume`, `/stream` |
|
|
412
393
|
| **Session Manager** | Per-client isolation | CWD injection, activity tracking, `/resume` for post-compaction recovery, SSE keep-alive |
|
|
413
|
-
| **Tool Registry** |
|
|
394
|
+
| **Tool Registry** | 120 tools, 21 categories | Zod schema validation, auto JSON Schema generation, runtime registration with `tools/list_changed` broadcast, full metadata (category, tags, examples, relatedTools) |
|
|
414
395
|
| **Provider Registry** | 7 LLM providers | OpenAI, Anthropic, Gemini (native SDKs) + Groq, DeepSeek, Ollama, OpenRouter (OpenAI-compatible). Lazy init, hot-reload, unified thinking tokens |
|
|
415
396
|
| **Tree-sitter AST** | 19 languages | WASM parsers, symbol navigation, rename, insert before/after, indentation detection |
|
|
416
397
|
| **Runtime Abstraction** | Bun / Node.js | Auto-detection at startup. Unified HTTP (`Bun.serve` / `node:http`), process spawning (`Bun.spawn` / `child_process`) |
|
|
@@ -471,7 +452,7 @@ ai-config --action test
|
|
|
471
452
|
| `src/session/` | `manager.ts` | Session create / destroy / cleanup lifecycle |
|
|
472
453
|
| | `cwd-resolver.ts` | Project path resolution priority chain |
|
|
473
454
|
| `src/tools/` | `registry.ts` | `UnifiedTool` interface, Zod → JSON Schema, broadcast on register |
|
|
474
|
-
| | `index.ts` | Central tool registration (
|
|
455
|
+
| | `index.ts` | Central tool registration (120 tools, 21 categories) |
|
|
475
456
|
| | `pipeline.tool.ts` | Sequential tool execution with `{{stepId.result}}` interpolation |
|
|
476
457
|
| `src/tools/agents/` | 9 tools | `agent-register`, `agent-watch`, `agent-alert`, `agent-inject`, `monitor`, `agent-summary`, `queue-message`, `agent-list`, `agent-history` |
|
|
477
458
|
| `src/tools/code/` | 8 tools | `find-definition`, `find-references`, `find-symbols`, `code-outline`, `insert-before-symbol`, `insert-after-symbol`, `rename-symbol`, `semantic-search` |
|
|
@@ -490,6 +471,8 @@ ai-config --action test
|
|
|
490
471
|
| `src/tools/loci/` | 4 tools | `graph-query`, `graph-find-path`, `loci-recall`, `sequence-recommend` |
|
|
491
472
|
| `src/tools/mpc/` | 4 tools | `mpc-split`, `mpc-distribute`, `mpc-reconstruct`, `mpc-status` |
|
|
492
473
|
| `src/tools/rl/` | 2 tools | `rl-reward-stats`, `rl-dopamine-log` |
|
|
474
|
+
| `src/tools/thinking/` | 1 tool | `thinking-chain` |
|
|
475
|
+
| `src/thinking/` | Store + types | `ThinkingChain`, `Thought` types, Redis-backed store with forward-only constraint |
|
|
493
476
|
| `src/utils/` | `commandExecutor.ts` | Process spawning with timeout, SIGTERM → SIGKILL |
|
|
494
477
|
| | `file-utils.ts` | Read/write with encoding detection (UTF-8, UTF-16, Latin1) |
|
|
495
478
|
| | `edit-utils.ts` | Line-based editing helpers |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KemdiCode MCP Server
|
|
3
|
+
* Copyright (C) 2025-2026 Kemdi Sp. z o.o.
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Thinking Chain Module
|
|
12
|
+
*
|
|
13
|
+
* Exports types and store functions for the thinking chain system.
|
|
14
|
+
*
|
|
15
|
+
* @module thinking
|
|
16
|
+
*/
|
|
17
|
+
export type { ThinkingChain, Thought, ChainStatus } from './types.js';
|
|
18
|
+
export { THINKING_KEYS, THINKING_TTL } from './types.js';
|
|
19
|
+
export { createChain, getChain, addThought, reviseThought, branchChain, concludeChain, listChains, } from './thinking-store.js';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/thinking/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;GAMG;AAEH,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KemdiCode MCP Server
|
|
3
|
+
* Copyright (C) 2025-2026 Kemdi Sp. z o.o.
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*/
|
|
10
|
+
export { THINKING_KEYS, THINKING_TTL } from './types.js';
|
|
11
|
+
export { createChain, getChain, addThought, reviseThought, branchChain, concludeChain, listChains, } from './thinking-store.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/thinking/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,UAAU,GACX,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KemdiCode MCP Server
|
|
3
|
+
* Copyright (C) 2025-2026 Kemdi Sp. z o.o.
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
import type { ThinkingChain, Thought, ChainStatus } from './types.js';
|
|
19
|
+
/**
|
|
20
|
+
* Create a new thinking chain with its first thought
|
|
21
|
+
*/
|
|
22
|
+
export declare function createChain(params: {
|
|
23
|
+
title: string;
|
|
24
|
+
agentId: string;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
content: string;
|
|
27
|
+
confidence: number;
|
|
28
|
+
reasoning?: string;
|
|
29
|
+
tags?: string[];
|
|
30
|
+
}): Promise<ThinkingChain>;
|
|
31
|
+
/**
|
|
32
|
+
* Get a chain by ID
|
|
33
|
+
*/
|
|
34
|
+
export declare function getChain(chainId: string): Promise<ThinkingChain | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Add a new thought to the end of a chain (forward-only)
|
|
37
|
+
*/
|
|
38
|
+
export declare function addThought(chainId: string, params: {
|
|
39
|
+
content: string;
|
|
40
|
+
confidence: number;
|
|
41
|
+
reasoning?: string;
|
|
42
|
+
}): Promise<Thought>;
|
|
43
|
+
/**
|
|
44
|
+
* Revise a thought in the chain.
|
|
45
|
+
* Only allowed if:
|
|
46
|
+
* - thoughtIndex is the last thought's index (revising latest), OR
|
|
47
|
+
* - The latest thought has confidence >= 90
|
|
48
|
+
*/
|
|
49
|
+
export declare function reviseThought(chainId: string, params: {
|
|
50
|
+
thoughtIndex: number;
|
|
51
|
+
content: string;
|
|
52
|
+
confidence: number;
|
|
53
|
+
reasoning?: string;
|
|
54
|
+
}): Promise<Thought>;
|
|
55
|
+
/**
|
|
56
|
+
* Branch a new chain from a specific thought in an existing chain
|
|
57
|
+
*/
|
|
58
|
+
export declare function branchChain(params: {
|
|
59
|
+
sourceChainId: string;
|
|
60
|
+
thoughtIndex: number;
|
|
61
|
+
title: string;
|
|
62
|
+
content: string;
|
|
63
|
+
confidence: number;
|
|
64
|
+
reasoning?: string;
|
|
65
|
+
}): Promise<ThinkingChain>;
|
|
66
|
+
/**
|
|
67
|
+
* Conclude a chain with a final conclusion
|
|
68
|
+
*/
|
|
69
|
+
export declare function concludeChain(chainId: string, conclusion: string): Promise<ThinkingChain>;
|
|
70
|
+
/**
|
|
71
|
+
* List chains with optional filters
|
|
72
|
+
*/
|
|
73
|
+
export declare function listChains(params: {
|
|
74
|
+
sessionId?: string;
|
|
75
|
+
agentId?: string;
|
|
76
|
+
status?: ChainStatus;
|
|
77
|
+
limit?: number;
|
|
78
|
+
}): Promise<ThinkingChain[]>;
|
|
79
|
+
//# sourceMappingURL=thinking-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thinking-store.d.ts","sourceRoot":"","sources":["../../src/thinking/thinking-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAsEtE;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiCzB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAS7E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE,OAAO,CAAC,OAAO,CAAC,CAwBlB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxF,OAAO,CAAC,OAAO,CAAC,CA0ClB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,aAAa,CAAC,CAwDzB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAmBxB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA0B3B"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KemdiCode MCP Server
|
|
3
|
+
* Copyright (C) 2025-2026 Kemdi Sp. z o.o.
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
* (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
* GNU General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Thinking Chain Store
|
|
20
|
+
*
|
|
21
|
+
* Redis-backed storage for thinking chains.
|
|
22
|
+
* Uses hash storage with JSON-serialized thoughts array.
|
|
23
|
+
*
|
|
24
|
+
* @module thinking/thinking-store
|
|
25
|
+
*/
|
|
26
|
+
import { getSharedRedis } from '../infrastructure/redis/connection.js';
|
|
27
|
+
import { THINKING_KEYS, THINKING_TTL } from './types.js';
|
|
28
|
+
import { randomBytes } from 'crypto';
|
|
29
|
+
/**
|
|
30
|
+
* Get Redis client
|
|
31
|
+
*/
|
|
32
|
+
async function getRedis() {
|
|
33
|
+
return getSharedRedis();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generate a unique chain ID
|
|
37
|
+
*/
|
|
38
|
+
function generateChainId() {
|
|
39
|
+
return `chain_${Date.now()}_${randomBytes(4).toString('hex')}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Safely parse JSON with fallback
|
|
43
|
+
*/
|
|
44
|
+
function safeJsonParse(value, fallback) {
|
|
45
|
+
if (!value)
|
|
46
|
+
return fallback;
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(value) ?? fallback;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return fallback;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Serialize chain for Redis storage
|
|
56
|
+
*/
|
|
57
|
+
function serializeChain(chain) {
|
|
58
|
+
return {
|
|
59
|
+
id: chain.id,
|
|
60
|
+
title: chain.title,
|
|
61
|
+
agentId: chain.agentId,
|
|
62
|
+
sessionId: chain.sessionId,
|
|
63
|
+
parentChainId: chain.parentChainId || '',
|
|
64
|
+
parentThoughtIndex: chain.parentThoughtIndex !== undefined ? String(chain.parentThoughtIndex) : '',
|
|
65
|
+
thoughts: JSON.stringify(chain.thoughts),
|
|
66
|
+
status: chain.status,
|
|
67
|
+
conclusion: chain.conclusion || '',
|
|
68
|
+
tags: JSON.stringify(chain.tags),
|
|
69
|
+
createdAt: String(chain.createdAt),
|
|
70
|
+
updatedAt: String(chain.updatedAt),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse chain from Redis data
|
|
75
|
+
*/
|
|
76
|
+
function parseChain(data) {
|
|
77
|
+
return {
|
|
78
|
+
id: data.id,
|
|
79
|
+
title: data.title,
|
|
80
|
+
agentId: data.agentId,
|
|
81
|
+
sessionId: data.sessionId,
|
|
82
|
+
parentChainId: data.parentChainId || undefined,
|
|
83
|
+
parentThoughtIndex: data.parentThoughtIndex ? parseInt(data.parentThoughtIndex, 10) : undefined,
|
|
84
|
+
thoughts: safeJsonParse(data.thoughts, []),
|
|
85
|
+
status: data.status || 'active',
|
|
86
|
+
conclusion: data.conclusion || undefined,
|
|
87
|
+
tags: safeJsonParse(data.tags, []),
|
|
88
|
+
createdAt: parseInt(data.createdAt, 10) || 0,
|
|
89
|
+
updatedAt: parseInt(data.updatedAt, 10) || 0,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create a new thinking chain with its first thought
|
|
94
|
+
*/
|
|
95
|
+
export async function createChain(params) {
|
|
96
|
+
const client = await getRedis();
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
const firstThought = {
|
|
99
|
+
index: 0,
|
|
100
|
+
content: params.content,
|
|
101
|
+
confidence: Math.max(0, Math.min(100, params.confidence)),
|
|
102
|
+
reasoning: params.reasoning,
|
|
103
|
+
createdAt: now,
|
|
104
|
+
};
|
|
105
|
+
const chain = {
|
|
106
|
+
id: generateChainId(),
|
|
107
|
+
title: params.title,
|
|
108
|
+
agentId: params.agentId,
|
|
109
|
+
sessionId: params.sessionId,
|
|
110
|
+
thoughts: [firstThought],
|
|
111
|
+
status: 'active',
|
|
112
|
+
tags: params.tags || [],
|
|
113
|
+
createdAt: now,
|
|
114
|
+
updatedAt: now,
|
|
115
|
+
};
|
|
116
|
+
const key = THINKING_KEYS.chain(chain.id);
|
|
117
|
+
await client.hset(key, serializeChain(chain));
|
|
118
|
+
await client.expire(key, THINKING_TTL);
|
|
119
|
+
// Add to indexes
|
|
120
|
+
await client.sadd(THINKING_KEYS.bySession(chain.sessionId), chain.id);
|
|
121
|
+
await client.sadd(THINKING_KEYS.byAgent(chain.agentId), chain.id);
|
|
122
|
+
return chain;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get a chain by ID
|
|
126
|
+
*/
|
|
127
|
+
export async function getChain(chainId) {
|
|
128
|
+
const client = await getRedis();
|
|
129
|
+
const data = await client.hgetall(THINKING_KEYS.chain(chainId));
|
|
130
|
+
if (!data || Object.keys(data).length === 0) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return parseChain(data);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Add a new thought to the end of a chain (forward-only)
|
|
137
|
+
*/
|
|
138
|
+
export async function addThought(chainId, params) {
|
|
139
|
+
const client = await getRedis();
|
|
140
|
+
const chain = await getChain(chainId);
|
|
141
|
+
if (!chain)
|
|
142
|
+
throw new Error(`Chain not found: ${chainId}`);
|
|
143
|
+
if (chain.status !== 'active')
|
|
144
|
+
throw new Error(`Chain is ${chain.status}, cannot add thoughts`);
|
|
145
|
+
const now = Date.now();
|
|
146
|
+
const thought = {
|
|
147
|
+
index: chain.thoughts.length,
|
|
148
|
+
content: params.content,
|
|
149
|
+
confidence: Math.max(0, Math.min(100, params.confidence)),
|
|
150
|
+
reasoning: params.reasoning,
|
|
151
|
+
createdAt: now,
|
|
152
|
+
};
|
|
153
|
+
chain.thoughts.push(thought);
|
|
154
|
+
const key = THINKING_KEYS.chain(chainId);
|
|
155
|
+
await client.hset(key, {
|
|
156
|
+
thoughts: JSON.stringify(chain.thoughts),
|
|
157
|
+
updatedAt: String(now),
|
|
158
|
+
});
|
|
159
|
+
return thought;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Revise a thought in the chain.
|
|
163
|
+
* Only allowed if:
|
|
164
|
+
* - thoughtIndex is the last thought's index (revising latest), OR
|
|
165
|
+
* - The latest thought has confidence >= 90
|
|
166
|
+
*/
|
|
167
|
+
export async function reviseThought(chainId, params) {
|
|
168
|
+
const client = await getRedis();
|
|
169
|
+
const chain = await getChain(chainId);
|
|
170
|
+
if (!chain)
|
|
171
|
+
throw new Error(`Chain not found: ${chainId}`);
|
|
172
|
+
if (chain.status !== 'active')
|
|
173
|
+
throw new Error(`Chain is ${chain.status}, cannot revise thoughts`);
|
|
174
|
+
const lastThought = chain.thoughts[chain.thoughts.length - 1];
|
|
175
|
+
const isLastThought = params.thoughtIndex === lastThought.index;
|
|
176
|
+
const highConfidence = lastThought.confidence >= 90;
|
|
177
|
+
if (!isLastThought && !highConfidence) {
|
|
178
|
+
throw new Error(`Cannot revise thought #${params.thoughtIndex}: backtracking blocked. ` +
|
|
179
|
+
`Latest thought confidence is ${lastThought.confidence}% (need ≥90%) ` +
|
|
180
|
+
`or revise the latest thought (#${lastThought.index}).`);
|
|
181
|
+
}
|
|
182
|
+
if (params.thoughtIndex < 0 || params.thoughtIndex >= chain.thoughts.length) {
|
|
183
|
+
throw new Error(`Thought index ${params.thoughtIndex} out of range (0-${chain.thoughts.length - 1})`);
|
|
184
|
+
}
|
|
185
|
+
const now = Date.now();
|
|
186
|
+
// Append a new thought that marks itself as a revision
|
|
187
|
+
const revisedThought = {
|
|
188
|
+
index: chain.thoughts.length,
|
|
189
|
+
content: params.content,
|
|
190
|
+
confidence: Math.max(0, Math.min(100, params.confidence)),
|
|
191
|
+
reasoning: params.reasoning,
|
|
192
|
+
revisedFrom: params.thoughtIndex,
|
|
193
|
+
createdAt: now,
|
|
194
|
+
};
|
|
195
|
+
chain.thoughts.push(revisedThought);
|
|
196
|
+
const key = THINKING_KEYS.chain(chainId);
|
|
197
|
+
await client.hset(key, {
|
|
198
|
+
thoughts: JSON.stringify(chain.thoughts),
|
|
199
|
+
updatedAt: String(now),
|
|
200
|
+
});
|
|
201
|
+
return revisedThought;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Branch a new chain from a specific thought in an existing chain
|
|
205
|
+
*/
|
|
206
|
+
export async function branchChain(params) {
|
|
207
|
+
const client = await getRedis();
|
|
208
|
+
const sourceChain = await getChain(params.sourceChainId);
|
|
209
|
+
if (!sourceChain)
|
|
210
|
+
throw new Error(`Source chain not found: ${params.sourceChainId}`);
|
|
211
|
+
if (params.thoughtIndex < 0 || params.thoughtIndex >= sourceChain.thoughts.length) {
|
|
212
|
+
throw new Error(`Thought index ${params.thoughtIndex} out of range (0-${sourceChain.thoughts.length - 1})`);
|
|
213
|
+
}
|
|
214
|
+
const now = Date.now();
|
|
215
|
+
const firstThought = {
|
|
216
|
+
index: 0,
|
|
217
|
+
content: params.content,
|
|
218
|
+
confidence: Math.max(0, Math.min(100, params.confidence)),
|
|
219
|
+
reasoning: params.reasoning,
|
|
220
|
+
createdAt: now,
|
|
221
|
+
};
|
|
222
|
+
const newChain = {
|
|
223
|
+
id: generateChainId(),
|
|
224
|
+
title: params.title,
|
|
225
|
+
agentId: sourceChain.agentId,
|
|
226
|
+
sessionId: sourceChain.sessionId,
|
|
227
|
+
parentChainId: params.sourceChainId,
|
|
228
|
+
parentThoughtIndex: params.thoughtIndex,
|
|
229
|
+
thoughts: [firstThought],
|
|
230
|
+
status: 'active',
|
|
231
|
+
tags: [...sourceChain.tags],
|
|
232
|
+
createdAt: now,
|
|
233
|
+
updatedAt: now,
|
|
234
|
+
};
|
|
235
|
+
// Save new chain
|
|
236
|
+
const key = THINKING_KEYS.chain(newChain.id);
|
|
237
|
+
await client.hset(key, serializeChain(newChain));
|
|
238
|
+
await client.expire(key, THINKING_TTL);
|
|
239
|
+
// Add to indexes
|
|
240
|
+
await client.sadd(THINKING_KEYS.bySession(newChain.sessionId), newChain.id);
|
|
241
|
+
await client.sadd(THINKING_KEYS.byAgent(newChain.agentId), newChain.id);
|
|
242
|
+
// Record branch in source chain's thought
|
|
243
|
+
const sourceThought = sourceChain.thoughts[params.thoughtIndex];
|
|
244
|
+
if (!sourceThought.branches)
|
|
245
|
+
sourceThought.branches = [];
|
|
246
|
+
sourceThought.branches.push(newChain.id);
|
|
247
|
+
await client.hset(THINKING_KEYS.chain(params.sourceChainId), {
|
|
248
|
+
thoughts: JSON.stringify(sourceChain.thoughts),
|
|
249
|
+
updatedAt: String(now),
|
|
250
|
+
});
|
|
251
|
+
return newChain;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Conclude a chain with a final conclusion
|
|
255
|
+
*/
|
|
256
|
+
export async function concludeChain(chainId, conclusion) {
|
|
257
|
+
const client = await getRedis();
|
|
258
|
+
const chain = await getChain(chainId);
|
|
259
|
+
if (!chain)
|
|
260
|
+
throw new Error(`Chain not found: ${chainId}`);
|
|
261
|
+
if (chain.status !== 'active')
|
|
262
|
+
throw new Error(`Chain is already ${chain.status}`);
|
|
263
|
+
const now = Date.now();
|
|
264
|
+
const key = THINKING_KEYS.chain(chainId);
|
|
265
|
+
await client.hset(key, {
|
|
266
|
+
status: 'concluded',
|
|
267
|
+
conclusion,
|
|
268
|
+
updatedAt: String(now),
|
|
269
|
+
});
|
|
270
|
+
chain.status = 'concluded';
|
|
271
|
+
chain.conclusion = conclusion;
|
|
272
|
+
chain.updatedAt = now;
|
|
273
|
+
return chain;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* List chains with optional filters
|
|
277
|
+
*/
|
|
278
|
+
export async function listChains(params) {
|
|
279
|
+
const client = await getRedis();
|
|
280
|
+
let chainIds = [];
|
|
281
|
+
if (params.agentId) {
|
|
282
|
+
chainIds = await client.smembers(THINKING_KEYS.byAgent(params.agentId));
|
|
283
|
+
}
|
|
284
|
+
else if (params.sessionId) {
|
|
285
|
+
chainIds = await client.smembers(THINKING_KEYS.bySession(params.sessionId));
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
const chains = [];
|
|
291
|
+
for (const id of chainIds) {
|
|
292
|
+
const chain = await getChain(id);
|
|
293
|
+
if (!chain)
|
|
294
|
+
continue;
|
|
295
|
+
if (params.status && chain.status !== params.status)
|
|
296
|
+
continue;
|
|
297
|
+
chains.push(chain);
|
|
298
|
+
}
|
|
299
|
+
// Sort by updatedAt desc
|
|
300
|
+
chains.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
301
|
+
const limit = params.limit || 20;
|
|
302
|
+
return chains.slice(0, limit);
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=thinking-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thinking-store.js","sourceRoot":"","sources":["../../src/thinking/thinking-store.ts"],"names":[],"mappings":"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"}
|