kemdicode-mcp 1.20.0 → 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 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
- 103 tools &bull; 7 LLM providers &bull; multi-agent orchestration &bull; kanban &bull; project memory
8
+ 120 tools &bull; 7 LLM providers &bull; multi-agent orchestration &bull; kanban &bull; 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.19.0-blue?style=flat-square" alt="Version" /></a>
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 **100+ specialized tools** for code analysis, generation, git operations, file management, AST-aware editing, project memory, multi-board kanban, and multi-agent coordination.
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.19.0](#whats-new-in-1190)
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,27 +50,29 @@
50
50
 
51
51
  ---
52
52
 
53
- ## What's New in 1.19.0
53
+ ## What's New in 1.21.0
54
54
 
55
- - **Batch/Multi-Item Support for 14 Tools** &mdash; all single-item tools now accept arrays for parallel batch operations: `board-create` (1-10), `board-share` (1-10), `board-invite` (1-20), `board-members` (1-20 ops), `workspace-create` (1-5), `write-memory` (1-20), `read-memory` (1-20), `delete-memory` (1-20), `edit-memory` (1-10), `file-read` (1-20), `file-write` (1-20), `file-diff` (1-10 pairs), `session-create` (1-10), `session-delete` (1-10). All return per-item success/failure with structured results.
56
- - **Memory Tools: Redis Pipeline Optimization** &mdash; `read-memory` and `delete-memory` batch operations use Redis pipelines instead of sequential queries, eliminating N+1 performance issues.
57
- - **5 Critical Bug Fixes** &mdash; memory leak in `sessionHistory` Map (LRU eviction), recursion context restoration in `tool-invoker`, Pub/Sub handler leak in `agent-monitor`, Redis connection leak in kanban subscriber, race condition in `claimTask` blocker validation.
58
- - **5 Performance Improvements** &mdash; session write-back throttling (dirty flag + 5min threshold), kanban `listTasks` N+1 → Redis pipeline, context `queryContext` N+1 → pipeline, rate-limit map cleanup timer, shared Redis connection pooling.
59
- - **2 Security Fixes** &mdash; hardcoded salt fallback removed (now throws on missing `SECURE_STORAGE_SALT`), command injection risk in `projectContext.enhanced.ts` fixed (switched to `execFile`).
60
- - **Template Injection Prevention** &mdash; `consensus-prompt` fixed reversed `replaceAll` order to prevent user prompt from injecting `{board_responses}` placeholder. CEO `maxTokens` capped at 32K.
61
- - **ANSI Escape Injection Protection** &mdash; new `sanitizeTerminalOutput()` utility applied to `agent-alert` and `agent-inject` to prevent terminal escape sequence injection via user-controlled strings.
62
- - **Shared Memory Module** &mdash; extracted duplicated types, constants, and helpers from 7 memory tools into `src/tools/memory/shared.ts`, eliminating 6x duplication.
63
- - **Shared Format Helpers** &mdash; new `src/utils/format-helpers.ts` with `sanitizeTerminalOutput()`, `wrapText()`, `priorityIcon()`, `statusIcon()` shared across agent tools.
64
- - **Input Validation Hardening** &mdash; prototype pollution prevention in `agent-register` metadata keys, octal mode regex validation in `file-write`, ref flag injection prevention in `git-log`, content size limits (1MB) in `queue-message`.
55
+ ### Thinking Chain Tool
65
56
 
66
- ### What was in 1.18.0
57
+ New `thinking-chain` tool for structured reasoning with forward-only constraint:
67
58
 
68
- - **Checkpoint Save/Restore** &mdash; new tools `checkpoint-save` and `checkpoint-restore` for temporary state snapshots in Redis (7-day TTL). Save progress mid-task and restore later.
69
- - **Session Resume** &mdash; new `/resume` HTTP endpoint returns the last active session with tool history, enabling post-compaction recovery. SSE connections receive a `resume` event on reconnect.
70
- - **Runtime Tool Broadcast** &mdash; dynamically registered tools now trigger `notifications/tools/list_changed` to all connected MCP clients, so IDEs see new tools without reconnecting.
71
- - **Session CWD Injection** &mdash; file tools automatically inherit the session's working directory for correct relative path resolution in multi-session setups.
72
- - **Session Cleanup** &mdash; proper cleanup of activity tracking and server references on session close, preventing memory leaks in long-running servers.
73
- - **Compact Tool Descriptions** &mdash; reduced tool description sizes across all 103 tools to slow down context compaction in long sessions.
59
+ - **7 actions** &mdash; `start`, `think`, `branch`, `revise`, `conclude`, `get`, `list`
60
+ - **Forward-only** &mdash; thoughts are appended sequentially; backtracking is blocked until the latest thought reaches **≥90% confidence** or you revise the last thought
61
+ - **Branching** &mdash; fork a new chain from any thought to explore alternative hypotheses without modifying the original chain
62
+ - **Revision tracking** &mdash; revisions are appended as new thoughts with `revisedFrom` reference, preserving the full reasoning history
63
+ - **Confidence tracking** &mdash; every thought has a 0-100% confidence score with optional reasoning
64
+ - **Visual display** &mdash; `get` action renders the chain with box-drawing UI showing thought flow, branches, revisions, and conclusion
65
+ - **Redis-backed** &mdash; 7-day TTL, indexed by session and agent
66
+
67
+ New `thinking` tool category added to the registry.
68
+
69
+ ### What was in 1.20.0
70
+
71
+ - **14 New Tools** &mdash; `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** &mdash; append-only notes for kanban tasks with `TaskNote` type, batch 1-20 comments, `task-get` returns notes
73
+ - **Metadata for All Tools** &mdash; every tool now has `category`, `tags`, `examples`, `relatedTools`. 4 new categories: `loci`, `mpc`, `session`, `rl`
74
+ - **UX Improvements** &mdash; auto-sessionId, board/workspace name lookup, shorthand mode, `format` param for git tools, configurable batch `maxResultLength`, rewritten `help` tool
75
+ - **Bug Fixes** &mdash; race condition in `task-comment` (Promise.all → sequential), emoji fix in priority/status fields
74
76
 
75
77
  ---
76
78
 
@@ -132,7 +134,7 @@ You: "Set up 3 agents: backend, frontend, QA. Backend works on the API, frontend
132
134
 
133
135
  | Capability | Description |
134
136
  |:-----------|:------------|
135
- | **103 MCP Tools** | Code review, refactoring, testing, git, file management, AST editing, memory, checkpoints, kanban |
137
+ | **119 MCP Tools** | Code review, refactoring, testing, git, file management, AST editing, memory, checkpoints, kanban, task comments, pipelines |
136
138
  | **7 LLM Providers** | Native SDKs for OpenAI (GPT-5), Anthropic (Claude 4.5), Gemini (Gemini 3) + OpenAI-compatible for Groq, DeepSeek, Ollama, OpenRouter |
137
139
  | **Multi-Agent** | Agents connect via HTTP, share context through Redis Pub/Sub, coordinate via kanban boards |
138
140
  | **Parallel Multi-Model** | Send one prompt to N models simultaneously; CEO-and-Board consensus pattern |
@@ -351,7 +353,7 @@ ai-config --action test
351
353
 
352
354
  ## Tool Reference
353
355
 
354
- > **103 tools** across 20 categories.
356
+ > **120 tools** across 21 categories.
355
357
 
356
358
  | Category | # | Tools |
357
359
  |:---------|:-:|:------|
@@ -361,18 +363,20 @@ ai-config --action test
361
363
  | **Line Editing** | 4 | `insert-at-line` `delete-lines` `replace-lines` `replace-content` |
362
364
  | **Symbol Editing** | 3 | `insert-before-symbol` `insert-after-symbol` `rename-symbol` |
363
365
  | **Code Modification** | 5 | `fix-bug` `refactor` `auto-fix` `auto-fix-agent` `write-tests` |
364
- | **Project Memory** | 7 | `write-memory` `read-memory` `list-memories` `edit-memory` `delete-memory` `checkpoint-save` `checkpoint-restore` |
365
- | **Git** | 5 | `git-status` `git-diff` `git-log` `git-blame` `git-branch` |
366
- | **File Operations** | 5 | `file-read` `file-write` `file-search` `file-tree` `file-diff` |
366
+ | **Project Memory** | 8 | `write-memory` `read-memory` `list-memories` `edit-memory` `delete-memory` `checkpoint-save` `checkpoint-restore` `checkpoint-diff` |
367
+ | **Git** | 8 | `git-status` `git-diff` `git-log` `git-blame` `git-branch` `git-add` `git-commit` `git-stash` |
368
+ | **File Operations** | 9 | `file-read` `file-write` `file-search` `file-tree` `file-diff` `file-delete` `file-move` `file-copy` `file-backup-restore` |
367
369
  | **Project** | 5 | `project-info` `run-script` `run-tests` `run-lint` `check-types` |
368
- | **Kanban &mdash; Tasks** | 7 | `task-create` `task-list` `task-update` `task-claim` `task-assign` `task-push-multi` `board-status` |
369
- | **Kanban &mdash; Workspaces** | 4 | `workspace-create` `workspace-list` `workspace-join` `workspace-leave` |
370
- | **Kanban &mdash; Boards** | 5 | `board-create` `board-list` `board-share` `board-members` `board-invite` |
370
+ | **Kanban &mdash; Tasks** | 10 | `task-create` `task-get` `task-list` `task-update` `task-delete` `task-comment` `task-claim` `task-assign` `task-push-multi` `board-status` |
371
+ | **Kanban &mdash; Workspaces** | 5 | `workspace-create` `workspace-list` `workspace-join` `workspace-leave` `workspace-delete` |
372
+ | **Kanban &mdash; Boards** | 6 | `board-create` `board-list` `board-share` `board-members` `board-invite` `board-delete` |
371
373
  | **Recursive** | 3 | `invoke-tool` `invoke-batch` `invocation-log` |
372
374
  | **Multi-Agent** | 13 | `agent-list` `agent-register` `agent-watch` `agent-alert` `agent-inject` `agent-history` `monitor` `agent-summary` `queue-message` `shared-thoughts` `get-shared-context` `feedback` `batch` |
375
+ | **Orchestration** | 1 | `pipeline` |
373
376
  | **Session** | 5 | `session-list` `session-info` `session-create` `session-switch` `session-delete` |
374
377
  | **MPC Security** | 4 | `mpc-split` `mpc-distribute` `mpc-reconstruct` `mpc-status` |
375
378
  | **RL Learning** | 2 | `rl-reward-stats` `rl-dopamine-log` |
379
+ | **Thinking Chain** | 1 | `thinking-chain` |
376
380
  | **Knowledge Graph** | 4 | `graph-query` `graph-find-path` `loci-recall` `sequence-recommend` |
377
381
  | **System** | 10 | `shell-exec` `process-list` `env-info` `memory-usage` `ai-config` `ai-models` `config` `ping` `help` `timeout-test` |
378
382
 
@@ -387,7 +391,7 @@ ai-config --action test
387
391
  | **Clients** | Claude Code, Cursor, KiroCode, RooCode | Connect via SSE + JSON-RPC (MCP Protocol) |
388
392
  | **HTTP Server** | `:3100` (Bun or Node.js) | Routes: `/sse`, `/message`, `/resume`, `/stream` |
389
393
  | **Session Manager** | Per-client isolation | CWD injection, activity tracking, `/resume` for post-compaction recovery, SSE keep-alive |
390
- | **Tool Registry** | 103 tools, 20 categories | Zod schema validation, auto JSON Schema generation, runtime registration with `tools/list_changed` broadcast |
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) |
391
395
  | **Provider Registry** | 7 LLM providers | OpenAI, Anthropic, Gemini (native SDKs) + Groq, DeepSeek, Ollama, OpenRouter (OpenAI-compatible). Lazy init, hot-reload, unified thinking tokens |
392
396
  | **Tree-sitter AST** | 19 languages | WASM parsers, symbol navigation, rename, insert before/after, indentation detection |
393
397
  | **Runtime Abstraction** | Bun / Node.js | Auto-detection at startup. Unified HTTP (`Bun.serve` / `node:http`), process spawning (`Bun.spawn` / `child_process`) |
@@ -436,10 +440,11 @@ ai-config --action test
436
440
  | | `storage.ts` | Redis-based shared context store (DB 2) |
437
441
  | | `feedback-loop.ts` | Learning from iteration results |
438
442
  | | `iteration-tracker.ts` | Track fix attempts per issue |
439
- | `src/kanban/` | `kanban-store.ts` | Task CRUD with Redis `hset`/`hgetall` persistence |
443
+ | `src/kanban/` | `kanban-store.ts` | Task CRUD with Redis `hset`/`hgetall` persistence, task notes |
440
444
  | | `workspace-store.ts` | Workspace CRUD operations |
441
445
  | | `board-store.ts` | Board management and membership |
442
446
  | | `membership-store.ts` | Role-based access: owner / admin / member / viewer |
447
+ | | `resolvers.ts` | Auto-sessionId injection, board/workspace name-to-ID resolution |
443
448
  | | `migration.ts` | Lazy migration to multi-board schema |
444
449
  | `src/recursive/` | `tool-invoker.ts` | Safe recursive tool calls: max depth 2, rate-limited, parallel isolation |
445
450
  | `src/tree-sitter/` | `parser-manager.ts` | WASM parser lifecycle for 19 languages |
@@ -447,15 +452,16 @@ ai-config --action test
447
452
  | `src/session/` | `manager.ts` | Session create / destroy / cleanup lifecycle |
448
453
  | | `cwd-resolver.ts` | Project path resolution priority chain |
449
454
  | `src/tools/` | `registry.ts` | `UnifiedTool` interface, Zod &rarr; JSON Schema, broadcast on register |
450
- | | `index.ts` | Central tool registration (103 tools) |
455
+ | | `index.ts` | Central tool registration (120 tools, 21 categories) |
456
+ | | `pipeline.tool.ts` | Sequential tool execution with `{{stepId.result}}` interpolation |
451
457
  | `src/tools/agents/` | 9 tools | `agent-register`, `agent-watch`, `agent-alert`, `agent-inject`, `monitor`, `agent-summary`, `queue-message`, `agent-list`, `agent-history` |
452
458
  | `src/tools/code/` | 8 tools | `find-definition`, `find-references`, `find-symbols`, `code-outline`, `insert-before-symbol`, `insert-after-symbol`, `rename-symbol`, `semantic-search` |
453
459
  | `src/tools/context/` | 4 tools | `shared-thoughts`, `get-shared-context`, `feedback`, `batch` |
454
460
  | `src/tools/edit/` | 4 tools | `insert-at-line`, `delete-lines`, `replace-lines`, `replace-content` |
455
- | `src/tools/file/` | 5 tools | `file-read`, `file-write`, `file-search`, `file-tree`, `file-diff` |
456
- | `src/tools/git/` | 5 tools | `git-status`, `git-diff`, `git-log`, `git-blame`, `git-branch` |
457
- | `src/tools/kanban/` | 16 tools | Tasks (7), boards (5), workspaces (4) |
458
- | `src/tools/memory/` | 7 tools | `write-memory`, `read-memory`, `list-memories`, `edit-memory`, `delete-memory`, `checkpoint-save`, `checkpoint-restore` |
461
+ | `src/tools/file/` | 9 tools | `file-read`, `file-write`, `file-search`, `file-tree`, `file-diff`, `file-delete`, `file-move`, `file-copy`, `file-backup-restore` |
462
+ | `src/tools/git/` | 8 tools | `git-status`, `git-diff`, `git-log`, `git-blame`, `git-branch`, `git-add`, `git-commit`, `git-stash` |
463
+ | `src/tools/kanban/` | 21 tools | Tasks (10), boards (6), workspaces (5) |
464
+ | `src/tools/memory/` | 8 tools | `write-memory`, `read-memory`, `list-memories`, `edit-memory`, `delete-memory`, `checkpoint-save`, `checkpoint-restore`, `checkpoint-diff` |
459
465
  | `src/tools/multi-llm/` | 2 tools | `multi-prompt`, `consensus-prompt` |
460
466
  | `src/tools/project/` | 5 tools | `project-info`, `run-script`, `run-tests`, `run-lint`, `check-types` |
461
467
  | `src/tools/recursive/` | 3 tools | `invoke-tool`, `invoke-batch`, `invocation-log` |
@@ -465,6 +471,8 @@ ai-config --action test
465
471
  | `src/tools/loci/` | 4 tools | `graph-query`, `graph-find-path`, `loci-recall`, `sequence-recommend` |
466
472
  | `src/tools/mpc/` | 4 tools | `mpc-split`, `mpc-distribute`, `mpc-reconstruct`, `mpc-status` |
467
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 |
468
476
  | `src/utils/` | `commandExecutor.ts` | Process spawning with timeout, SIGTERM &rarr; SIGKILL |
469
477
  | | `file-utils.ts` | Read/write with encoding detection (UTF-8, UTF-16, Latin1) |
470
478
  | | `edit-utils.ts` | Line-based editing helpers |
@@ -557,7 +565,7 @@ task-create --tasks '[
557
565
  task-push-multi --taskIds '["t-1","t-2"]' --agents '["agent-1"]' --mode assign
558
566
  ```
559
567
 
560
- **Features:** workspaces &bull; multiple boards &bull; owner / admin / member / viewer roles &bull; batch create / update (1-20 per call) &bull; assign / clone / notify distribution modes
568
+ **Features:** workspaces &bull; multiple boards &bull; owner / admin / member / viewer roles &bull; batch create / update / delete (1-20 per call) &bull; assign / clone / notify distribution modes &bull; append-only task comments &bull; auto-sessionId &bull; board/workspace name lookup
561
569
 
562
570
  ---
563
571
 
@@ -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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"}