opencontext-mcp 1.0.0 → 1.2.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 +95 -114
- package/dist/config.d.ts +24 -0
- package/dist/config.js +145 -0
- package/dist/config.js.map +1 -0
- package/dist/context-store.d.ts +55 -1
- package/dist/context-store.js +252 -16
- package/dist/context-store.js.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +8 -1
- package/dist/server.js +44 -3
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +42 -2
- package/dist/types.js +34 -2
- package/dist/types.js.map +1 -1
- package/dist/validation.d.ts +46 -0
- package/dist/validation.js +98 -1
- package/dist/validation.js.map +1 -1
- package/package.json +4 -4
- package/LICENSE +0 -21
- package/examples/build-agent.md +0 -48
- package/examples/plan-agent.md +0 -53
package/README.md
CHANGED
|
@@ -1,47 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://opencntx.dev">
|
|
3
|
+
<img src="https://github.com/slxca/opencontext/blob/master/apps/web/public/opencontext.png?raw=true" alt="OpenContext logo" width="500">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
[](https://www.typescriptlang.org/)
|
|
5
|
-
[](https://nodejs.org/)
|
|
6
|
-
[](https://opencntx.dev/)
|
|
7
|
-
[](LICENSE)
|
|
7
|
+
<p align="center"><b>Persistent, project-local memory for AI coding agents.</b></p>
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://opencntx.dev"><img alt="Website" src="https://img.shields.io/badge/website-opencntx.dev-191919?style=flat-square" /></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/opencontext-mcp"><img alt="npm version" src="https://img.shields.io/npm/v/opencontext-mcp?style=flat-square" /></a>
|
|
12
|
+
<a href="https://github.com/slxca/opencontext/actions"><img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/slxca/opencontext/ci.yml?style=flat-square&branch=master" /></a>
|
|
13
|
+
</p>
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
---
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
Most coding agents lose critical decisions between sessions: architecture invariants, API contracts, rejected patterns, and setup quirks. OpenContext solves context loss through a lightweight Model Context Protocol (MCP) server that lets agents read and mutate durable markdown files inside `.opencontext/`.
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
No vector databases, no cloud subscriptions, and no hidden state. Memory is plain markdown tracked directly in Git.
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
- `read_context`: read one saved topic or list all available topics
|
|
19
|
-
- Project-specific storage based on the client's current working directory
|
|
20
|
-
- No database, account, cloud sync, or hidden state
|
|
21
|
-
- Works with MCP-compatible clients over stdio
|
|
22
|
-
- Built with strict TypeScript and the official `@modelcontextprotocol/sdk`
|
|
21
|
+
---
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
### Quickstart
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Run directly without installation via `npx`:
|
|
27
26
|
|
|
28
27
|
```bash
|
|
29
28
|
npx -y opencontext-mcp
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
For local development in this repository:
|
|
33
29
|
|
|
34
|
-
```bash
|
|
35
|
-
pnpm install
|
|
36
|
-
pnpm build
|
|
37
|
-
pnpm start
|
|
38
30
|
```
|
|
39
31
|
|
|
40
|
-
|
|
32
|
+
### Client Setup
|
|
41
33
|
|
|
42
|
-
|
|
34
|
+
#### OpenCode
|
|
43
35
|
|
|
44
|
-
Add OpenContext
|
|
36
|
+
Add OpenContext to your project MCP configuration (`opencode.json`):
|
|
45
37
|
|
|
46
38
|
```json
|
|
47
39
|
{
|
|
@@ -53,11 +45,12 @@ Add OpenContext MCP to your OpenCode MCP configuration:
|
|
|
53
45
|
}
|
|
54
46
|
}
|
|
55
47
|
}
|
|
48
|
+
|
|
56
49
|
```
|
|
57
50
|
|
|
58
|
-
|
|
51
|
+
#### Cursor / Claude Desktop / Windsurf
|
|
59
52
|
|
|
60
|
-
|
|
53
|
+
Add OpenContext to your MCP settings file (`claude_desktop_config.json` or Cursor MCP settings):
|
|
61
54
|
|
|
62
55
|
```json
|
|
63
56
|
{
|
|
@@ -68,128 +61,116 @@ Cursor and Claude Desktop use the same MCP server configuration:
|
|
|
68
61
|
}
|
|
69
62
|
}
|
|
70
63
|
}
|
|
64
|
+
|
|
71
65
|
```
|
|
72
66
|
|
|
73
|
-
|
|
67
|
+
---
|
|
74
68
|
|
|
75
|
-
|
|
69
|
+
### Core Tools
|
|
76
70
|
|
|
77
|
-
|
|
71
|
+
| Tool | Parameters | Description |
|
|
72
|
+
| --- | --- | --- |
|
|
73
|
+
| `read_context` | `topic?` *(optional string)* | Reads a specific context topic, or returns the lightweight topic index (~100 tokens) if omitted. |
|
|
74
|
+
| `save_context` | `topic` *(string)*, `content` *(string)* | Writes or mutates markdown memory inside `.opencontext/<topic>.md` with built-in write guards and symlink protections. |
|
|
75
|
+
| `delete_context` | `topic` *(string)* | Removes an obsolete topic file and automatically rebuilds the topic index. |
|
|
78
76
|
|
|
79
|
-
|
|
80
|
-
your-project/
|
|
81
|
-
.opencontext/
|
|
82
|
-
architecture.md
|
|
83
|
-
api-contracts.md
|
|
84
|
-
coding_rules.md
|
|
85
|
-
```
|
|
77
|
+
---
|
|
86
78
|
|
|
87
|
-
|
|
79
|
+
### ADR Lifecycle & Frontmatter
|
|
88
80
|
|
|
89
|
-
|
|
81
|
+
Topics support optional YAML frontmatter to track lifecycle status — useful when architectural decisions evolve and old context should be visible but clearly flagged as outdated.
|
|
90
82
|
|
|
91
|
-
|
|
83
|
+
````markdown
|
|
84
|
+
---
|
|
85
|
+
description: OAuth2 + PKCE authentication flow
|
|
86
|
+
status: active
|
|
87
|
+
supersedes: auth_v1
|
|
88
|
+
---
|
|
92
89
|
|
|
93
|
-
|
|
90
|
+
# Authentication v2
|
|
94
91
|
|
|
95
|
-
|
|
92
|
+
Migrated from JWT to OAuth2 with PKCE.
|
|
93
|
+
````
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
| --------- | ------ | -------- | --------------------------------------------- |
|
|
99
|
-
| `topic` | string | yes | Lowercase snake_case or kebab-case topic name |
|
|
100
|
-
| `content` | string | yes | Markdown content to save |
|
|
95
|
+
**Supported frontmatter keys:**
|
|
101
96
|
|
|
102
|
-
|
|
97
|
+
| Key | Values | Description |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
| `description` | string | Short summary used in the auto-generated index. |
|
|
100
|
+
| `status` | `active` \| `deprecated` \| `superseded` | Lifecycle status. Defaults to `active` when omitted. |
|
|
101
|
+
| `supersedes` | string | Topic name this topic replaces *(set on the newer topic)*. |
|
|
102
|
+
| `superseded_by` | string | Topic name that replaced this one *(set on the older topic)*. |
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
Save our API conventions under topic api-contracts.
|
|
106
|
-
```
|
|
104
|
+
Non-active topics automatically receive `[DEPRECATED]` or `[SUPERSEDED]` badges in the auto-generated `index.md`, along with cross-references showing which topic replaced or was replaced.
|
|
107
105
|
|
|
108
|
-
|
|
106
|
+
---
|
|
109
107
|
|
|
110
|
-
|
|
108
|
+
### Agent Workflows
|
|
111
109
|
|
|
112
|
-
|
|
110
|
+
Instruct your agents to automatically leverage project context. Add this snippet to your `.cursorrules`, `CLAUDE.md`, or system prompt:
|
|
113
111
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
| `topic` | string | no | Topic to read |
|
|
112
|
+
```markdown
|
|
113
|
+
Before making structural code changes, run `read_context` to inspect existing project topics and architectural decisions.
|
|
117
114
|
|
|
118
|
-
|
|
115
|
+
Whenever a new architectural convention, database schema, or API rule is established or refactored, call `save_context` with a concise, topic-scoped markdown summary. Use YAML frontmatter (status, supersedes) when updating conventions to track lifecycle changes.
|
|
119
116
|
|
|
120
|
-
|
|
121
|
-
Read the architecture context before changing the routing layer.
|
|
117
|
+
When a topic becomes obsolete, call `delete_context` to remove it. For deprecated topics that should remain visible, set status: deprecated or status: superseded in the frontmatter instead of deleting.
|
|
122
118
|
```
|
|
123
119
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
MCP tools are most useful when your agent is explicitly told when to use them. Add instructions like these to your system prompt or project rules:
|
|
120
|
+
---
|
|
127
121
|
|
|
128
|
-
|
|
129
|
-
Always use read_context before making code changes. First list available topics, then read any topic relevant to the task.
|
|
122
|
+
### Configuration
|
|
130
123
|
|
|
131
|
-
|
|
124
|
+
Customize storage paths and security boundaries with an optional `.opencontext.jsonc` file in your repository root:
|
|
132
125
|
|
|
133
|
-
|
|
134
|
-
|
|
126
|
+
```jsonc
|
|
127
|
+
{
|
|
128
|
+
// Storage location (default: ".opencontext")
|
|
129
|
+
"path": ".opencontext",
|
|
135
130
|
|
|
136
|
-
|
|
131
|
+
// Prevent agents from writing or updating files
|
|
132
|
+
"readOnly": false,
|
|
137
133
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
3. Let agents update context when they discover something that should survive the current chat.
|
|
141
|
-
4. Review `.opencontext/` files like normal project documentation.
|
|
134
|
+
// Auto-generate index.md with topic descriptions
|
|
135
|
+
"autoIndex": true,
|
|
142
136
|
|
|
143
|
-
|
|
137
|
+
// Write guard & prompt injection defenses
|
|
138
|
+
"guard": {
|
|
139
|
+
"enabled": true,
|
|
140
|
+
"maxFileSizeKb": 50,
|
|
141
|
+
"strictPatternCheck": true
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
- [`examples/build-agent.md`](examples/build-agent.md) -- developer that reads context before coding
|
|
145
|
+
```
|
|
147
146
|
|
|
148
|
-
|
|
147
|
+
---
|
|
149
148
|
|
|
150
|
-
|
|
149
|
+
### Local Development
|
|
151
150
|
|
|
152
151
|
```bash
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
# Clone and install dependencies
|
|
153
|
+
git clone [https://github.com/slxca/opencontext.git](https://github.com/slxca/opencontext.git)
|
|
154
|
+
cd opencontext
|
|
155
|
+
pnpm install
|
|
155
156
|
|
|
156
|
-
|
|
157
|
+
# Build & run tests
|
|
158
|
+
pnpm build
|
|
159
|
+
pnpm test
|
|
157
160
|
|
|
158
|
-
```gitignore
|
|
159
|
-
.opencontext/
|
|
160
161
|
```
|
|
161
162
|
|
|
162
|
-
|
|
163
|
+
---
|
|
163
164
|
|
|
164
|
-
|
|
165
|
+
### Documentation
|
|
165
166
|
|
|
166
|
-
|
|
167
|
-
pnpm install
|
|
168
|
-
pnpm build # compile TypeScript
|
|
169
|
-
pnpm typecheck # type-check without emitting
|
|
170
|
-
pnpm test # run vitest suite
|
|
171
|
-
pnpm start # start the MCP server
|
|
172
|
-
```
|
|
167
|
+
For advanced setup guides, guard parameters, and agent prompt templates, visit **[opencntx.dev/docs](https://www.google.com/search?q=https://opencntx.dev/docs)**.
|
|
173
168
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
```text
|
|
177
|
-
src/
|
|
178
|
-
index.ts CLI entrypoint (stdio transport, startup error handling)
|
|
179
|
-
server.ts McpServer factory and tool registration
|
|
180
|
-
context-store.ts Filesystem operations for .opencontext/
|
|
181
|
-
validation.ts Topic validation and input rules
|
|
182
|
-
types.ts Shared constants, error classes, and result helpers
|
|
183
|
-
test/
|
|
184
|
-
validation.test.ts Unit tests for topic validation
|
|
185
|
-
context-store.test.ts Unit tests for read/write/list operations
|
|
186
|
-
examples/
|
|
187
|
-
plan-agent.md Architect system prompt
|
|
188
|
-
build-agent.md Developer system prompt
|
|
189
|
-
README.md User documentation
|
|
190
|
-
LICENSE MIT license
|
|
191
|
-
```
|
|
169
|
+
### Contributing
|
|
192
170
|
|
|
193
|
-
|
|
171
|
+
Contributions are welcome. Please ensure all unit tests and typechecks pass before submitting a pull request:
|
|
194
172
|
|
|
195
|
-
|
|
173
|
+
```bash
|
|
174
|
+
pnpm typecheck && pnpm test
|
|
175
|
+
|
|
176
|
+
```
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface OpenContextConfig {
|
|
2
|
+
$schema?: string;
|
|
3
|
+
path?: string;
|
|
4
|
+
readOnly?: boolean;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
autoIndex?: boolean;
|
|
7
|
+
history?: {
|
|
8
|
+
enabled?: boolean;
|
|
9
|
+
maxBackupsPerTopic?: number;
|
|
10
|
+
retentionDays?: number;
|
|
11
|
+
};
|
|
12
|
+
guard?: {
|
|
13
|
+
enabled?: boolean;
|
|
14
|
+
maxFileSizeKb?: number;
|
|
15
|
+
strictPatternCheck?: boolean;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export type ResolvedConfig = Required<Omit<OpenContextConfig, "$schema">>;
|
|
19
|
+
export declare const DEFAULT_CONFIG: ResolvedConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Loads configuration from .opencontext.jsonc or .opencontext.json in the given directory.
|
|
22
|
+
* Falls back to DEFAULT_CONFIG if no file exists or parsing fails.
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadConfig(cwd?: string): Promise<ResolvedConfig>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
export const DEFAULT_CONFIG = {
|
|
4
|
+
path: ".opencontext",
|
|
5
|
+
readOnly: false,
|
|
6
|
+
disabled: false,
|
|
7
|
+
autoIndex: true,
|
|
8
|
+
history: {
|
|
9
|
+
enabled: false,
|
|
10
|
+
maxBackupsPerTopic: 5,
|
|
11
|
+
retentionDays: 7,
|
|
12
|
+
},
|
|
13
|
+
guard: {
|
|
14
|
+
enabled: true,
|
|
15
|
+
maxFileSizeKb: 50,
|
|
16
|
+
strictPatternCheck: true,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
const CONFIG_CANDIDATES = [".opencontext.jsonc", ".opencontext.json"];
|
|
20
|
+
/**
|
|
21
|
+
* Strips JSONC content into parseable JSON by removing comments and trailing commas.
|
|
22
|
+
* Handles single-line (//), multi-line (/* * /), and trailing commas.
|
|
23
|
+
* Trailing comma removal is token-aware to avoid modifying string literals.
|
|
24
|
+
*/
|
|
25
|
+
function stripJsonComments(raw) {
|
|
26
|
+
let result = "";
|
|
27
|
+
let i = 0;
|
|
28
|
+
const len = raw.length;
|
|
29
|
+
while (i < len) {
|
|
30
|
+
const ch = raw[i];
|
|
31
|
+
// Strings: copy verbatim (including escaped characters)
|
|
32
|
+
if (ch === '"') {
|
|
33
|
+
result += ch;
|
|
34
|
+
i++;
|
|
35
|
+
while (i < len && raw[i] !== '"') {
|
|
36
|
+
if (raw[i] === "\\") {
|
|
37
|
+
result += raw[i];
|
|
38
|
+
i++;
|
|
39
|
+
}
|
|
40
|
+
if (i < len) {
|
|
41
|
+
result += raw[i];
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (i < len) {
|
|
46
|
+
result += raw[i]; // closing quote
|
|
47
|
+
i++;
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// Single-line comment: skip until newline
|
|
52
|
+
if (ch === "/" && i + 1 < len && raw[i + 1] === "/") {
|
|
53
|
+
while (i < len && raw[i] !== "\n") {
|
|
54
|
+
i++;
|
|
55
|
+
}
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Multi-line comment: skip until */
|
|
59
|
+
if (ch === "/" && i + 1 < len && raw[i + 1] === "*") {
|
|
60
|
+
i += 2;
|
|
61
|
+
while (i < len - 1 && !(raw[i] === "*" && raw[i + 1] === "/")) {
|
|
62
|
+
i++;
|
|
63
|
+
}
|
|
64
|
+
i += 2; // skip */
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
// Trailing comma: skip comma if followed by optional whitespace/comments then } or ]
|
|
68
|
+
if (ch === ",") {
|
|
69
|
+
let j = i + 1;
|
|
70
|
+
// Skip whitespace and comments to find the next meaningful token
|
|
71
|
+
while (j < len) {
|
|
72
|
+
if (raw[j] === " " || raw[j] === "\t" || raw[j] === "\n" || raw[j] === "\r") {
|
|
73
|
+
j++;
|
|
74
|
+
}
|
|
75
|
+
else if (raw[j] === "/" && j + 1 < len && raw[j + 1] === "/") {
|
|
76
|
+
while (j < len && raw[j] !== "\n")
|
|
77
|
+
j++;
|
|
78
|
+
}
|
|
79
|
+
else if (raw[j] === "/" && j + 1 < len && raw[j + 1] === "*") {
|
|
80
|
+
j += 2;
|
|
81
|
+
while (j < len - 1 && !(raw[j] === "*" && raw[j + 1] === "/"))
|
|
82
|
+
j++;
|
|
83
|
+
j += 2;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (j < len && (raw[j] === "}" || raw[j] === "]")) {
|
|
90
|
+
i = j; // skip comma and whitespace/comments, continue from closing bracket
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// Not a trailing comma — keep it
|
|
94
|
+
result += ch;
|
|
95
|
+
i++;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
result += ch;
|
|
99
|
+
i++;
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
function deepMerge(target, source) {
|
|
104
|
+
const result = { ...target };
|
|
105
|
+
for (const key of Object.keys(source)) {
|
|
106
|
+
const sourceVal = source[key];
|
|
107
|
+
const targetVal = result[key];
|
|
108
|
+
if (sourceVal !== null &&
|
|
109
|
+
typeof sourceVal === "object" &&
|
|
110
|
+
!Array.isArray(sourceVal) &&
|
|
111
|
+
targetVal !== null &&
|
|
112
|
+
typeof targetVal === "object" &&
|
|
113
|
+
!Array.isArray(targetVal)) {
|
|
114
|
+
result[key] = deepMerge(targetVal, sourceVal);
|
|
115
|
+
}
|
|
116
|
+
else if (sourceVal !== undefined) {
|
|
117
|
+
result[key] = sourceVal;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Loads configuration from .opencontext.jsonc or .opencontext.json in the given directory.
|
|
124
|
+
* Falls back to DEFAULT_CONFIG if no file exists or parsing fails.
|
|
125
|
+
*/
|
|
126
|
+
export async function loadConfig(cwd = process.cwd()) {
|
|
127
|
+
for (const filename of CONFIG_CANDIDATES) {
|
|
128
|
+
const filePath = path.join(cwd, filename);
|
|
129
|
+
try {
|
|
130
|
+
const raw = await readFile(filePath, "utf8");
|
|
131
|
+
const cleaned = stripJsonComments(raw);
|
|
132
|
+
const parsed = JSON.parse(cleaned);
|
|
133
|
+
return deepMerge(DEFAULT_CONFIG, parsed);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (error.code === "ENOENT") {
|
|
137
|
+
continue; // file doesn't exist, try next candidate
|
|
138
|
+
}
|
|
139
|
+
console.error(`OpenContext: failed to parse ${filename}: ${error.message}`);
|
|
140
|
+
return DEFAULT_CONFIG;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return DEFAULT_CONFIG;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/context-store.d.ts
CHANGED
|
@@ -1,9 +1,63 @@
|
|
|
1
|
+
import { type ResolvedConfig } from "./config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manages context file storage operations.
|
|
4
|
+
* Handles reading, writing, and listing context files in the configured directory.
|
|
5
|
+
*/
|
|
1
6
|
export declare class ContextStore {
|
|
2
7
|
private readonly basePath;
|
|
3
|
-
|
|
8
|
+
private readonly config;
|
|
9
|
+
private readonly contextDir;
|
|
10
|
+
constructor(basePath?: string, config?: ResolvedConfig);
|
|
11
|
+
/** Returns the absolute path to the context directory. */
|
|
4
12
|
getContextDirectory(): string;
|
|
13
|
+
/** Returns the absolute path to a topic file. */
|
|
5
14
|
getTopicFilePath(topic: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Saves context content to a topic file.
|
|
17
|
+
* Validates payload using WriteGuard before writing.
|
|
18
|
+
* @param topicInput - Topic name (will be validated and trimmed)
|
|
19
|
+
* @param content - Markdown content to save
|
|
20
|
+
* @returns Success message with file location
|
|
21
|
+
* @throws UserInputError if validation fails
|
|
22
|
+
*/
|
|
6
23
|
saveContext(topicInput: string, content: string): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Reads context content from a topic file, or lists all topics if none specified.
|
|
26
|
+
* @param topicInput - Optional topic name to read
|
|
27
|
+
* @returns Topic content or list of available topics
|
|
28
|
+
* @throws UserInputError if topic doesn't exist or is invalid
|
|
29
|
+
*/
|
|
7
30
|
readContext(topicInput?: string): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Deletes a context topic file from the context directory.
|
|
33
|
+
* @param topicInput - Topic name to delete
|
|
34
|
+
* @returns Success message with confirmation
|
|
35
|
+
* @throws UserInputError if topic doesn't exist or is invalid
|
|
36
|
+
*/
|
|
37
|
+
deleteContext(topicInput: string): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Lists all available context topics.
|
|
40
|
+
* Scans the context directory for .md files and returns sorted topic names.
|
|
41
|
+
* @returns Sorted array of topic names
|
|
42
|
+
*/
|
|
8
43
|
listTopics(): Promise<string[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Parses YAML frontmatter from markdown content.
|
|
46
|
+
* Returns extracted fields or empty object if no frontmatter found.
|
|
47
|
+
* Uses simple line-by-line parsing — no external YAML dependency.
|
|
48
|
+
*/
|
|
49
|
+
private parseFrontmatter;
|
|
50
|
+
/**
|
|
51
|
+
* Extracts a short description from markdown content.
|
|
52
|
+
* Strategy: frontmatter description → first heading → first paragraph → fallback.
|
|
53
|
+
* @param content - Raw markdown content
|
|
54
|
+
* @returns Truncated description (max 120 chars)
|
|
55
|
+
*/
|
|
56
|
+
private extractDescription;
|
|
57
|
+
/**
|
|
58
|
+
* Rebuilds the auto-generated index.md file in the context directory.
|
|
59
|
+
* Scans all topic files, extracts metadata, and writes a compact index.
|
|
60
|
+
* @returns The generated index markdown content
|
|
61
|
+
*/
|
|
62
|
+
rebuildContextIndex(): Promise<string>;
|
|
9
63
|
}
|