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 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
- 119 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.20.1-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 **119 specialized tools** for code analysis, generation, git operations, file management, AST-aware editing, project memory, multi-board kanban, task comments, 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.20.0](#whats-new-in-1200)
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.20.0
53
+ ## What's New in 1.21.0
54
54
 
55
- ### 14 New Tools
55
+ ### Thinking Chain Tool
56
56
 
57
- - **Git workflow** &mdash; `git-add` (stage files), `git-commit` (create commits), `git-stash` (full stash management: push/pop/list/drop/apply/show)
58
- - **Kanban CRUD** &mdash; `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** &mdash; `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** &mdash; `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
- ### Task Comments System
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
63
66
 
64
- New append-only notes for kanban tasks &mdash; agents can add progress notes without overwriting the task description:
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
- ### Metadata for All 119 Tools
69
+ ### What was in 1.20.0
70
70
 
71
- Every tool now has a `metadata` block with `category`, `tags`, `examples` (realistic args), and `relatedTools`. The `help` tool generates a categorized listing from this metadata. 4 new categories: `loci`, `mpc`, `session`, `rl`.
72
-
73
- ### UX Improvements
74
-
75
- - **Auto-sessionId** &mdash; `sessionId` is now optional in all kanban/workspace tools; auto-detected from the MCP connection
76
- - **Name lookup** &mdash; use board/workspace names instead of UUIDs (`"name:My Board"` or just `"My Board"`)
77
- - **Shorthand mode** &mdash; `file-read` and `write-memory` accept single-item format without array wrapper
78
- - **git-status / git-diff** &mdash; new `format` parameter (`text` / `json`)
79
- - **batch tool** &mdash; configurable `maxResultLength` (up to 50,000 chars, default 5,000)
80
- - **help tool** &mdash; rewritten with categorized tool listing from registry
81
- - **Progress reporting** &mdash; fixed in `run-lint`
82
- - **Cross-references** &mdash; `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** &mdash; 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** &mdash; `read-memory` and `delete-memory` use Redis pipelines, eliminating N+1 issues.
93
- - **5 Critical Bug Fixes** &mdash; memory leak in `sessionHistory`, recursion context restoration, Pub/Sub handler leak, Redis connection leak, race condition in `claimTask`.
94
- - **5 Performance Improvements** &mdash; session write-back throttling, kanban/context N+1 → pipeline, rate-limit cleanup, shared Redis pooling.
95
- - **Security** &mdash; hardcoded salt removed, command injection fix, template injection prevention, ANSI escape protection, input validation hardening.
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
96
76
 
97
77
  ---
98
78
 
@@ -373,7 +353,7 @@ ai-config --action test
373
353
 
374
354
  ## Tool Reference
375
355
 
376
- > **119 tools** across 20 categories.
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** | 119 tools, 20 categories | Zod schema validation, auto JSON Schema generation, runtime registration with `tools/list_changed` broadcast, full metadata (category, tags, examples, relatedTools) |
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 &rarr; JSON Schema, broadcast on register |
474
- | | `index.ts` | Central tool registration (119 tools) |
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 &rarr; 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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"}