@iworkforces/tracelattice 2.0.8 → 2.1.2
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 +89 -64
- package/dist/ServerConfig.d.ts +1 -1
- package/dist/ServerConfig.js.map +1 -1
- package/dist/cli.js +18 -73
- package/dist/cli.js.map +1 -1
- package/dist/config/ConfigLoader.d.ts +29 -26
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +40 -36
- package/dist/config/ConfigLoader.js.map +1 -1
- package/dist/contracts/PersistenceBackend.d.ts +7 -108
- package/dist/contracts/PersistenceBackend.d.ts.map +1 -1
- package/dist/contracts/PersistenceBackend.js +1 -6
- package/dist/contracts/calibrator.d.ts +6 -6
- package/dist/contracts/calibrator.d.ts.map +1 -1
- package/dist/contracts/ids.d.ts +1 -8
- package/dist/contracts/ids.d.ts.map +1 -1
- package/dist/contracts/ids.js +2 -3
- package/dist/contracts/ids.js.map +1 -1
- package/dist/contracts/interfaces.d.ts +4 -6
- package/dist/contracts/interfaces.d.ts.map +1 -1
- package/dist/contracts/persistence-work.d.ts +2 -3
- package/dist/contracts/persistence-work.d.ts.map +1 -1
- package/dist/core/HistoryManager.d.ts +12 -16
- package/dist/core/HistoryManager.d.ts.map +1 -1
- package/dist/core/HistoryManager.js +19 -40
- package/dist/core/HistoryManager.js.map +1 -1
- package/dist/core/IHistoryManager.d.ts +22 -30
- package/dist/core/IHistoryManager.d.ts.map +1 -1
- package/dist/core/InputNormalizer.d.ts +7 -24
- package/dist/core/InputNormalizer.d.ts.map +1 -1
- package/dist/core/InputNormalizer.js +3 -9
- package/dist/core/InputNormalizer.js.map +1 -1
- package/dist/core/PersistenceBuffer.d.ts +3 -20
- package/dist/core/PersistenceBuffer.d.ts.map +1 -1
- package/dist/core/PersistenceBuffer.js +1 -4
- package/dist/core/PersistenceBuffer.js.map +1 -1
- package/dist/core/PersistenceRestore.d.ts.map +1 -1
- package/dist/core/PersistenceRestore.js +4 -10
- package/dist/core/PersistenceRestore.js.map +1 -1
- package/dist/core/PersistenceWriter.d.ts.map +1 -1
- package/dist/core/PersistenceWriter.js +3 -12
- package/dist/core/PersistenceWriter.js.map +1 -1
- package/dist/core/SessionErrors.d.ts +0 -11
- package/dist/core/SessionErrors.d.ts.map +1 -1
- package/dist/core/SessionErrors.js +1 -14
- package/dist/core/SessionErrors.js.map +1 -1
- package/dist/core/SessionLock.d.ts +4 -5
- package/dist/core/SessionLock.d.ts.map +1 -1
- package/dist/core/SessionLock.js +5 -10
- package/dist/core/SessionLock.js.map +1 -1
- package/dist/core/SessionManager.d.ts +0 -2
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +3 -5
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/SessionResetCoordinator.d.ts +10 -7
- package/dist/core/SessionResetCoordinator.d.ts.map +1 -1
- package/dist/core/SessionResetCoordinator.js +10 -28
- package/dist/core/SessionResetCoordinator.js.map +1 -1
- package/dist/core/ThoughtEvaluator.d.ts +5 -5
- package/dist/core/ThoughtEvaluator.d.ts.map +1 -1
- package/dist/core/ThoughtEvaluator.js +4 -40
- package/dist/core/ThoughtEvaluator.js.map +1 -1
- package/dist/core/ThoughtProcessor.d.ts +10 -3
- package/dist/core/ThoughtProcessor.d.ts.map +1 -1
- package/dist/core/ThoughtProcessor.js +34 -38
- package/dist/core/ThoughtProcessor.js.map +1 -1
- package/dist/core/VerificationOutcomeAdmission.d.ts.map +1 -1
- package/dist/core/VerificationOutcomeAdmission.js +5 -7
- package/dist/core/VerificationOutcomeAdmission.js.map +1 -1
- package/dist/core/evaluator/Calibrator.d.ts +1 -1
- package/dist/core/evaluator/Calibrator.d.ts.map +1 -1
- package/dist/core/evaluator/Calibrator.js +2 -5
- package/dist/core/evaluator/Calibrator.js.map +1 -1
- package/dist/core/evaluator/internals.d.ts +0 -4
- package/dist/core/evaluator/internals.d.ts.map +1 -1
- package/dist/core/evaluator/internals.js +1 -3
- package/dist/core/evaluator/internals.js.map +1 -1
- package/dist/core/graph/Edge.d.ts +1 -1
- package/dist/core/graph/EdgeEmitter.d.ts +2 -4
- package/dist/core/graph/EdgeEmitter.d.ts.map +1 -1
- package/dist/core/graph/EdgeEmitter.js +2 -4
- package/dist/core/graph/EdgeEmitter.js.map +1 -1
- package/dist/core/reasoning/OutcomeRecorder.d.ts +0 -1
- package/dist/core/reasoning/OutcomeRecorder.d.ts.map +1 -1
- package/dist/core/reasoning/OutcomeRecorder.js.map +1 -1
- package/dist/core/reasoning/strategies/SequentialStrategy.d.ts +3 -3
- package/dist/core/reasoning/strategies/SequentialStrategy.js.map +1 -1
- package/dist/core/thought.d.ts +2 -1
- package/dist/core/thought.d.ts.map +1 -1
- package/dist/errors.d.ts +4 -20
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -28
- package/dist/errors.js.map +1 -1
- package/dist/lib.d.ts +13 -20
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +4 -7
- package/dist/lib.js.map +1 -1
- package/dist/logger/NullLogger.d.ts +9 -11
- package/dist/logger/NullLogger.d.ts.map +1 -1
- package/dist/logger/NullLogger.js.map +1 -1
- package/dist/persistence/FilePersistence.d.ts +3 -12
- package/dist/persistence/FilePersistence.d.ts.map +1 -1
- package/dist/persistence/FilePersistence.js +9 -61
- package/dist/persistence/FilePersistence.js.map +1 -1
- package/dist/persistence/FileSnapshotV2.d.ts +2 -2
- package/dist/persistence/FileSnapshotV2.js +2 -2
- package/dist/persistence/FileSnapshotV2.js.map +1 -1
- package/dist/persistence/FileWriter.d.ts +1 -0
- package/dist/persistence/FileWriter.d.ts.map +1 -1
- package/dist/persistence/FileWriter.js +3 -3
- package/dist/persistence/FileWriter.js.map +1 -1
- package/dist/persistence/MemoryPersistence.d.ts +5 -15
- package/dist/persistence/MemoryPersistence.d.ts.map +1 -1
- package/dist/persistence/MemoryPersistence.js +6 -40
- package/dist/persistence/MemoryPersistence.js.map +1 -1
- package/dist/persistence/PersistenceCodec.js +1 -3
- package/dist/persistence/PersistenceCodec.js.map +1 -1
- package/dist/persistence/PersistenceErrors.d.ts +0 -6
- package/dist/persistence/PersistenceErrors.d.ts.map +1 -1
- package/dist/persistence/PersistenceErrors.js +1 -9
- package/dist/persistence/PersistenceErrors.js.map +1 -1
- package/dist/persistence/PersistenceScope.d.ts.map +1 -1
- package/dist/persistence/PersistenceScope.js +2 -2
- package/dist/persistence/PersistenceScope.js.map +1 -1
- package/dist/persistence/SqlitePersistence.d.ts +3 -10
- package/dist/persistence/SqlitePersistence.d.ts.map +1 -1
- package/dist/persistence/SqlitePersistence.js +2 -26
- package/dist/persistence/SqlitePersistence.js.map +1 -1
- package/dist/persistence/SqliteSchemaV2.d.ts.map +1 -1
- package/dist/persistence/SqliteSchemaV2.js +3 -12
- package/dist/persistence/SqliteSchemaV2.js.map +1 -1
- package/dist/pool/ConnectionPool.d.ts +3 -12
- package/dist/pool/ConnectionPool.d.ts.map +1 -1
- package/dist/pool/ConnectionPool.js +5 -8
- package/dist/pool/ConnectionPool.js.map +1 -1
- package/dist/pool/IConnectionPool.d.ts +3 -9
- package/dist/pool/IConnectionPool.d.ts.map +1 -1
- package/dist/registry/BaseRegistry.d.ts +10 -2
- package/dist/registry/BaseRegistry.d.ts.map +1 -1
- package/dist/registry/BaseRegistry.js +128 -81
- package/dist/registry/BaseRegistry.js.map +1 -1
- package/dist/registry/SkillRegistry.d.ts +1 -7
- package/dist/registry/SkillRegistry.d.ts.map +1 -1
- package/dist/registry/SkillRegistry.js +0 -15
- package/dist/registry/SkillRegistry.js.map +1 -1
- package/dist/registry/ToolRegistry.d.ts +1 -9
- package/dist/registry/ToolRegistry.d.ts.map +1 -1
- package/dist/registry/ToolRegistry.js +0 -21
- package/dist/registry/ToolRegistry.js.map +1 -1
- package/dist/schema.d.ts +2 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +3 -3
- package/dist/schema.js.map +1 -1
- package/dist/transport/BaseTransport.d.ts +0 -9
- package/dist/transport/BaseTransport.d.ts.map +1 -1
- package/dist/transport/BaseTransport.js +0 -11
- package/dist/transport/BaseTransport.js.map +1 -1
- package/dist/watchers/SkillWatcher.d.ts.map +1 -1
- package/dist/watchers/SkillWatcher.js +1 -1
- package/dist/watchers/SkillWatcher.js.map +1 -1
- package/package.json +1 -1
- package/dist/contracts/PersistenceBackend.js.map +0 -1
- package/dist/persistence/FileLegacyImport.d.ts +0 -2
- package/dist/persistence/FileLegacyImport.d.ts.map +0 -1
- package/dist/persistence/FileLegacyImport.js +0 -183
- package/dist/persistence/FileLegacyImport.js.map +0 -1
- package/dist/persistence/SessionScopedPersistence.d.ts +0 -4
- package/dist/persistence/SessionScopedPersistence.d.ts.map +0 -1
- package/dist/persistence/SessionScopedPersistence.js +0 -9
- package/dist/persistence/SessionScopedPersistence.js.map +0 -1
- package/dist/persistence/SqliteLegacyImport.d.ts +0 -14
- package/dist/persistence/SqliteLegacyImport.d.ts.map +0 -1
- package/dist/persistence/SqliteLegacyImport.js +0 -136
- package/dist/persistence/SqliteLegacyImport.js.map +0 -1
- package/dist/persistence/SqliteLegacySchema.d.ts +0 -15
- package/dist/persistence/SqliteLegacySchema.d.ts.map +0 -1
- package/dist/persistence/SqliteLegacySchema.js +0 -72
- package/dist/persistence/SqliteLegacySchema.js.map +0 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ An MCP server that gives AI agents structured sequential thinking with tool and
|
|
|
16
16
|
- Tool and skill recommendations with confidence scores, rationales, and automatic discovery
|
|
17
17
|
- Per-session isolation with TTL eviction and LRU caching
|
|
18
18
|
- CLI transports: stdio (default) and Streamable HTTP (production). A stateless HTTP JSON-RPC transport is also available as a library transport
|
|
19
|
-
- Strict TypeScript, Valibot validation, and
|
|
19
|
+
- Strict TypeScript, Valibot validation, and a 20-service DI container
|
|
20
20
|
|
|
21
21
|
## Install
|
|
22
22
|
|
|
@@ -36,11 +36,11 @@ User-scoped (`~/.claude.json`) or project-scoped (`.mcp.json` in project root):
|
|
|
36
36
|
|
|
37
37
|
```json
|
|
38
38
|
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"tracelattice": {
|
|
41
|
+
"command": "tracelattice"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
44
|
}
|
|
45
45
|
```
|
|
46
46
|
|
|
@@ -85,21 +85,18 @@ Global (`~/.config/opencode/opencode.json`) or project-scoped (`.opencode.json`)
|
|
|
85
85
|
|
|
86
86
|
```json
|
|
87
87
|
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
88
|
+
"mcpServers": {
|
|
89
|
+
"tracelattice": {
|
|
90
|
+
"type": "local",
|
|
91
|
+
"command": ["npx", "-y", "@iworkforces/tracelattice"],
|
|
92
|
+
"enabled": true,
|
|
93
|
+
"environment": {
|
|
94
|
+
"TRACELATTICE_TRANSPORT_TYPE": "stdio",
|
|
95
|
+
"TRACELATTICE_MAX_HISTORY_SIZE": "10000",
|
|
96
|
+
"TRACELATTICE_LOG_LEVEL": "debug"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
103
100
|
}
|
|
104
101
|
```
|
|
105
102
|
|
|
@@ -107,24 +104,25 @@ Global (`~/.config/opencode/opencode.json`) or project-scoped (`.opencode.json`)
|
|
|
107
104
|
|
|
108
105
|
### Server
|
|
109
106
|
|
|
110
|
-
Set `
|
|
107
|
+
Set `TRACELATTICE_LOG_LEVEL` in the process environment to `debug`, `info`, `warn`, or `error`:
|
|
111
108
|
|
|
112
109
|
```bash
|
|
113
|
-
|
|
110
|
+
TRACELATTICE_LOG_LEVEL=debug tracelattice
|
|
114
111
|
```
|
|
115
112
|
|
|
116
113
|
Environment variables override values from configuration files.
|
|
117
114
|
|
|
118
|
-
| Variable
|
|
119
|
-
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
115
|
+
| Variable | Default | Description |
|
|
116
|
+
| --------------------------------------- | ------------ | ------------------------------------------- |
|
|
117
|
+
| `TRACELATTICE_CONFIG` | search paths | Explicit YAML or JSON configuration file |
|
|
118
|
+
| `TRACELATTICE_MAX_HISTORY_SIZE` | `10000` | Maximum thoughts to keep in history |
|
|
119
|
+
| `TRACELATTICE_MAX_BRANCHES` | `50` | Maximum number of branches |
|
|
120
|
+
| `TRACELATTICE_MAX_BRANCH_SIZE` | `100` | Maximum size of each branch |
|
|
121
|
+
| `TRACELATTICE_LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error` |
|
|
122
|
+
| `TRACELATTICE_PRETTY_LOG` | `true` | Enable pretty log output |
|
|
123
|
+
| `TRACELATTICE_SESSION_MAX_PER_OWNER` | `50` | Maximum isolated sessions per owner |
|
|
124
|
+
| `TRACELATTICE_TOOL_INTERLEAVE_TTL_MS` | `60000` | Suspended tool-call token TTL in ms |
|
|
125
|
+
| `TRACELATTICE_TOOL_INTERLEAVE_SWEEP_MS` | `60000` | Expired suspension cleanup interval in ms |
|
|
128
126
|
|
|
129
127
|
### Config files
|
|
130
128
|
|
|
@@ -163,46 +161,58 @@ maxSessionsPerOwner: 50
|
|
|
163
161
|
|
|
164
162
|
All feature flags default to enabled in `ServerConfig`. Set a boolean flag to `false` or `0` to opt out, or to `true` or `1` to opt back in.
|
|
165
163
|
|
|
166
|
-
| Variable
|
|
167
|
-
|
|
168
|
-
| `TRACELATTICE_FEATURES_DAG_EDGES`
|
|
169
|
-
| `TRACELATTICE_FEATURES_CALIBRATION`
|
|
170
|
-
| `TRACELATTICE_FEATURES_COMPRESSION`
|
|
171
|
-
| `TRACELATTICE_FEATURES_TOOL_INTERLEAVE`
|
|
172
|
-
| `TRACELATTICE_FEATURES_NEW_THOUGHT_TYPES`
|
|
173
|
-
| `TRACELATTICE_FEATURES_OUTCOME_RECORDING`
|
|
174
|
-
| `TRACELATTICE_FEATURES_REASONING_STRATEGY` | Strategy: `sequential` (default) or `tot`
|
|
164
|
+
| Variable | Description |
|
|
165
|
+
| ------------------------------------------ | ------------------------------------------------------------------------ |
|
|
166
|
+
| `TRACELATTICE_FEATURES_DAG_EDGES` | Enable DAG edges for thought relationships |
|
|
167
|
+
| `TRACELATTICE_FEATURES_CALIBRATION` | Enable confidence calibration with Beta(2,2) priors |
|
|
168
|
+
| `TRACELATTICE_FEATURES_COMPRESSION` | Enable branch compression for cold branches |
|
|
169
|
+
| `TRACELATTICE_FEATURES_TOOL_INTERLEAVE` | Enable suspend/resume for tool calls |
|
|
170
|
+
| `TRACELATTICE_FEATURES_NEW_THOUGHT_TYPES` | Enable tool_call, tool_observation, assumption, decomposition, backtrack |
|
|
171
|
+
| `TRACELATTICE_FEATURES_OUTCOME_RECORDING` | Enable outcome recording for tool results |
|
|
172
|
+
| `TRACELATTICE_FEATURES_REASONING_STRATEGY` | Strategy: `sequential` (default) or `tot` |
|
|
175
173
|
|
|
176
174
|
### Transport
|
|
177
175
|
|
|
178
|
-
| Variable
|
|
179
|
-
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
| `
|
|
185
|
-
| `
|
|
186
|
-
| `
|
|
176
|
+
| Variable | Default | Description |
|
|
177
|
+
| --------------------------------------- | ----------------------- | -------------------------------------------- |
|
|
178
|
+
| `TRACELATTICE_TRANSPORT_TYPE` | `stdio` | Transport: `stdio` or `streamable-http` |
|
|
179
|
+
| `TRACELATTICE_STREAMABLE_HTTP_PORT` | `9007` | Port for Streamable HTTP server |
|
|
180
|
+
| `TRACELATTICE_STREAMABLE_HTTP_HOST` | `localhost` | Host for Streamable HTTP server |
|
|
181
|
+
| `TRACELATTICE_STREAMABLE_HTTP_STATEFUL` | `true` | Enable stateful session tracking |
|
|
182
|
+
| `TRACELATTICE_CORS_ORIGIN` | `*` | CORS origin |
|
|
183
|
+
| `TRACELATTICE_ENABLE_CORS` | `true` | Enable CORS preflight |
|
|
184
|
+
| `TRACELATTICE_ALLOWED_HOSTS` | derived from bound host | Comma-separated allowed `Host` header values |
|
|
187
185
|
|
|
188
186
|
### Skill discovery
|
|
189
187
|
|
|
190
|
-
| Variable
|
|
191
|
-
|
|
192
|
-
| `
|
|
193
|
-
| `
|
|
194
|
-
| `
|
|
188
|
+
| Variable | Default | Description |
|
|
189
|
+
| --------------------------------------- | -------------------------------------- | ------------------------------------------------------- |
|
|
190
|
+
| `TRACELATTICE_SKILL_DIRS` | `.claude/skills:<home>/.claude/skills` | Colon-separated skill directories |
|
|
191
|
+
| `TRACELATTICE_TOOL_DIRS` | `.claude/tools:<home>/.claude/tools` | Colon-separated tool directories |
|
|
192
|
+
| `TRACELATTICE_DISCOVERY_CACHE_TTL` | `300` | Discovery cache TTL in seconds; stored internally as ms |
|
|
193
|
+
| `TRACELATTICE_DISCOVERY_CACHE_MAX_SIZE` | `100` | Discovery cache max entries |
|
|
194
|
+
| `TRACELATTICE_WATCHER_VERBOSE` | unset | Log skill watcher events when set to `true` |
|
|
195
195
|
|
|
196
196
|
## Transports
|
|
197
197
|
|
|
198
|
-
Set `
|
|
198
|
+
Set `TRACELATTICE_TRANSPORT_TYPE` to pick one:
|
|
199
199
|
|
|
200
|
-
| Transport
|
|
201
|
-
|
|
202
|
-
| `stdio` (default) | Local MCP clients
|
|
203
|
-
| `streamable-http` | Production deployments | `
|
|
200
|
+
| Transport | When to use | Command |
|
|
201
|
+
| ----------------- | ---------------------- | ---------------------------------------------------------- |
|
|
202
|
+
| `stdio` (default) | Local MCP clients | `tracelattice` |
|
|
203
|
+
| `streamable-http` | Production deployments | `TRACELATTICE_TRANSPORT_TYPE=streamable-http tracelattice` |
|
|
204
204
|
|
|
205
|
-
The Streamable HTTP endpoint defaults to `POST /mcp` for JSON-RPC requests and supports stateful sessions via the `Mcp-Session-Id` header. `GET /mcp` is not allowed. The library also exposes `HttpTransport` for stateless JSON-RPC over HTTP, but the CLI does not select it with `
|
|
205
|
+
The Streamable HTTP endpoint defaults to `POST /mcp` for JSON-RPC requests and supports stateful sessions via the `Mcp-Session-Id` header. `GET /mcp` is not allowed. The library also exposes `HttpTransport` for stateless JSON-RPC over HTTP, but the CLI does not select it with `TRACELATTICE_TRANSPORT_TYPE`.
|
|
206
|
+
|
|
207
|
+
### Session model
|
|
208
|
+
|
|
209
|
+
TraceLattice uses separate session concepts with separate identifiers:
|
|
210
|
+
|
|
211
|
+
- A **thought session** is the required `session_id` in every `sequentialthinking_tools` call. Callers choose an explicit named session, and each successful response echoes that identifier. The retired `__global__` value and omitted `session_id` are rejected. Library reads such as `getBranches(sessionId)` also require the thought session explicitly.
|
|
212
|
+
- An **MCP transport session** is the Streamable HTTP connection identified by the `Mcp-Session-Id` header. It controls transport state. Request-owner identity is a separate authorization context; neither supplies or replaces a thought `session_id`.
|
|
213
|
+
- An **all-session administration operation** is explicit. `resetAll()`, persistence `clearAll()`, and complete server shutdown intentionally act across every thought session. They are not fallback behavior for an omitted thought session.
|
|
214
|
+
|
|
215
|
+
`ConnectionPool` slots are an optional HTTP isolation layer and are separate from both thought sessions and MCP transport sessions.
|
|
206
216
|
|
|
207
217
|
### Stateless HTTP library API
|
|
208
218
|
|
|
@@ -231,6 +241,21 @@ export async function startHttpTransport(mcpServer: McpServer): Promise<ITranspo
|
|
|
231
241
|
|
|
232
242
|
Call and await `transport.stop()` during application shutdown.
|
|
233
243
|
|
|
244
|
+
## Current v2 contract
|
|
245
|
+
|
|
246
|
+
TraceLattice exposes only the current API and persistence contract. There are no compatibility aliases or data import shims.
|
|
247
|
+
|
|
248
|
+
| Removed surface | Current replacement |
|
|
249
|
+
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
250
|
+
| Omitted thought sessions or the retired `__global__` sentinel | Supply an explicit named `session_id` on every thought; use explicit all-session administration only when intentionally operating across every session |
|
|
251
|
+
| Unscoped persistence operations | `saveThoughtForSession`, `loadHistoryForSession`, `saveBranchForSession`, `deleteBranchForSession`, `loadBranchForSession`, `listBranchesForSession`, `clearSession`, and `clearAll` |
|
|
252
|
+
| Tool/skill-specific registry aliases | Canonical `add`, `remove`, `update`, `get`, `getAll`, `has`, and `getNames` methods |
|
|
253
|
+
| Synchronous server/history clearing | Await `resetSession(sessionId)` or `resetAll()` |
|
|
254
|
+
| Partial server cleanup | Await `dispose()` to release the server and all container-owned resources |
|
|
255
|
+
| Unprefixed environment variables | The `TRACELATTICE_*` variables documented above |
|
|
256
|
+
|
|
257
|
+
File persistence accepts the strict v2 `snapshot.json` document. SQLite persistence accepts the exact v2 schema with its authoritative `schema_version` row. Invalid, unknown, or differently versioned storage fails closed; startup does not rewrite it.
|
|
258
|
+
|
|
234
259
|
## Development
|
|
235
260
|
|
|
236
261
|
```bash
|
|
@@ -261,9 +286,9 @@ src/
|
|
|
261
286
|
│ ├── reasoning/ # OutcomeRecorder + strategies (Sequential, TreeOfThought, StrategyFactory)
|
|
262
287
|
│ └── tools/ # InMemorySuspensionStore (suspend/resume)
|
|
263
288
|
├── contracts/ # Shared interfaces and branded ID types (cross-module coupling point)
|
|
264
|
-
├── persistence/ # File, SQLite, Memory
|
|
289
|
+
├── persistence/ # Session-scoped File v2, SQLite v2, and Memory sinks
|
|
265
290
|
├── transport/ # Streamable HTTP, HTTP JSON-RPC
|
|
266
|
-
├── di/ # IoC container (
|
|
291
|
+
├── di/ # IoC container (20 services) + ServiceRegistry
|
|
267
292
|
├── registry/ # Tool/Skill discovery with frontmatter parsing and LRU cache
|
|
268
293
|
├── config/ # YAML + env var loading
|
|
269
294
|
├── cache/ # LRU+TTL discovery cache
|
package/dist/ServerConfig.d.ts
CHANGED
|
@@ -86,7 +86,7 @@ export interface ServerConfigOptions {
|
|
|
86
86
|
*/
|
|
87
87
|
persistenceMaxRetries?: number;
|
|
88
88
|
/**
|
|
89
|
-
* Feature flag overrides. Missing fields are filled with defaults (all
|
|
89
|
+
* Feature flag overrides. Missing fields are filled with defaults (all ON,
|
|
90
90
|
* reasoningStrategy='sequential').
|
|
91
91
|
*/
|
|
92
92
|
features?: Partial<FeatureFlags>;
|
package/dist/ServerConfig.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerConfig.js","sources":["../src/ServerConfig.ts"],"sourcesContent":["/**\n * Server configuration management with validation.\n *\n * This module provides the `ServerConfig` class which handles all server configuration\n * with built-in validation and sensible defaults. Configuration values are validated\n * on construction and warnings are emitted for out-of-range values.\n *\n * @module ServerConfig\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { ConfigurationError } from './errors.js';\nimport type { PersistenceConfig } from './contracts/PersistenceBackend.js';\n\n/**\n * Configuration options for creating a `ServerConfig` instance.\n *\n * All properties are optional with sensible defaults applied during validation.\n *\n * @example\n * ```typescript\n * const options: ServerConfigOptions = {\n * maxHistorySize: 500,\n * maxBranches: 25,\n * skillDirs: ['./custom-skills'],\n * toolDirs: ['./custom-tools'],\n * persistence: { enabled: true, backend: 'sqlite' }\n * };\n * ```\n */\n\nimport type { FeatureFlags } from './contracts/features.js';\nexport interface ServerConfigOptions {\n\t/**\n\t * Maximum number of thoughts to keep in history.\n\t * @default 1000\n\t */\n\tmaxHistorySize?: number;\n\n\t/**\n\t * Maximum number of branches to maintain.\n\t * @default 50\n\t */\n\tmaxBranches?: number;\n\n\t/**\n\t * Maximum size of each branch.\n\t * @default 100\n\t */\n\tmaxBranchSize?: number;\n\n\t/**\n\t * Directory paths to search for skills.\n\t * @default ['.claude/skills', '~/.claude/skills', '.agents/skills', '~/.agents/skills']\n\t */\n\tskillDirs?: string[];\n\n\t/**\n\t * Directory paths to search for tools.\n\t * @default ['.claude/tools', '~/.claude/tools']\n\t */\n\ttoolDirs?: string[];\n\n\t/**\n\t * Discovery cache configuration.\n\t */\n\tdiscoveryCache?: {\n\t\t/**\n\t\t * Time-to-live for cache entries in milliseconds.\n\t\t * @default 300000 (5 minutes)\n\t\t */\n\t\tttl?: number;\n\t\t/**\n\t\t * Maximum number of entries in the cache.\n\t\t * @default 100\n\t\t */\n\t\tmaxSize?: number;\n\t};\n\n\t/**\n\t * Persistence configuration for storing history and state.\n\t */\n\tpersistence?: PersistenceConfig;\n\n\t/**\n\t * Maximum number of thoughts to buffer before flushing to persistence.\n\t * @default 100\n\t */\n\tpersistenceBufferSize?: number;\n\n\t/**\n\t * Interval in milliseconds between periodic persistence flushes.\n\t * @default 1000\n\t */\n\tpersistenceFlushInterval?: number;\n\n\t/**\n\t * Maximum number of retries for failed persistence flushes.\n\t * @default 3\n\t */\n\tpersistenceMaxRetries?: number;\n\n\t/**\n\t * Feature flag overrides. Missing fields are filled with defaults (all OFF,\n\t * reasoningStrategy='sequential').\n\t */\n\tfeatures?: Partial<FeatureFlags>;\n\n\t/**\n\t * TTL in milliseconds for suspended tool-interleave entries in SuspensionStore.\n\t * @default 60000\n\t */\n\ttoolInterleaveTtlMs?: number;\n\n\t/**\n\t * Sweep interval in milliseconds for SuspensionStore expiration cleanup.\n\t * @default 60000\n\t */\n\ttoolInterleaveSweepMs?: number;\n\n\t/**\n\t * Maximum sessions per owner. Prevents one user from consuming all session slots.\n\t * @default 50\n\t */\n\tmaxSessionsPerOwner?: number;\n}\n\n/**\n * Server configuration with validation and defaults.\n *\n * This class manages all server configuration including history limits,\n * branch limits, discovery directories, cache settings, and persistence.\n * All values are validated on construction with appropriate defaults applied.\n *\n * @remarks\n * - Values outside recommended ranges trigger warnings but are still applied\n * - Environment variables override file-based configuration\n * - The `toJSON()` method provides a plain object representation\n *\n * @example\n * ```typescript\n * // Using defaults\n * const config1 = new ServerConfig();\n * console.log(config1.maxHistorySize); // 10000\n *\n * // With custom options\n * const config2 = new ServerConfig({\n * maxHistorySize: 500,\n * persistence: { enabled: true, backend: 'file', options: { dataDir: './data' } }\n * });\n *\n * // Export as plain object\n * const json = config2.toJSON();\n * ```\n */\nexport class ServerConfig {\n\t/** Maximum number of thoughts to keep in history. */\n\tpublic maxHistorySize: number;\n\n\t/** Maximum number of branches to maintain. */\n\tpublic maxBranches: number;\n\n\t/** Maximum size of each branch. */\n\tpublic maxBranchSize: number;\n\n\t/** Directory paths to search for skills. */\n\tpublic skillDirs: string[];\n\n\t/** Directory paths to search for tools. */\n\tpublic toolDirs: string[];\n\n\t/** Discovery cache configuration. */\n\tpublic discoveryCache: { ttl: number; maxSize: number };\n\n\t/** Persistence configuration. */\n\tpublic persistence: PersistenceConfig;\n\n\t/** Maximum number of thoughts to buffer before flushing to persistence. */\n\tpublic persistenceBufferSize: number;\n\n\t/** Interval in milliseconds between periodic persistence flushes. */\n\tpublic persistenceFlushInterval: number;\n\n\t/** Maximum number of retries for failed persistence flushes. */\n\tpublic persistenceMaxRetries: number;\n\n\t/** Feature flag toggles. */\n\tpublic features: FeatureFlags;\n\n\t/** TTL in milliseconds for suspended tool-interleave entries. */\n\tpublic toolInterleaveTtlMs: number;\n\n\t/** Sweep interval in milliseconds for SuspensionStore expiration cleanup. */\n\tpublic toolInterleaveSweepMs: number;\n\n\t/** Maximum sessions per owner (LRU per-owner bucket). */\n\tpublic maxSessionsPerOwner: number;\n\n\t/**\n\t * Creates a new ServerConfig instance with validation.\n\t *\n\t * All values are validated and defaults are applied for undefined options.\n\t * Warnings are emitted to console for values outside recommended ranges.\n\t *\n\t * @param options - Optional configuration overrides\n\t *\n\t * @example\n\t * ```typescript\n\t * const config = new ServerConfig({\n\t * maxHistorySize: 500,\n\t * skillDirs: ['./my-skills']\n\t * });\n\t * ```\n\t */\n\tconstructor(options: ServerConfigOptions = {}) {\n\t\tthis.maxHistorySize = this.validateMaxHistorySize(options.maxHistorySize);\n\t\tthis.maxBranches = this.validateMaxBranches(options.maxBranches);\n\t\tthis.maxBranchSize = this.validateMaxBranchSize(options.maxBranchSize);\n\t\tthis.skillDirs = this.validateSkillDirs(options.skillDirs);\n\t\tthis.toolDirs = this.validateToolDirs(options.toolDirs);\n\t\tthis.discoveryCache = this.validateDiscoveryCache(options.discoveryCache);\n\t\tthis.persistence = this.validatePersistence(options.persistence);\n\t\tthis.persistenceBufferSize = this.validatePersistenceBufferSize(options.persistenceBufferSize);\n\t\tthis.persistenceFlushInterval = this.validatePersistenceFlushInterval(\n\t\t\toptions.persistenceFlushInterval\n\t\t);\n\t\tthis.persistenceMaxRetries = this.validatePersistenceMaxRetries(options.persistenceMaxRetries);\n\t\tthis.features = this.validateFeatures(options.features);\n\t\tthis.toolInterleaveTtlMs = this.validatePositiveMs(\n\t\t\toptions.toolInterleaveTtlMs,\n\t\t\t60000,\n\t\t\t'toolInterleaveTtlMs'\n\t\t);\n\t\tthis.toolInterleaveSweepMs = this.validatePositiveMs(\n\t\t\toptions.toolInterleaveSweepMs,\n\t\t\t60000,\n\t\t\t'toolInterleaveSweepMs'\n\t\t);\n\t\tthis.maxSessionsPerOwner = this.validateMaxSessionsPerOwner(options.maxSessionsPerOwner);\n\t}\n\n\t/**\n\t * Validates the max history size value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (1000)\n\t * @private\n\t */\n\tprivate validateMaxHistorySize(value?: number): number {\n\t\tconst defaultValue = 10000;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxHistorySize must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`maxHistorySize must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 10000) {\n\t\t\tthrow new ConfigurationError(`maxHistorySize must not exceed 10000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the max branches value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (50)\n\t * @private\n\t */\n\tprivate validateMaxBranches(value?: number): number {\n\t\tconst defaultValue = 50;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxBranches must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 0) {\n\t\t\tthrow new ConfigurationError(`maxBranches must be non-negative, got ${value}`);\n\t\t}\n\t\tif (value > 1000) {\n\t\t\tthrow new ConfigurationError(`maxBranches must not exceed 1000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the max branch size value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (100)\n\t * @private\n\t */\n\tprivate validateMaxBranchSize(value?: number): number {\n\t\tconst defaultValue = 100;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxBranchSize must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`maxBranchSize must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 1000) {\n\t\t\tthrow new ConfigurationError(`maxBranchSize must not exceed 1000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the skill directories value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default ['.claude/skills', '~/.claude/skills', '.agents/skills', '~/.agents/skills']\n\t * @private\n\t */\n\tprivate validateSkillDirs(value?: string[]): string[] {\n\t\tconst defaultValue = [\n\t\t\t'.claude/skills',\n\t\t\tjoin(homedir(), '.claude/skills'),\n\t\t\t'.agents/skills',\n\t\t\tjoin(homedir(), '.agents/skills'),\n\t\t];\n\t\treturn value === undefined ? defaultValue : [...value];\n\t}\n\n\tprivate validateToolDirs(value?: string[]): string[] {\n\t\tconst defaultValue = ['.claude/tools', join(homedir(), '.claude/tools')];\n\t\treturn value === undefined ? defaultValue : [...value];\n\t}\n\n\t/**\n\t * Validates the discovery cache configuration.\n\t * @param value - The value to validate\n\t * @returns The validated value with defaults applied\n\t * @private\n\t */\n\tprivate validateDiscoveryCache(value?: { ttl?: number; maxSize?: number }): {\n\t\tttl: number;\n\t\tmaxSize: number;\n\t} {\n\t\treturn {\n\t\t\tttl: value?.ttl ?? 300000,\n\t\t\tmaxSize: value?.maxSize ?? 100,\n\t\t};\n\t}\n\n\t/**\n\t * Validates the persistence configuration.\n\t * @param value - The value to validate\n\t * @returns The validated value with defaults applied\n\t * @private\n\t */\n\tprivate validatePersistence(value?: PersistenceConfig): PersistenceConfig {\n\t\tif (!value) {\n\t\t\t// Default to in-memory (no actual persistence, just consistency)\n\t\t\treturn {\n\t\t\t\tenabled: false,\n\t\t\t\tbackend: 'memory',\n\t\t\t};\n\t\t}\n\n\t\t// Validate backend type\n\t\tconst validBackends = ['file', 'sqlite', 'memory'];\n\t\tconst backend = value.backend ?? 'memory';\n\t\tif (!validBackends.includes(backend)) {\n\t\t\tthrow new ConfigurationError(\n\t\t\t\t`persistence.backend must be one of ${validBackends.join(', ')}, got ${backend}`\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tenabled: value.enabled ?? false,\n\t\t\tbackend,\n\t\t\toptions: value.options ?? {},\n\t\t};\n\t}\n\n\t/**\n\t * Validates the persistence buffer size value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (100)\n\t * @private\n\t */\n\tprivate validatePersistenceBufferSize(value?: number): number {\n\t\tconst defaultValue = 100;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`persistenceBufferSize must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`persistenceBufferSize must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 10000) {\n\t\t\tthrow new ConfigurationError(`persistenceBufferSize must not exceed 10000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the persistence flush interval value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (1000)\n\t * @private\n\t */\n\tprivate validatePersistenceFlushInterval(value?: number): number {\n\t\tconst defaultValue = 1000;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(\n\t\t\t\t`persistenceFlushInterval must be a finite number, got ${value}`\n\t\t\t);\n\t\t}\n\t\tif (value < 100) {\n\t\t\tthrow new ConfigurationError(`persistenceFlushInterval must be at least 100, got ${value}`);\n\t\t}\n\t\tif (value > 60000) {\n\t\t\tthrow new ConfigurationError(`persistenceFlushInterval must not exceed 60000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the persistence max retries value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (3)\n\t * @private\n\t */\n\tprivate validatePersistenceMaxRetries(value?: number): number {\n\t\tconst defaultValue = 3;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`persistenceMaxRetries must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 0) {\n\t\t\tthrow new ConfigurationError(`persistenceMaxRetries must be non-negative, got ${value}`);\n\t\t}\n\t\tif (value > 10) {\n\t\t\tthrow new ConfigurationError(`persistenceMaxRetries must not exceed 10, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates feature flags and fills defaults for missing fields.\n\t * @param value - Partial feature flag overrides\n\t * @returns Fully populated FeatureFlags with defaults applied\n\t * @private\n\t */\n\tprivate validateFeatures(value?: Partial<FeatureFlags>): FeatureFlags {\n\t\tconst reasoningStrategy = value?.reasoningStrategy ?? 'sequential';\n\t\tif (reasoningStrategy !== 'sequential' && reasoningStrategy !== 'tot') {\n\t\t\tthrow new ConfigurationError(\n\t\t\t\t`features.reasoningStrategy must be one of sequential, tot, got ${reasoningStrategy}`\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tdagEdges: value?.dagEdges ?? true,\n\t\t\treasoningStrategy,\n\t\t\tcalibration: value?.calibration ?? true,\n\t\t\tcompression: value?.compression ?? true,\n\t\t\ttoolInterleave: value?.toolInterleave ?? true,\n\t\t\tnewThoughtTypes: value?.newThoughtTypes ?? true,\n\t\t\toutcomeRecording: value?.outcomeRecording ?? true,\n\t\t};\n\t}\n\n\t/**\n\t * Validates a positive millisecond value with a default fallback.\n\t * @param value - The value to validate\n\t * @param defaultValue - Default applied if value is undefined/null\n\t * @param fieldName - Field name for error messages\n\t * @returns The validated millisecond value\n\t * @private\n\t */\n\tprivate validatePositiveMs(\n\t\tvalue: number | undefined,\n\t\tdefaultValue: number,\n\t\tfieldName: string\n\t): number {\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`${fieldName} must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`${fieldName} must be at least 1, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the max sessions per owner value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (50)\n\t * @private\n\t */\n\tprivate validateMaxSessionsPerOwner(value?: number): number {\n\t\tconst defaultValue = 50;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxSessionsPerOwner must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`maxSessionsPerOwner must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 10000) {\n\t\t\tthrow new ConfigurationError(`maxSessionsPerOwner must not exceed 10000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Converts the configuration to a plain object.\n\t *\n\t * Useful for serialization, logging, or when a plain object representation\n\t * is preferred over the ServerConfig instance.\n\t *\n\t * @returns A plain object representation of the configuration\n\t *\n\t * @example\n\t * ```typescript\n\t * const config = new ServerConfig({ maxHistorySize: 500 });\n\t * const json = config.toJSON();\n\t * console.log(JSON.stringify(json, null, 2));\n\t * ```\n\t */\n\tpublic toJSON(): ServerConfigOptions {\n\t\treturn {\n\t\t\tmaxHistorySize: this.maxHistorySize,\n\t\t\tmaxBranches: this.maxBranches,\n\t\t\tmaxBranchSize: this.maxBranchSize,\n\t\t\tskillDirs: this.skillDirs,\n\t\t\ttoolDirs: this.toolDirs,\n\t\t\tdiscoveryCache: this.discoveryCache,\n\t\t\tpersistence: this.persistence,\n\t\t\tpersistenceBufferSize: this.persistenceBufferSize,\n\t\t\tpersistenceFlushInterval: this.persistenceFlushInterval,\n\t\t\tpersistenceMaxRetries: this.persistenceMaxRetries,\n\t\t\tfeatures: this.features,\n\t\t\ttoolInterleaveTtlMs: this.toolInterleaveTtlMs,\n\t\t\ttoolInterleaveSweepMs: this.toolInterleaveSweepMs,\n\t\t\tmaxSessionsPerOwner: this.maxSessionsPerOwner,\n\t\t};\n\t}\n}\n"],"names":["ServerConfig","options","value","defaultValue","Number","ConfigurationError","join","homedir","undefined","validBackends","backend","reasoningStrategy","fieldName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ServerConfig.js","sources":["../src/ServerConfig.ts"],"sourcesContent":["/**\n * Server configuration management with validation.\n *\n * This module provides the `ServerConfig` class which handles all server configuration\n * with built-in validation and sensible defaults. Configuration values are validated\n * on construction and warnings are emitted for out-of-range values.\n *\n * @module ServerConfig\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { ConfigurationError } from './errors.js';\nimport type { PersistenceConfig } from './contracts/PersistenceBackend.js';\n\n/**\n * Configuration options for creating a `ServerConfig` instance.\n *\n * All properties are optional with sensible defaults applied during validation.\n *\n * @example\n * ```typescript\n * const options: ServerConfigOptions = {\n * maxHistorySize: 500,\n * maxBranches: 25,\n * skillDirs: ['./custom-skills'],\n * toolDirs: ['./custom-tools'],\n * persistence: { enabled: true, backend: 'sqlite' }\n * };\n * ```\n */\n\nimport type { FeatureFlags } from './contracts/features.js';\nexport interface ServerConfigOptions {\n\t/**\n\t * Maximum number of thoughts to keep in history.\n\t * @default 1000\n\t */\n\tmaxHistorySize?: number;\n\n\t/**\n\t * Maximum number of branches to maintain.\n\t * @default 50\n\t */\n\tmaxBranches?: number;\n\n\t/**\n\t * Maximum size of each branch.\n\t * @default 100\n\t */\n\tmaxBranchSize?: number;\n\n\t/**\n\t * Directory paths to search for skills.\n\t * @default ['.claude/skills', '~/.claude/skills', '.agents/skills', '~/.agents/skills']\n\t */\n\tskillDirs?: string[];\n\n\t/**\n\t * Directory paths to search for tools.\n\t * @default ['.claude/tools', '~/.claude/tools']\n\t */\n\ttoolDirs?: string[];\n\n\t/**\n\t * Discovery cache configuration.\n\t */\n\tdiscoveryCache?: {\n\t\t/**\n\t\t * Time-to-live for cache entries in milliseconds.\n\t\t * @default 300000 (5 minutes)\n\t\t */\n\t\tttl?: number;\n\t\t/**\n\t\t * Maximum number of entries in the cache.\n\t\t * @default 100\n\t\t */\n\t\tmaxSize?: number;\n\t};\n\n\t/**\n\t * Persistence configuration for storing history and state.\n\t */\n\tpersistence?: PersistenceConfig;\n\n\t/**\n\t * Maximum number of thoughts to buffer before flushing to persistence.\n\t * @default 100\n\t */\n\tpersistenceBufferSize?: number;\n\n\t/**\n\t * Interval in milliseconds between periodic persistence flushes.\n\t * @default 1000\n\t */\n\tpersistenceFlushInterval?: number;\n\n\t/**\n\t * Maximum number of retries for failed persistence flushes.\n\t * @default 3\n\t */\n\tpersistenceMaxRetries?: number;\n\n\t/**\n\t * Feature flag overrides. Missing fields are filled with defaults (all ON,\n\t * reasoningStrategy='sequential').\n\t */\n\tfeatures?: Partial<FeatureFlags>;\n\n\t/**\n\t * TTL in milliseconds for suspended tool-interleave entries in SuspensionStore.\n\t * @default 60000\n\t */\n\ttoolInterleaveTtlMs?: number;\n\n\t/**\n\t * Sweep interval in milliseconds for SuspensionStore expiration cleanup.\n\t * @default 60000\n\t */\n\ttoolInterleaveSweepMs?: number;\n\n\t/**\n\t * Maximum sessions per owner. Prevents one user from consuming all session slots.\n\t * @default 50\n\t */\n\tmaxSessionsPerOwner?: number;\n}\n\n/**\n * Server configuration with validation and defaults.\n *\n * This class manages all server configuration including history limits,\n * branch limits, discovery directories, cache settings, and persistence.\n * All values are validated on construction with appropriate defaults applied.\n *\n * @remarks\n * - Values outside recommended ranges trigger warnings but are still applied\n * - Environment variables override file-based configuration\n * - The `toJSON()` method provides a plain object representation\n *\n * @example\n * ```typescript\n * // Using defaults\n * const config1 = new ServerConfig();\n * console.log(config1.maxHistorySize); // 10000\n *\n * // With custom options\n * const config2 = new ServerConfig({\n * maxHistorySize: 500,\n * persistence: { enabled: true, backend: 'file', options: { dataDir: './data' } }\n * });\n *\n * // Export as plain object\n * const json = config2.toJSON();\n * ```\n */\nexport class ServerConfig {\n\t/** Maximum number of thoughts to keep in history. */\n\tpublic maxHistorySize: number;\n\n\t/** Maximum number of branches to maintain. */\n\tpublic maxBranches: number;\n\n\t/** Maximum size of each branch. */\n\tpublic maxBranchSize: number;\n\n\t/** Directory paths to search for skills. */\n\tpublic skillDirs: string[];\n\n\t/** Directory paths to search for tools. */\n\tpublic toolDirs: string[];\n\n\t/** Discovery cache configuration. */\n\tpublic discoveryCache: { ttl: number; maxSize: number };\n\n\t/** Persistence configuration. */\n\tpublic persistence: PersistenceConfig;\n\n\t/** Maximum number of thoughts to buffer before flushing to persistence. */\n\tpublic persistenceBufferSize: number;\n\n\t/** Interval in milliseconds between periodic persistence flushes. */\n\tpublic persistenceFlushInterval: number;\n\n\t/** Maximum number of retries for failed persistence flushes. */\n\tpublic persistenceMaxRetries: number;\n\n\t/** Feature flag toggles. */\n\tpublic features: FeatureFlags;\n\n\t/** TTL in milliseconds for suspended tool-interleave entries. */\n\tpublic toolInterleaveTtlMs: number;\n\n\t/** Sweep interval in milliseconds for SuspensionStore expiration cleanup. */\n\tpublic toolInterleaveSweepMs: number;\n\n\t/** Maximum sessions per owner (LRU per-owner bucket). */\n\tpublic maxSessionsPerOwner: number;\n\n\t/**\n\t * Creates a new ServerConfig instance with validation.\n\t *\n\t * All values are validated and defaults are applied for undefined options.\n\t * Warnings are emitted to console for values outside recommended ranges.\n\t *\n\t * @param options - Optional configuration overrides\n\t *\n\t * @example\n\t * ```typescript\n\t * const config = new ServerConfig({\n\t * maxHistorySize: 500,\n\t * skillDirs: ['./my-skills']\n\t * });\n\t * ```\n\t */\n\tconstructor(options: ServerConfigOptions = {}) {\n\t\tthis.maxHistorySize = this.validateMaxHistorySize(options.maxHistorySize);\n\t\tthis.maxBranches = this.validateMaxBranches(options.maxBranches);\n\t\tthis.maxBranchSize = this.validateMaxBranchSize(options.maxBranchSize);\n\t\tthis.skillDirs = this.validateSkillDirs(options.skillDirs);\n\t\tthis.toolDirs = this.validateToolDirs(options.toolDirs);\n\t\tthis.discoveryCache = this.validateDiscoveryCache(options.discoveryCache);\n\t\tthis.persistence = this.validatePersistence(options.persistence);\n\t\tthis.persistenceBufferSize = this.validatePersistenceBufferSize(options.persistenceBufferSize);\n\t\tthis.persistenceFlushInterval = this.validatePersistenceFlushInterval(\n\t\t\toptions.persistenceFlushInterval\n\t\t);\n\t\tthis.persistenceMaxRetries = this.validatePersistenceMaxRetries(options.persistenceMaxRetries);\n\t\tthis.features = this.validateFeatures(options.features);\n\t\tthis.toolInterleaveTtlMs = this.validatePositiveMs(\n\t\t\toptions.toolInterleaveTtlMs,\n\t\t\t60000,\n\t\t\t'toolInterleaveTtlMs'\n\t\t);\n\t\tthis.toolInterleaveSweepMs = this.validatePositiveMs(\n\t\t\toptions.toolInterleaveSweepMs,\n\t\t\t60000,\n\t\t\t'toolInterleaveSweepMs'\n\t\t);\n\t\tthis.maxSessionsPerOwner = this.validateMaxSessionsPerOwner(options.maxSessionsPerOwner);\n\t}\n\n\t/**\n\t * Validates the max history size value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (1000)\n\t * @private\n\t */\n\tprivate validateMaxHistorySize(value?: number): number {\n\t\tconst defaultValue = 10000;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxHistorySize must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`maxHistorySize must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 10000) {\n\t\t\tthrow new ConfigurationError(`maxHistorySize must not exceed 10000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the max branches value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (50)\n\t * @private\n\t */\n\tprivate validateMaxBranches(value?: number): number {\n\t\tconst defaultValue = 50;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxBranches must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 0) {\n\t\t\tthrow new ConfigurationError(`maxBranches must be non-negative, got ${value}`);\n\t\t}\n\t\tif (value > 1000) {\n\t\t\tthrow new ConfigurationError(`maxBranches must not exceed 1000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the max branch size value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (100)\n\t * @private\n\t */\n\tprivate validateMaxBranchSize(value?: number): number {\n\t\tconst defaultValue = 100;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxBranchSize must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`maxBranchSize must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 1000) {\n\t\t\tthrow new ConfigurationError(`maxBranchSize must not exceed 1000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the skill directories value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default ['.claude/skills', '~/.claude/skills', '.agents/skills', '~/.agents/skills']\n\t * @private\n\t */\n\tprivate validateSkillDirs(value?: string[]): string[] {\n\t\tconst defaultValue = [\n\t\t\t'.claude/skills',\n\t\t\tjoin(homedir(), '.claude/skills'),\n\t\t\t'.agents/skills',\n\t\t\tjoin(homedir(), '.agents/skills'),\n\t\t];\n\t\treturn value === undefined ? defaultValue : [...value];\n\t}\n\n\tprivate validateToolDirs(value?: string[]): string[] {\n\t\tconst defaultValue = ['.claude/tools', join(homedir(), '.claude/tools')];\n\t\treturn value === undefined ? defaultValue : [...value];\n\t}\n\n\t/**\n\t * Validates the discovery cache configuration.\n\t * @param value - The value to validate\n\t * @returns The validated value with defaults applied\n\t * @private\n\t */\n\tprivate validateDiscoveryCache(value?: { ttl?: number; maxSize?: number }): {\n\t\tttl: number;\n\t\tmaxSize: number;\n\t} {\n\t\treturn {\n\t\t\tttl: value?.ttl ?? 300000,\n\t\t\tmaxSize: value?.maxSize ?? 100,\n\t\t};\n\t}\n\n\t/**\n\t * Validates the persistence configuration.\n\t * @param value - The value to validate\n\t * @returns The validated value with defaults applied\n\t * @private\n\t */\n\tprivate validatePersistence(value?: PersistenceConfig): PersistenceConfig {\n\t\tif (!value) {\n\t\t\t// Default to in-memory (no actual persistence, just consistency)\n\t\t\treturn {\n\t\t\t\tenabled: false,\n\t\t\t\tbackend: 'memory',\n\t\t\t};\n\t\t}\n\n\t\t// Validate backend type\n\t\tconst validBackends = ['file', 'sqlite', 'memory'];\n\t\tconst backend = value.backend ?? 'memory';\n\t\tif (!validBackends.includes(backend)) {\n\t\t\tthrow new ConfigurationError(\n\t\t\t\t`persistence.backend must be one of ${validBackends.join(', ')}, got ${backend}`\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tenabled: value.enabled ?? false,\n\t\t\tbackend,\n\t\t\toptions: value.options ?? {},\n\t\t};\n\t}\n\n\t/**\n\t * Validates the persistence buffer size value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (100)\n\t * @private\n\t */\n\tprivate validatePersistenceBufferSize(value?: number): number {\n\t\tconst defaultValue = 100;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`persistenceBufferSize must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`persistenceBufferSize must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 10000) {\n\t\t\tthrow new ConfigurationError(`persistenceBufferSize must not exceed 10000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the persistence flush interval value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (1000)\n\t * @private\n\t */\n\tprivate validatePersistenceFlushInterval(value?: number): number {\n\t\tconst defaultValue = 1000;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(\n\t\t\t\t`persistenceFlushInterval must be a finite number, got ${value}`\n\t\t\t);\n\t\t}\n\t\tif (value < 100) {\n\t\t\tthrow new ConfigurationError(`persistenceFlushInterval must be at least 100, got ${value}`);\n\t\t}\n\t\tif (value > 60000) {\n\t\t\tthrow new ConfigurationError(`persistenceFlushInterval must not exceed 60000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the persistence max retries value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (3)\n\t * @private\n\t */\n\tprivate validatePersistenceMaxRetries(value?: number): number {\n\t\tconst defaultValue = 3;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`persistenceMaxRetries must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 0) {\n\t\t\tthrow new ConfigurationError(`persistenceMaxRetries must be non-negative, got ${value}`);\n\t\t}\n\t\tif (value > 10) {\n\t\t\tthrow new ConfigurationError(`persistenceMaxRetries must not exceed 10, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates feature flags and fills defaults for missing fields.\n\t * @param value - Partial feature flag overrides\n\t * @returns Fully populated FeatureFlags with defaults applied\n\t * @private\n\t */\n\tprivate validateFeatures(value?: Partial<FeatureFlags>): FeatureFlags {\n\t\tconst reasoningStrategy = value?.reasoningStrategy ?? 'sequential';\n\t\tif (reasoningStrategy !== 'sequential' && reasoningStrategy !== 'tot') {\n\t\t\tthrow new ConfigurationError(\n\t\t\t\t`features.reasoningStrategy must be one of sequential, tot, got ${reasoningStrategy}`\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tdagEdges: value?.dagEdges ?? true,\n\t\t\treasoningStrategy,\n\t\t\tcalibration: value?.calibration ?? true,\n\t\t\tcompression: value?.compression ?? true,\n\t\t\ttoolInterleave: value?.toolInterleave ?? true,\n\t\t\tnewThoughtTypes: value?.newThoughtTypes ?? true,\n\t\t\toutcomeRecording: value?.outcomeRecording ?? true,\n\t\t};\n\t}\n\n\t/**\n\t * Validates a positive millisecond value with a default fallback.\n\t * @param value - The value to validate\n\t * @param defaultValue - Default applied if value is undefined/null\n\t * @param fieldName - Field name for error messages\n\t * @returns The validated millisecond value\n\t * @private\n\t */\n\tprivate validatePositiveMs(\n\t\tvalue: number | undefined,\n\t\tdefaultValue: number,\n\t\tfieldName: string\n\t): number {\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`${fieldName} must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`${fieldName} must be at least 1, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Validates the max sessions per owner value.\n\t * @param value - The value to validate\n\t * @returns The validated value or default (50)\n\t * @private\n\t */\n\tprivate validateMaxSessionsPerOwner(value?: number): number {\n\t\tconst defaultValue = 50;\n\t\tif (value === undefined || value === null) return defaultValue;\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthrow new ConfigurationError(`maxSessionsPerOwner must be a finite number, got ${value}`);\n\t\t}\n\t\tif (value < 1) {\n\t\t\tthrow new ConfigurationError(`maxSessionsPerOwner must be at least 1, got ${value}`);\n\t\t}\n\t\tif (value > 10000) {\n\t\t\tthrow new ConfigurationError(`maxSessionsPerOwner must not exceed 10000, got ${value}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * Converts the configuration to a plain object.\n\t *\n\t * Useful for serialization, logging, or when a plain object representation\n\t * is preferred over the ServerConfig instance.\n\t *\n\t * @returns A plain object representation of the configuration\n\t *\n\t * @example\n\t * ```typescript\n\t * const config = new ServerConfig({ maxHistorySize: 500 });\n\t * const json = config.toJSON();\n\t * console.log(JSON.stringify(json, null, 2));\n\t * ```\n\t */\n\tpublic toJSON(): ServerConfigOptions {\n\t\treturn {\n\t\t\tmaxHistorySize: this.maxHistorySize,\n\t\t\tmaxBranches: this.maxBranches,\n\t\t\tmaxBranchSize: this.maxBranchSize,\n\t\t\tskillDirs: this.skillDirs,\n\t\t\ttoolDirs: this.toolDirs,\n\t\t\tdiscoveryCache: this.discoveryCache,\n\t\t\tpersistence: this.persistence,\n\t\t\tpersistenceBufferSize: this.persistenceBufferSize,\n\t\t\tpersistenceFlushInterval: this.persistenceFlushInterval,\n\t\t\tpersistenceMaxRetries: this.persistenceMaxRetries,\n\t\t\tfeatures: this.features,\n\t\t\ttoolInterleaveTtlMs: this.toolInterleaveTtlMs,\n\t\t\ttoolInterleaveSweepMs: this.toolInterleaveSweepMs,\n\t\t\tmaxSessionsPerOwner: this.maxSessionsPerOwner,\n\t\t};\n\t}\n}\n"],"names":["ServerConfig","options","value","defaultValue","Number","ConfigurationError","join","homedir","undefined","validBackends","backend","reasoningStrategy","fieldName"],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -133,13 +133,9 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
133
133
|
PERSISTENCE_DRAIN: 'PERSISTENCE_DRAIN',
|
|
134
134
|
PERSISTENCE_SESSION_ADMISSION_CLOSED: 'PERSISTENCE_SESSION_ADMISSION_CLOSED',
|
|
135
135
|
PERSISTENCE_SESSION_BARRIER_REENTRANCY: 'PERSISTENCE_SESSION_BARRIER_REENTRANCY',
|
|
136
|
-
ASYNC_RESET_REQUIRED: 'ASYNC_RESET_REQUIRED',
|
|
137
|
-
PERSISTENCE_CAPABILITY_UNSUPPORTED: 'PERSISTENCE_CAPABILITY_UNSUPPORTED',
|
|
138
136
|
PERSISTENCE_SCOPE_MISMATCH: 'PERSISTENCE_SCOPE_MISMATCH',
|
|
139
137
|
PERSISTENCE_UNAVAILABLE: 'PERSISTENCE_UNAVAILABLE',
|
|
140
|
-
PERSISTENCE_COMPATIBILITY: 'PERSISTENCE_COMPATIBILITY'
|
|
141
|
-
PERSISTENCE_IMPORT_REQUIRED: 'PERSISTENCE_IMPORT_REQUIRED',
|
|
142
|
-
PERSISTENCE_LEGACY_AMBIGUITY: 'PERSISTENCE_LEGACY_AMBIGUITY'
|
|
138
|
+
PERSISTENCE_COMPATIBILITY: 'PERSISTENCE_COMPATIBILITY'
|
|
143
139
|
};
|
|
144
140
|
/**
|
|
145
141
|
* All known warning codes as a const object.
|
|
@@ -210,7 +206,7 @@ class ConfigurationError extends SequentialThinkingError {
|
|
|
210
206
|
*
|
|
211
207
|
* @example
|
|
212
208
|
* ```typescript
|
|
213
|
-
* const tool = registry.
|
|
209
|
+
* const tool = registry.get('non-existent-tool');
|
|
214
210
|
* if (!tool) {
|
|
215
211
|
* throw new ToolNotFoundError('non-existent-tool');
|
|
216
212
|
* }
|
|
@@ -245,7 +241,7 @@ class ConfigurationError extends SequentialThinkingError {
|
|
|
245
241
|
*
|
|
246
242
|
* @example
|
|
247
243
|
* ```typescript
|
|
248
|
-
* const skill = registry.
|
|
244
|
+
* const skill = registry.get('non-existent-skill');
|
|
249
245
|
* if (!skill) {
|
|
250
246
|
* throw new SkillNotFoundError('non-existent-skill');
|
|
251
247
|
* }
|
|
@@ -381,7 +377,7 @@ class ConfigurationError extends SequentialThinkingError {
|
|
|
381
377
|
*
|
|
382
378
|
* @example
|
|
383
379
|
* ```typescript
|
|
384
|
-
* if (registry.
|
|
380
|
+
* if (registry.has(skill.name)) {
|
|
385
381
|
* throw new DuplicateSkillError(skill.name);
|
|
386
382
|
* }
|
|
387
383
|
* ```
|
|
@@ -439,7 +435,7 @@ class ConfigurationError extends SequentialThinkingError {
|
|
|
439
435
|
*
|
|
440
436
|
* @example
|
|
441
437
|
* ```typescript
|
|
442
|
-
* if (registry.
|
|
438
|
+
* if (registry.has(tool.name)) {
|
|
443
439
|
* throw new DuplicateToolError(tool.name);
|
|
444
440
|
* }
|
|
445
441
|
* ```
|
|
@@ -753,28 +749,6 @@ class PersistenceClosedError extends SequentialThinkingError {
|
|
|
753
749
|
this.cause = cause;
|
|
754
750
|
}
|
|
755
751
|
}
|
|
756
|
-
/** Error raised when legacy files require an explicit one-way import. */ class PersistenceImportRequiredError extends SequentialThinkingError {
|
|
757
|
-
sourcePath;
|
|
758
|
-
legacyArtifacts;
|
|
759
|
-
constructor(sourcePath, legacyArtifacts){
|
|
760
|
-
super(`Legacy persistence at '${sourcePath}' requires explicit import`, ERROR_CODES.PERSISTENCE_IMPORT_REQUIRED);
|
|
761
|
-
this.name = 'PersistenceImportRequiredError';
|
|
762
|
-
this.sourcePath = sourcePath;
|
|
763
|
-
this.legacyArtifacts = [
|
|
764
|
-
...legacyArtifacts
|
|
765
|
-
];
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
/** Error raised when legacy bytes do not identify one durable namespace. */ class PersistenceLegacyAmbiguityError extends SequentialThinkingError {
|
|
769
|
-
sourcePath;
|
|
770
|
-
detail;
|
|
771
|
-
constructor(sourcePath, detail){
|
|
772
|
-
super(`Legacy persistence at '${sourcePath}' is ambiguous: ${detail}`, ERROR_CODES.PERSISTENCE_LEGACY_AMBIGUITY);
|
|
773
|
-
this.name = 'PersistenceLegacyAmbiguityError';
|
|
774
|
-
this.sourcePath = sourcePath;
|
|
775
|
-
this.detail = detail;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
752
|
/**
|
|
779
753
|
* Type guard to check if an error has a specific error code.
|
|
780
754
|
*/ function isErrorCode(err, code) {
|
|
@@ -921,8 +895,8 @@ Reasoning Enhancement Parameters:
|
|
|
921
895
|
- merge_branch_ids: Branch IDs merged into current context
|
|
922
896
|
- meta_observation: Observation about reasoning process (with thought_type 'meta')
|
|
923
897
|
- reasoning_depth: How deep to reason: 'shallow' (quick), 'moderate' (default), 'deep' (thorough)
|
|
924
|
-
- session_id:
|
|
925
|
-
- reset_state: (Optional) When true, clears all state for the
|
|
898
|
+
- session_id: Required unique identifier that scopes thought history, branches, and statistics to an explicit session. Format: alphanumeric, hyphens, underscores, 1-100 chars; the retired value __global__ is rejected.
|
|
899
|
+
- reset_state: (Optional) When true, clears all state for the required session_id before processing the current thought. Use this to start a fresh reasoning chain without accumulated state from previous chains.
|
|
926
900
|
|
|
927
901
|
Response Enrichment:
|
|
928
902
|
- When reasoning fields are set, response includes confidence_signals (depth, revision/branch count, type distribution, avg confidence, structural_quality, quality_components) and reasoning_stats (hypothesis tracking)
|
|
@@ -1171,6 +1145,7 @@ You should:
|
|
|
1171
1145
|
* thought: 'I need to analyze the problem',
|
|
1172
1146
|
* thought_number: 1,
|
|
1173
1147
|
* total_thoughts: 5,
|
|
1148
|
+
* session_id: 'analysis-task',
|
|
1174
1149
|
* next_thought_needed: true,
|
|
1175
1150
|
* available_mcp_tools: ['Read', 'Write', 'Grep']
|
|
1176
1151
|
* });
|
|
@@ -1227,7 +1202,7 @@ You should:
|
|
|
1227
1202
|
'moderate',
|
|
1228
1203
|
'deep'
|
|
1229
1204
|
]), valibot__rspack_import_0.description('Effort signal: how deep reasoning should go'))),
|
|
1230
|
-
session_id: valibot__rspack_import_0.
|
|
1205
|
+
session_id: valibot__rspack_import_0.pipe(valibot__rspack_import_0.string(), valibot__rspack_import_0.regex(/^[a-zA-Z0-9_-]+$/, 'Session ID must contain only letters, numbers, hyphens, and underscores'), valibot__rspack_import_0.minLength(1), valibot__rspack_import_0.maxLength(100), valibot__rspack_import_0.notValue('__global__', "Session ID '__global__' is retired; use an explicit named session"), valibot__rspack_import_0.description('Required session identifier for state isolation. Thought history, branches, and statistics are scoped to this explicit named session.')),
|
|
1231
1206
|
reset_state: valibot__rspack_import_0.optional(valibot__rspack_import_0.pipe(valibot__rspack_import_0.boolean(), valibot__rspack_import_0.description('When true, clears all state for the target session before processing this thought. The thought is then processed as the first in a fresh session.'))),
|
|
1232
1207
|
tool_name: valibot__rspack_import_0.optional(valibot__rspack_import_0.pipe(valibot__rspack_import_0.string(), valibot__rspack_import_0.minLength(1), valibot__rspack_import_0.description('Name of the tool being invoked (for tool_call thoughts)'))),
|
|
1233
1208
|
tool_arguments: valibot__rspack_import_0.optional(valibot__rspack_import_0.pipe(valibot__rspack_import_0.record(valibot__rspack_import_0.string(), valibot__rspack_import_0.unknown()), valibot__rspack_import_0.description('Arguments passed to the tool (for tool_call thoughts)'))),
|
|
@@ -1391,7 +1366,6 @@ var schema = __webpack_require__("R");
|
|
|
1391
1366
|
* @remarks
|
|
1392
1367
|
* **Security Features:**
|
|
1393
1368
|
* - Session ID validation (alphanumeric, max 64 chars)
|
|
1394
|
-
* - Query parameter sanitization (whitelist allowed keys)
|
|
1395
1369
|
* - Rate limiting per IP (configurable, default 100 req/min)
|
|
1396
1370
|
* - CORS origin validation
|
|
1397
1371
|
*
|
|
@@ -1415,14 +1389,6 @@ var schema = __webpack_require__("R");
|
|
|
1415
1389
|
return this._level;
|
|
1416
1390
|
}
|
|
1417
1391
|
}
|
|
1418
|
-
/**
|
|
1419
|
-
* Allowed query parameter names (whitelist for security).
|
|
1420
|
-
*/ const ALLOWED_QUERY_PARAMS = new Set([
|
|
1421
|
-
'session',
|
|
1422
|
-
'sessionId',
|
|
1423
|
-
'client',
|
|
1424
|
-
'clientId'
|
|
1425
|
-
]);
|
|
1426
1392
|
/**
|
|
1427
1393
|
* Rate limit settings (requests per minute per IP).
|
|
1428
1394
|
*/ const RATE_LIMIT_REQUESTS = 100;
|
|
@@ -1474,20 +1440,6 @@ class BaseTransport {
|
|
|
1474
1440
|
}
|
|
1475
1441
|
return SESSION_ID_PATTERN.test(sessionId);
|
|
1476
1442
|
}
|
|
1477
|
-
/**
|
|
1478
|
-
* Sanitize query parameters by removing any not in whitelist.
|
|
1479
|
-
*
|
|
1480
|
-
* @param url - The URL object containing query parameters
|
|
1481
|
-
* @returns A sanitized record of allowed query parameters
|
|
1482
|
-
*/ sanitizeQueryParams(url) {
|
|
1483
|
-
const sanitized = {};
|
|
1484
|
-
for (const [key, value] of url.searchParams.entries()){
|
|
1485
|
-
if (ALLOWED_QUERY_PARAMS.has(key)) {
|
|
1486
|
-
sanitized[key] = value;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
return sanitized;
|
|
1490
|
-
}
|
|
1491
1443
|
/**
|
|
1492
1444
|
* Check rate limit for a given IP address.
|
|
1493
1445
|
*
|
|
@@ -1726,13 +1678,12 @@ class BaseTransport {
|
|
|
1726
1678
|
* Validate and brand a string as a {@link SessionId}.
|
|
1727
1679
|
*
|
|
1728
1680
|
* Enforces {@link SESSION_ID_PATTERN} and {@link MAX_SESSION_ID_LENGTH}.
|
|
1729
|
-
* The
|
|
1681
|
+
* The retired global session sentinel `__global__` is rejected.
|
|
1730
1682
|
*
|
|
1731
1683
|
* @throws {ValidationError} when the input is not a valid session id.
|
|
1732
1684
|
*/ function asSessionId(value) {
|
|
1733
1685
|
if (value === '__global__') {
|
|
1734
|
-
|
|
1735
|
-
return value;
|
|
1686
|
+
throw new errors/* .ValidationError */.yI('session_id', "reserved value '__global__' is retired; use an explicit named session");
|
|
1736
1687
|
}
|
|
1737
1688
|
if (typeof value !== 'string' || value.length === 0) {
|
|
1738
1689
|
throw new errors/* .ValidationError */.yI('session_id', 'must be a non-empty string');
|
|
@@ -1773,12 +1724,6 @@ class BaseTransport {
|
|
|
1773
1724
|
/** Generate a fresh {@link SummaryId}. */ function generateSummaryId() {
|
|
1774
1725
|
return generateUlid();
|
|
1775
1726
|
}
|
|
1776
|
-
/**
|
|
1777
|
-
* Reserved sentinel session id used when callers omit `session_id`.
|
|
1778
|
-
*
|
|
1779
|
-
* Branded once here so production and test code share one constant
|
|
1780
|
-
* instead of casting `'__global__'` ad-hoc.
|
|
1781
|
-
*/ const GLOBAL_SESSION_ID = asSessionId('__global__');
|
|
1782
1727
|
|
|
1783
1728
|
;// CONCATENATED MODULE: external "node:string_decoder"
|
|
1784
1729
|
|
|
@@ -3168,7 +3113,7 @@ if (shouldShowVersion) {
|
|
|
3168
3113
|
process.exit(0);
|
|
3169
3114
|
}
|
|
3170
3115
|
async function main() {
|
|
3171
|
-
const transportType = process.env.
|
|
3116
|
+
const transportType = process.env.TRACELATTICE_TRANSPORT_TYPE || 'stdio';
|
|
3172
3117
|
const adapter = new __rspack_external__tmcp_adapter_valibot_0faddfa6.ValibotJsonSchemaAdapter();
|
|
3173
3118
|
const server = new __rspack_external_tmcp.McpServer({
|
|
3174
3119
|
name: CLI_NAME,
|
|
@@ -3204,16 +3149,16 @@ async function main() {
|
|
|
3204
3149
|
* Start Streamable HTTP transport (MCP spec recommended)
|
|
3205
3150
|
*/ async function startStreamableHttpTransport(server, thinkingServer, lifecycle) {
|
|
3206
3151
|
const { StreamableHttpTransport } = await Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, "q"));
|
|
3207
|
-
const port = parseInt(process.env.
|
|
3208
|
-
const host = process.env.
|
|
3152
|
+
const port = parseInt(process.env.TRACELATTICE_STREAMABLE_HTTP_PORT || '9007', 10);
|
|
3153
|
+
const host = process.env.TRACELATTICE_STREAMABLE_HTTP_HOST || 'localhost';
|
|
3209
3154
|
const transportMetrics = thinkingServer.getContainer().resolve('Metrics');
|
|
3210
|
-
const stateful = process.env.
|
|
3155
|
+
const stateful = process.env.TRACELATTICE_STREAMABLE_HTTP_STATEFUL !== 'false';
|
|
3211
3156
|
const streamableTransport = new StreamableHttpTransport({
|
|
3212
3157
|
port,
|
|
3213
3158
|
host,
|
|
3214
|
-
corsOrigin: process.env.
|
|
3215
|
-
enableCors: process.env.
|
|
3216
|
-
allowedHosts: process.env.
|
|
3159
|
+
corsOrigin: process.env.TRACELATTICE_CORS_ORIGIN || '*',
|
|
3160
|
+
enableCors: process.env.TRACELATTICE_ENABLE_CORS !== 'false',
|
|
3161
|
+
allowedHosts: process.env.TRACELATTICE_ALLOWED_HOSTS?.split(',').map((hostValue)=>hostValue.trim()),
|
|
3217
3162
|
metrics: transportMetrics,
|
|
3218
3163
|
stateful
|
|
3219
3164
|
});
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env bun\n\n// CLI entry point for tracelattice MCP server.\n// This file handles CLI argument parsing, transport selection, and signal handlers.\n// For library usage, import from './lib.js' or './index.js' instead.\n\nimport { ValibotJsonSchemaAdapter } from '@tmcp/adapter-valibot';\nimport { StdioTransport } from '@tmcp/transport-stdio';\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { McpServer } from 'tmcp';\nimport { CliLifecycle, createCliShutdownHandler } from './CliLifecycle.js';\nimport type { ToolAwareSequentialThinkingServer } from './lib.js';\nimport { initializeServer } from './lib.js';\nimport { StructuredLogger } from './logger/StructuredLogger.js';\nimport { getErrorMessage } from './errors.js';\nimport { SEQUENTIAL_THINKING_TOOL, SequentialThinkingSchema } from './schema.js';\n\n// Get version from package.json\nconst CLI_NAME = 'tracelattice' as const;\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst package_json = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\nconst { version } = package_json;\n// Handle CLI arguments\nconst args = process.argv.slice(2);\nconst shouldShowVersion = args.includes('--version') || args.includes('-v');\n\nif (shouldShowVersion) {\n\tconsole.log(`${CLI_NAME} v${version}`);\n\tprocess.exit(0);\n}\nasync function main() {\n\tconst transportType = process.env.TRANSPORT_TYPE || 'stdio';\n\tconst adapter = new ValibotJsonSchemaAdapter();\n\tconst server = new McpServer(\n\t\t{\n\t\t\tname: CLI_NAME,\n\t\t\tversion,\n\t\t\tdescription: 'Semantic Sequential Thinking MCP Server',\n\t\t},\n\t\t{\n\t\t\tadapter,\n\t\t\tcapabilities: {\n\t\t\t\ttools: { listChanged: true },\n\t\t\t},\n\t\t}\n\t);\n\n\tconst thinkingServer = await initializeServer();\n\tconst lifecycle = new CliLifecycle(thinkingServer);\n\ttry {\n\t\tserver.tool(\n\t\t\t{\n\t\t\t\tname: 'sequentialthinking_tools',\n\t\t\t\tdescription: SEQUENTIAL_THINKING_TOOL.description,\n\t\t\t\tschema: SequentialThinkingSchema,\n\t\t\t},\n\t\t\tasync (input) => thinkingServer.processThought(input)\n\t\t);\n\t\tif (transportType === 'streamable-http') {\n\t\t\tawait startStreamableHttpTransport(server, thinkingServer, lifecycle);\n\t\t} else {\n\t\t\tawait startStdioTransport(server, thinkingServer, lifecycle);\n\t\t}\n\t\tregisterShutdownHandlers(lifecycle, thinkingServer, transportType === 'stdio');\n\t} catch (error) {\n\t\tawait lifecycle.rollbackStartup(error);\n\t}\n}\n/**\n * Start Streamable HTTP transport (MCP spec recommended)\n */\nasync function startStreamableHttpTransport(\n\tserver: McpServer,\n\tthinkingServer: ToolAwareSequentialThinkingServer,\n\tlifecycle: CliLifecycle\n): Promise<void> {\n\tconst { StreamableHttpTransport } = await import('./transport/StreamableHttpTransport.js');\n\tconst port = parseInt(process.env.STREAMABLE_HTTP_PORT || '9007', 10);\n\tconst host = process.env.STREAMABLE_HTTP_HOST || 'localhost';\n\tconst transportMetrics = thinkingServer.getContainer().resolve('Metrics');\n\tconst stateful = process.env.STREAMABLE_HTTP_STATEFUL !== 'false';\n\tconst streamableTransport = new StreamableHttpTransport({\n\t\tport,\n\t\thost,\n\t\tcorsOrigin: process.env.CORS_ORIGIN || '*',\n\t\tenableCors: process.env.ENABLE_CORS !== 'false',\n\t\tallowedHosts: process.env.ALLOWED_HOSTS?.split(',').map((hostValue) => hostValue.trim()),\n\t\tmetrics: transportMetrics,\n\t\tstateful,\n\t});\n\tlifecycle.attachTransport(streamableTransport);\n\t// Connect the Streamable HTTP transport\n\tawait streamableTransport.connect(server);\n\tthinkingServer['_logger'].info(\n\t\t`Sequential Thinking MCP Server running on Streamable HTTP transport at http://${host}:${port}`\n\t);\n}\n/**\n * Start stdio transport (default, single-user)\n */\nasync function startStdioTransport(\n\tserver: McpServer,\n\tthinkingServer: ToolAwareSequentialThinkingServer,\n\tlifecycle: CliLifecycle\n): Promise<void> {\n\tconst transport = new StdioTransport(server);\n\tconst processListeners = {\n\t\tsigint: new Set(process.listeners('SIGINT')),\n\t\tsigterm: new Set(process.listeners('SIGTERM')),\n\t\tstdinEnd: new Set(process.stdin.listeners('end')),\n\t};\n\tlifecycle.attachTransport({ stop: () => transport.close() });\n\ttransport.listen();\n\tfor (const listener of process.listeners('SIGINT')) {\n\t\tif (!processListeners.sigint.has(listener)) process.off('SIGINT', listener);\n\t}\n\tfor (const listener of process.listeners('SIGTERM')) {\n\t\tif (!processListeners.sigterm.has(listener)) process.off('SIGTERM', listener);\n\t}\n\tfor (const listener of process.stdin.listeners('end')) {\n\t\tif (!processListeners.stdinEnd.has(listener)) process.stdin.off('end', listener);\n\t}\n\tthinkingServer['_logger'].info('Sequential Thinking MCP Server running on stdio');\n}\n/**\n * Register shutdown signal handlers for a common pattern\n */\nfunction registerShutdownHandlers(\n\tlifecycle: CliLifecycle,\n\tthinkingServer: ToolAwareSequentialThinkingServer,\n\tshutdownOnStdinEnd: boolean\n): void {\n\tconst shutdown = createCliShutdownHandler(lifecycle, {\n\t\treportFailure: (error) => {\n\t\t\tthinkingServer['_logger'].error('CLI shutdown failed', failureMetadata(error));\n\t\t},\n\t\texit: (code) => process.exit(code),\n\t});\n\tconst requestShutdown = (): void => {\n\t\tvoid shutdown();\n\t};\n\tprocess.on('SIGINT', requestShutdown);\n\tprocess.on('SIGTERM', requestShutdown);\n\tif (shutdownOnStdinEnd) process.stdin.on('end', requestShutdown);\n}\n\nfunction failureMetadata(error: unknown): Record<string, unknown> {\n\tif (!(error instanceof AggregateError)) return { error: getErrorMessage(error) };\n\treturn {\n\t\terror: error.message,\n\t\tcauses: error.errors.map((cause) => getErrorMessage(cause)),\n\t};\n}\nmain().catch((error) => {\n\tconst logger = new StructuredLogger({\n\t\tlevel: 'error',\n\t\tcontext: 'SequentialThinking',\n\t\tpretty: true,\n\t});\n\tlogger.error('Fatal error running server', failureMetadata(error));\n\tprocess.exit(1);\n});\n"],"names":["CLI_NAME","__filename","fileURLToPath","__dirname","dirname","package_json","JSON","readFileSync","join","version","args","process","shouldShowVersion","console","main","transportType","adapter","ValibotJsonSchemaAdapter","server","McpServer","thinkingServer","initializeServer","lifecycle","CliLifecycle","SEQUENTIAL_THINKING_TOOL","SequentialThinkingSchema","input","startStreamableHttpTransport","startStdioTransport","registerShutdownHandlers","error","StreamableHttpTransport","port","parseInt","host","transportMetrics","stateful","streamableTransport","hostValue","transport","StdioTransport","processListeners","Set","listener","shutdownOnStdinEnd","shutdown","createCliShutdownHandler","failureMetadata","code","requestShutdown","AggregateError","getErrorMessage","cause","logger","StructuredLogger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env bun\n\n// CLI entry point for tracelattice MCP server.\n// This file handles CLI argument parsing, transport selection, and signal handlers.\n// For library usage, import from './lib.js' or './index.js' instead.\n\nimport { ValibotJsonSchemaAdapter } from '@tmcp/adapter-valibot';\nimport { StdioTransport } from '@tmcp/transport-stdio';\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { McpServer } from 'tmcp';\nimport { CliLifecycle, createCliShutdownHandler } from './CliLifecycle.js';\nimport type { ToolAwareSequentialThinkingServer } from './lib.js';\nimport { initializeServer } from './lib.js';\nimport { StructuredLogger } from './logger/StructuredLogger.js';\nimport { getErrorMessage } from './errors.js';\nimport { SEQUENTIAL_THINKING_TOOL, SequentialThinkingSchema } from './schema.js';\n\n// Get version from package.json\nconst CLI_NAME = 'tracelattice' as const;\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst package_json = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\nconst { version } = package_json;\n// Handle CLI arguments\nconst args = process.argv.slice(2);\nconst shouldShowVersion = args.includes('--version') || args.includes('-v');\n\nif (shouldShowVersion) {\n\tconsole.log(`${CLI_NAME} v${version}`);\n\tprocess.exit(0);\n}\nasync function main() {\n\tconst transportType = process.env.TRACELATTICE_TRANSPORT_TYPE || 'stdio';\n\tconst adapter = new ValibotJsonSchemaAdapter();\n\tconst server = new McpServer(\n\t\t{\n\t\t\tname: CLI_NAME,\n\t\t\tversion,\n\t\t\tdescription: 'Semantic Sequential Thinking MCP Server',\n\t\t},\n\t\t{\n\t\t\tadapter,\n\t\t\tcapabilities: {\n\t\t\t\ttools: { listChanged: true },\n\t\t\t},\n\t\t}\n\t);\n\n\tconst thinkingServer = await initializeServer();\n\tconst lifecycle = new CliLifecycle(thinkingServer);\n\ttry {\n\t\tserver.tool(\n\t\t\t{\n\t\t\t\tname: 'sequentialthinking_tools',\n\t\t\t\tdescription: SEQUENTIAL_THINKING_TOOL.description,\n\t\t\t\tschema: SequentialThinkingSchema,\n\t\t\t},\n\t\t\tasync (input) => thinkingServer.processThought(input)\n\t\t);\n\t\tif (transportType === 'streamable-http') {\n\t\t\tawait startStreamableHttpTransport(server, thinkingServer, lifecycle);\n\t\t} else {\n\t\t\tawait startStdioTransport(server, thinkingServer, lifecycle);\n\t\t}\n\t\tregisterShutdownHandlers(lifecycle, thinkingServer, transportType === 'stdio');\n\t} catch (error) {\n\t\tawait lifecycle.rollbackStartup(error);\n\t}\n}\n/**\n * Start Streamable HTTP transport (MCP spec recommended)\n */\nasync function startStreamableHttpTransport(\n\tserver: McpServer,\n\tthinkingServer: ToolAwareSequentialThinkingServer,\n\tlifecycle: CliLifecycle\n): Promise<void> {\n\tconst { StreamableHttpTransport } = await import('./transport/StreamableHttpTransport.js');\n\tconst port = parseInt(process.env.TRACELATTICE_STREAMABLE_HTTP_PORT || '9007', 10);\n\tconst host = process.env.TRACELATTICE_STREAMABLE_HTTP_HOST || 'localhost';\n\tconst transportMetrics = thinkingServer.getContainer().resolve('Metrics');\n\tconst stateful = process.env.TRACELATTICE_STREAMABLE_HTTP_STATEFUL !== 'false';\n\tconst streamableTransport = new StreamableHttpTransport({\n\t\tport,\n\t\thost,\n\t\tcorsOrigin: process.env.TRACELATTICE_CORS_ORIGIN || '*',\n\t\tenableCors: process.env.TRACELATTICE_ENABLE_CORS !== 'false',\n\t\tallowedHosts: process.env.TRACELATTICE_ALLOWED_HOSTS?.split(',').map((hostValue) =>\n\t\t\thostValue.trim()\n\t\t),\n\t\tmetrics: transportMetrics,\n\t\tstateful,\n\t});\n\tlifecycle.attachTransport(streamableTransport);\n\t// Connect the Streamable HTTP transport\n\tawait streamableTransport.connect(server);\n\tthinkingServer['_logger'].info(\n\t\t`Sequential Thinking MCP Server running on Streamable HTTP transport at http://${host}:${port}`\n\t);\n}\n/**\n * Start stdio transport (default, single-user)\n */\nasync function startStdioTransport(\n\tserver: McpServer,\n\tthinkingServer: ToolAwareSequentialThinkingServer,\n\tlifecycle: CliLifecycle\n): Promise<void> {\n\tconst transport = new StdioTransport(server);\n\tconst processListeners = {\n\t\tsigint: new Set(process.listeners('SIGINT')),\n\t\tsigterm: new Set(process.listeners('SIGTERM')),\n\t\tstdinEnd: new Set(process.stdin.listeners('end')),\n\t};\n\tlifecycle.attachTransport({ stop: () => transport.close() });\n\ttransport.listen();\n\tfor (const listener of process.listeners('SIGINT')) {\n\t\tif (!processListeners.sigint.has(listener)) process.off('SIGINT', listener);\n\t}\n\tfor (const listener of process.listeners('SIGTERM')) {\n\t\tif (!processListeners.sigterm.has(listener)) process.off('SIGTERM', listener);\n\t}\n\tfor (const listener of process.stdin.listeners('end')) {\n\t\tif (!processListeners.stdinEnd.has(listener)) process.stdin.off('end', listener);\n\t}\n\tthinkingServer['_logger'].info('Sequential Thinking MCP Server running on stdio');\n}\n/**\n * Register shutdown signal handlers for a common pattern\n */\nfunction registerShutdownHandlers(\n\tlifecycle: CliLifecycle,\n\tthinkingServer: ToolAwareSequentialThinkingServer,\n\tshutdownOnStdinEnd: boolean\n): void {\n\tconst shutdown = createCliShutdownHandler(lifecycle, {\n\t\treportFailure: (error) => {\n\t\t\tthinkingServer['_logger'].error('CLI shutdown failed', failureMetadata(error));\n\t\t},\n\t\texit: (code) => process.exit(code),\n\t});\n\tconst requestShutdown = (): void => {\n\t\tvoid shutdown();\n\t};\n\tprocess.on('SIGINT', requestShutdown);\n\tprocess.on('SIGTERM', requestShutdown);\n\tif (shutdownOnStdinEnd) process.stdin.on('end', requestShutdown);\n}\n\nfunction failureMetadata(error: unknown): Record<string, unknown> {\n\tif (!(error instanceof AggregateError)) return { error: getErrorMessage(error) };\n\treturn {\n\t\terror: error.message,\n\t\tcauses: error.errors.map((cause) => getErrorMessage(cause)),\n\t};\n}\nmain().catch((error) => {\n\tconst logger = new StructuredLogger({\n\t\tlevel: 'error',\n\t\tcontext: 'SequentialThinking',\n\t\tpretty: true,\n\t});\n\tlogger.error('Fatal error running server', failureMetadata(error));\n\tprocess.exit(1);\n});\n"],"names":["CLI_NAME","__filename","fileURLToPath","__dirname","dirname","package_json","JSON","readFileSync","join","version","args","process","shouldShowVersion","console","main","transportType","adapter","ValibotJsonSchemaAdapter","server","McpServer","thinkingServer","initializeServer","lifecycle","CliLifecycle","SEQUENTIAL_THINKING_TOOL","SequentialThinkingSchema","input","startStreamableHttpTransport","startStdioTransport","registerShutdownHandlers","error","StreamableHttpTransport","port","parseInt","host","transportMetrics","stateful","streamableTransport","hostValue","transport","StdioTransport","processListeners","Set","listener","shutdownOnStdinEnd","shutdown","createCliShutdownHandler","failureMetadata","code","requestShutdown","AggregateError","getErrorMessage","cause","logger","StructuredLogger"],"mappings":"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"}
|