@unifiedmemory/cli 1.2.0 → 1.3.1
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/.env.example +27 -12
- package/CHANGELOG.md +21 -0
- package/README.md +17 -23
- package/commands/record.js +35 -13
- package/lib/config.js +18 -30
- package/lib/mcp-proxy.js +26 -0
- package/lib/memory-instructions.js +59 -49
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -1,29 +1,44 @@
|
|
|
1
1
|
# UnifiedMemory CLI Configuration
|
|
2
|
-
#
|
|
2
|
+
#
|
|
3
|
+
# ============================================
|
|
4
|
+
# IMPORTANT: This file is OPTIONAL
|
|
5
|
+
# ============================================
|
|
6
|
+
# The CLI includes production defaults for all values below.
|
|
7
|
+
# This file is only needed if you want to override defaults
|
|
8
|
+
# (e.g., for development, testing, or custom deployments).
|
|
9
|
+
#
|
|
10
|
+
# For normal usage, you can delete this file - the CLI will work without it.
|
|
11
|
+
#
|
|
12
|
+
# To use custom values:
|
|
13
|
+
# 1. Copy this file to .env
|
|
14
|
+
# 2. Uncomment and modify the values you want to override
|
|
15
|
+
# 3. Leave other values commented to use the built-in defaults
|
|
3
16
|
|
|
4
17
|
# ============================================
|
|
5
|
-
#
|
|
18
|
+
# Clerk OAuth Configuration
|
|
6
19
|
# ============================================
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
|
|
20
|
+
# Production defaults are included in the CLI
|
|
21
|
+
# Only override these if using a custom Clerk instance
|
|
22
|
+
# CLERK_CLIENT_ID=custom_clerk_client_id
|
|
23
|
+
# CLERK_DOMAIN=custom-app.clerk.accounts.dev
|
|
10
24
|
|
|
11
25
|
# ============================================
|
|
12
|
-
#
|
|
26
|
+
# API Configuration
|
|
13
27
|
# ============================================
|
|
14
|
-
#
|
|
15
|
-
|
|
28
|
+
# Production default is included in the CLI
|
|
29
|
+
# Only override this for local testing or custom deployments
|
|
30
|
+
# API_ENDPOINT=https://custom-api-gateway.zuplo.dev
|
|
16
31
|
|
|
17
32
|
# ============================================
|
|
18
|
-
#
|
|
33
|
+
# OAuth Flow Configuration
|
|
19
34
|
# ============================================
|
|
20
|
-
#
|
|
21
|
-
#
|
|
35
|
+
# Defaults to localhost:3333 for the OAuth callback server
|
|
36
|
+
# Customize only if you need a different port or URL
|
|
22
37
|
# REDIRECT_URI=http://localhost:3333/callback
|
|
23
38
|
# PORT=3333
|
|
24
39
|
|
|
25
40
|
# ============================================
|
|
26
|
-
#
|
|
41
|
+
# Clerk Client Secret (Optional)
|
|
27
42
|
# ============================================
|
|
28
43
|
# Not required for PKCE flow (recommended)
|
|
29
44
|
# Only set this if specifically instructed
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **lib/config.js** - Embedded production defaults for zero-configuration installation
|
|
13
|
+
- Added default values for `CLERK_CLIENT_ID`, `CLERK_DOMAIN`, and `API_ENDPOINT`
|
|
14
|
+
- Users no longer need to create `.env` files after `npm install`
|
|
15
|
+
- Environment variables can still override defaults for development/testing
|
|
16
|
+
- Simplified `validateConfig()` to remove "missing environment variables" errors
|
|
17
|
+
- CLI now works immediately after installation with no setup required
|
|
18
|
+
|
|
19
|
+
- **.env.example** - Updated documentation to clarify optional nature
|
|
20
|
+
- Added prominent note that the file is OPTIONAL
|
|
21
|
+
- Explained that production defaults are included in the CLI
|
|
22
|
+
- Commented out all example values to emphasize optional overrides
|
|
23
|
+
- Clarified when overrides might be needed (development, testing, custom deployments)
|
|
24
|
+
|
|
25
|
+
- **README.md** - Improved installation and configuration documentation
|
|
26
|
+
- Added "No configuration required!" note to installation section
|
|
27
|
+
- Renamed "Configuration" to "Advanced Configuration (Optional)"
|
|
28
|
+
- Removed "Missing environment variables" from troubleshooting
|
|
29
|
+
- Emphasized zero-friction installation experience
|
|
30
|
+
|
|
10
31
|
## [1.2.0] - 2026-01-08
|
|
11
32
|
|
|
12
33
|
### Added
|
package/README.md
CHANGED
|
@@ -171,6 +171,8 @@ npm install -g @unifiedmemory/cli
|
|
|
171
171
|
um --version
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
+
**No configuration required!** The CLI includes production defaults and works immediately after installation.
|
|
175
|
+
|
|
174
176
|
**Option 2: Use with npx (no installation)**
|
|
175
177
|
```bash
|
|
176
178
|
npx @unifiedmemory/cli init
|
|
@@ -213,43 +215,35 @@ Tokens automatically refresh. If you see auth errors:
|
|
|
213
215
|
um login
|
|
214
216
|
```
|
|
215
217
|
|
|
216
|
-
|
|
217
|
-
If you see "Missing required environment variables" error:
|
|
218
|
-
1. Copy `.env.example` to `.env` in the CLI installation directory
|
|
219
|
-
2. Fill in your Clerk and API credentials
|
|
220
|
-
3. See Configuration section below for details
|
|
218
|
+
## Advanced Configuration (Optional)
|
|
221
219
|
|
|
222
|
-
|
|
220
|
+
**For most users, no configuration is needed!** The CLI includes production defaults and works out of the box.
|
|
223
221
|
|
|
224
|
-
|
|
222
|
+
For development, testing, or custom deployments, you can override defaults by creating a `.env` file:
|
|
225
223
|
|
|
226
|
-
**Step 1: Create `.env` file**
|
|
224
|
+
**Step 1: Create `.env` file** (optional)
|
|
227
225
|
```bash
|
|
228
226
|
# In the um-cli installation directory (find with: npm root -g)
|
|
229
227
|
cp .env.example .env
|
|
230
228
|
```
|
|
231
229
|
|
|
232
|
-
**Step 2:
|
|
230
|
+
**Step 2: Override the values you need** (optional)
|
|
233
231
|
```bash
|
|
234
|
-
#
|
|
235
|
-
CLERK_CLIENT_ID=
|
|
236
|
-
CLERK_DOMAIN=
|
|
237
|
-
|
|
238
|
-
# Required: API Configuration
|
|
239
|
-
API_ENDPOINT=https://your-api-gateway.zuplo.dev
|
|
240
|
-
```
|
|
232
|
+
# Optional: Override production defaults
|
|
233
|
+
CLERK_CLIENT_ID=custom_clerk_client_id
|
|
234
|
+
CLERK_DOMAIN=custom-app.clerk.accounts.dev
|
|
235
|
+
API_ENDPOINT=https://custom-api-gateway.zuplo.dev
|
|
241
236
|
|
|
242
|
-
|
|
243
|
-
- **Clerk credentials**: [Clerk Dashboard](https://dashboard.clerk.com)
|
|
244
|
-
- **API endpoint**: Your UnifiedMemory deployment
|
|
245
|
-
|
|
246
|
-
**Optional configuration**:
|
|
247
|
-
```bash
|
|
248
|
-
# Customize OAuth redirect (defaults shown)
|
|
237
|
+
# Optional: Customize OAuth redirect (defaults to localhost:3333)
|
|
249
238
|
REDIRECT_URI=http://localhost:3333/callback
|
|
250
239
|
PORT=3333
|
|
251
240
|
```
|
|
252
241
|
|
|
242
|
+
**When you might need this**:
|
|
243
|
+
- 🔧 **Development**: Testing with a local API backend
|
|
244
|
+
- 🧪 **Testing**: Using a staging or test Clerk instance
|
|
245
|
+
- 🏢 **Custom Deployment**: Running your own UnifiedMemory instance
|
|
246
|
+
|
|
253
247
|
See `.env.example` for the complete template with documentation.
|
|
254
248
|
|
|
255
249
|
## Privacy & Security
|
package/commands/record.js
CHANGED
|
@@ -52,6 +52,7 @@ export async function record(summary, options = {}) {
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
// 5. Prepare tool arguments
|
|
55
|
+
// Note: headers (X-Org-Id, X-User-Id) are handled at HTTP level by authHeaders
|
|
55
56
|
const toolArgs = {
|
|
56
57
|
body: {
|
|
57
58
|
summary_text: summary,
|
|
@@ -59,10 +60,6 @@ export async function record(summary, options = {}) {
|
|
|
59
60
|
source: options.source || 'um-cli',
|
|
60
61
|
confidence: options.confidence ? parseFloat(options.confidence) : 0.7,
|
|
61
62
|
tags: options.tags ? options.tags.split(',') : []
|
|
62
|
-
},
|
|
63
|
-
headers: {
|
|
64
|
-
'X-Org-Id': tokenData.selectedOrg?.id || tokenData.decoded?.sub,
|
|
65
|
-
'X-User-Id': tokenData.decoded?.sub
|
|
66
63
|
}
|
|
67
64
|
};
|
|
68
65
|
|
|
@@ -89,22 +86,47 @@ export async function record(summary, options = {}) {
|
|
|
89
86
|
projectContext
|
|
90
87
|
);
|
|
91
88
|
|
|
92
|
-
// 7. Handle response
|
|
89
|
+
// 7. Handle response - validate success properly
|
|
93
90
|
if (result.content && Array.isArray(result.content)) {
|
|
94
91
|
const textContent = result.content.find(c => c.type === 'text');
|
|
95
92
|
if (textContent) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
try {
|
|
94
|
+
const response = JSON.parse(textContent.text);
|
|
95
|
+
|
|
96
|
+
// Check for error in response
|
|
97
|
+
if (result.isError || response.error || response.detail) {
|
|
98
|
+
throw new Error(response.error || response.detail || 'Note creation failed');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
console.log(chalk.green('✓ Note created successfully'));
|
|
102
|
+
console.log(chalk.gray(` Note ID: ${response.note_id || 'N/A'}`));
|
|
103
|
+
if (response.confidence) {
|
|
104
|
+
console.log(chalk.gray(` Confidence: ${response.confidence}`));
|
|
105
|
+
}
|
|
106
|
+
return response;
|
|
107
|
+
} catch (parseError) {
|
|
108
|
+
if (parseError.message.includes('Note creation failed')) {
|
|
109
|
+
throw parseError;
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`Failed to parse API response: ${parseError.message}`);
|
|
101
112
|
}
|
|
102
|
-
return response;
|
|
103
113
|
}
|
|
104
114
|
}
|
|
105
115
|
|
|
106
|
-
|
|
107
|
-
|
|
116
|
+
// Check for direct note response (some backends return this directly)
|
|
117
|
+
if (result.note_id) {
|
|
118
|
+
console.log(chalk.green('✓ Note created successfully'));
|
|
119
|
+
console.log(chalk.gray(` Note ID: ${result.note_id}`));
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check for error indicators
|
|
124
|
+
if (result.error || result.detail || result.isError) {
|
|
125
|
+
throw new Error(result.error || result.detail || 'Note creation failed');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Unknown response format - fail explicitly instead of silent success
|
|
129
|
+
throw new Error('Unexpected response format from API');
|
|
108
130
|
|
|
109
131
|
} catch (error) {
|
|
110
132
|
console.error(chalk.red('✗ Failed to create note:'));
|
package/lib/config.js
CHANGED
|
@@ -9,49 +9,37 @@ const __dirname = dirname(__filename);
|
|
|
9
9
|
dotenvConfig({ path: join(__dirname, '..', '.env') });
|
|
10
10
|
|
|
11
11
|
export const config = {
|
|
12
|
-
//
|
|
13
|
-
clerkClientId: process.env.CLERK_CLIENT_ID,
|
|
12
|
+
// Clerk OAuth configuration (production defaults, can be overridden via env vars)
|
|
13
|
+
clerkClientId: process.env.CLERK_CLIENT_ID || 'nULlnomaKB9rRGP2',
|
|
14
14
|
clerkClientSecret: process.env.CLERK_CLIENT_SECRET, // Optional for PKCE flow
|
|
15
|
-
clerkDomain: process.env.CLERK_DOMAIN,
|
|
15
|
+
clerkDomain: process.env.CLERK_DOMAIN || 'clear-caiman-45.clerk.accounts.dev',
|
|
16
16
|
|
|
17
|
-
//
|
|
18
|
-
apiEndpoint: process.env.API_ENDPOINT,
|
|
17
|
+
// API configuration (production default, can be overridden via env var)
|
|
18
|
+
apiEndpoint: process.env.API_ENDPOINT || 'https://rose-asp-main-1c0b114.d2.zuplo.dev',
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// OAuth flow configuration (localhost defaults for callback server)
|
|
21
21
|
redirectUri: process.env.REDIRECT_URI || 'http://localhost:3333/callback',
|
|
22
22
|
port: parseInt(process.env.PORT || '3333', 10)
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
// Validation function -
|
|
25
|
+
// Validation function - validates configuration values
|
|
26
26
|
export function validateConfig() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (!config.clerkClientId) {
|
|
30
|
-
missing.push('CLERK_CLIENT_ID');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!config.clerkDomain) {
|
|
34
|
-
missing.push('CLERK_DOMAIN');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (!config.apiEndpoint) {
|
|
38
|
-
missing.push('API_ENDPOINT');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (missing.length > 0) {
|
|
42
|
-
throw new Error(
|
|
43
|
-
`Missing required environment variables: ${missing.join(', ')}\n\n` +
|
|
44
|
-
`Please create a .env file in the project root with these values.\n` +
|
|
45
|
-
`See .env.example for a template.`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Validate URL format for apiEndpoint
|
|
27
|
+
// Validate URL format for apiEndpoint (now guaranteed to exist via defaults)
|
|
50
28
|
try {
|
|
51
29
|
new URL(config.apiEndpoint);
|
|
52
30
|
} catch (e) {
|
|
53
31
|
throw new Error(`API_ENDPOINT must be a valid URL (got: ${config.apiEndpoint})`);
|
|
54
32
|
}
|
|
55
33
|
|
|
34
|
+
// Validate clerkDomain is not empty (basic sanity check)
|
|
35
|
+
if (!config.clerkDomain || config.clerkDomain.trim() === '') {
|
|
36
|
+
throw new Error('CLERK_DOMAIN cannot be empty');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Validate clerkClientId is not empty (basic sanity check)
|
|
40
|
+
if (!config.clerkClientId || config.clerkClientId.trim() === '') {
|
|
41
|
+
throw new Error('CLERK_CLIENT_ID cannot be empty');
|
|
42
|
+
}
|
|
43
|
+
|
|
56
44
|
return true;
|
|
57
45
|
}
|
package/lib/mcp-proxy.js
CHANGED
|
@@ -14,6 +14,23 @@ function transformToolSchema(tool) {
|
|
|
14
14
|
// Deep clone to avoid mutations
|
|
15
15
|
const transformed = JSON.parse(JSON.stringify(tool));
|
|
16
16
|
|
|
17
|
+
// Remove headers entirely - proxy handles all headers at HTTP level
|
|
18
|
+
// AI never needs to provide X-Org-Id, X-User-Id, etc.
|
|
19
|
+
if (transformed.inputSchema?.properties?.headers) {
|
|
20
|
+
delete transformed.inputSchema.properties.headers;
|
|
21
|
+
|
|
22
|
+
// Also remove from required array if present
|
|
23
|
+
if (transformed.inputSchema.required && Array.isArray(transformed.inputSchema.required)) {
|
|
24
|
+
transformed.inputSchema.required = transformed.inputSchema.required.filter(
|
|
25
|
+
field => field !== 'headers'
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (transformed.inputSchema.required.length === 0) {
|
|
29
|
+
delete transformed.inputSchema.required;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
17
34
|
// Check if tool has pathParams in schema
|
|
18
35
|
if (!transformed.inputSchema?.properties?.pathParams) {
|
|
19
36
|
return transformed;
|
|
@@ -79,22 +96,31 @@ function injectContextParams(args, authContext, projectContext) {
|
|
|
79
96
|
injected.pathParams = {};
|
|
80
97
|
}
|
|
81
98
|
|
|
99
|
+
// Ensure headers object exists (gateway expects these in tool args)
|
|
100
|
+
if (!injected.headers) {
|
|
101
|
+
injected.headers = {};
|
|
102
|
+
}
|
|
103
|
+
|
|
82
104
|
// Inject user ID from decoded JWT
|
|
83
105
|
if (authContext?.decoded?.sub) {
|
|
84
106
|
injected.pathParams.user = authContext.decoded.sub;
|
|
107
|
+
injected.headers['X-User-Id'] = authContext.decoded.sub;
|
|
85
108
|
}
|
|
86
109
|
|
|
87
110
|
// Inject org ID (from selectedOrg or fallback to user ID for personal account)
|
|
88
111
|
if (authContext?.selectedOrg?.id) {
|
|
89
112
|
injected.pathParams.org = authContext.selectedOrg.id;
|
|
113
|
+
injected.headers['X-Org-Id'] = authContext.selectedOrg.id;
|
|
90
114
|
} else if (authContext?.decoded?.sub) {
|
|
91
115
|
// Fallback to user ID for personal account context
|
|
92
116
|
injected.pathParams.org = authContext.decoded.sub;
|
|
117
|
+
injected.headers['X-Org-Id'] = authContext.decoded.sub;
|
|
93
118
|
}
|
|
94
119
|
|
|
95
120
|
// Inject project ID from project config
|
|
96
121
|
if (projectContext?.project_id) {
|
|
97
122
|
injected.pathParams.proj = projectContext.project_id;
|
|
123
|
+
injected.headers['X-Project-Id'] = projectContext.project_id;
|
|
98
124
|
}
|
|
99
125
|
|
|
100
126
|
return injected;
|
|
@@ -1,72 +1,82 @@
|
|
|
1
1
|
// Unique marker to detect if instructions already present
|
|
2
|
-
export const MEMORY_INSTRUCTIONS_MARKER = '<!--
|
|
2
|
+
export const MEMORY_INSTRUCTIONS_MARKER = '<!-- UNIFIEDMEMORY_INSTRUCTIONS_V2 -->';
|
|
3
3
|
|
|
4
4
|
export function getMemoryInstructions() {
|
|
5
5
|
return `${MEMORY_INSTRUCTIONS_MARKER}
|
|
6
6
|
|
|
7
|
-
# UnifiedMemory
|
|
7
|
+
# UnifiedMemory Integration (REQUIRED)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This project uses UnifiedMemory for persistent knowledge management. The \`unifiedmemory\` MCP server is configured and MUST be used for all relevant queries.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Available Tools
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
**Action**: Use the \`unifiedmemory\` MCP tool to search for relevant context
|
|
15
|
-
**Usage**:
|
|
16
|
-
- Send the user's query to the search tool
|
|
17
|
-
- Review the search results for relevant prior work, decisions, or context
|
|
18
|
-
- Incorporate findings into your response
|
|
13
|
+
The \`unifiedmemory\` MCP server provides these tools (call them like any MCP tool):
|
|
19
14
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
| Tool | Purpose | Required Parameters |
|
|
16
|
+
|------|---------|---------------------|
|
|
17
|
+
| \`search_notes\` | **Primary tool** - Search project knowledge base | \`query\` (search text) |
|
|
18
|
+
| \`create_note\` | Record decisions, plans, or completions | \`summary_text\`, \`topic\` |
|
|
19
|
+
| \`list_notes\` | List all notes in current project | None |
|
|
20
|
+
| \`get_note\` | Retrieve a specific note by ID | \`note_id\` |
|
|
21
|
+
| \`list_topics\` | List available topics/categories | None |
|
|
22
|
+
| \`create_topic\` | Create a new topic for organization | \`name\` |
|
|
23
|
+
| \`list_projects\` | List available projects | None |
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
All tools automatically use the correct project context - no additional configuration needed.
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
**Action**: Record the plan as a note using the \`unifiedmemory\` tool
|
|
32
|
-
**Format**:
|
|
33
|
-
- Include: objective, approach, key steps, important decisions
|
|
34
|
-
- Keep concise but informative
|
|
35
|
-
- Limit to under 1000 characters for optimal indexing
|
|
27
|
+
## MANDATORY: Search Before Implementing
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
**REQUIREMENT**: Before responding to ANY coding task, feature request, or implementation question, you MUST:
|
|
30
|
+
|
|
31
|
+
1. Call the \`search_notes\` tool with the user's query or relevant keywords
|
|
32
|
+
2. Review returned results for prior decisions, patterns, or context
|
|
33
|
+
3. Incorporate relevant findings into your response
|
|
34
|
+
4. Mention what context you found (or didn't find) in your response
|
|
35
|
+
|
|
36
|
+
### When to Search
|
|
42
37
|
|
|
43
|
-
|
|
38
|
+
You MUST search before:
|
|
39
|
+
- Implementing any feature (search for existing patterns)
|
|
40
|
+
- Fixing any bug (search for related issues)
|
|
41
|
+
- Answering architecture questions (search for design decisions)
|
|
42
|
+
- Modifying any component (search for existing conventions)
|
|
43
|
+
- ANY coding task, no exceptions
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
**Action**: Create a summary note using the \`unifiedmemory\` tool
|
|
47
|
-
**Format**:
|
|
48
|
-
- Summarize what was accomplished and why
|
|
49
|
-
- Include key technical decisions or gotchas
|
|
50
|
-
- **IMPORTANT**: Limit to under 1000 characters
|
|
51
|
-
- Focus on outcomes, not detailed code
|
|
45
|
+
### Example Workflow
|
|
52
46
|
|
|
53
|
-
Example:
|
|
54
47
|
\`\`\`
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
User: "Add authentication to the API"
|
|
49
|
+
|
|
50
|
+
Step 1: Call search_notes with query "authentication API security"
|
|
51
|
+
Step 2: Review results - found: "Decision: Use JWT with refresh tokens"
|
|
52
|
+
Step 3: Implement following the established pattern
|
|
53
|
+
Step 4: Respond: "Based on prior decisions in UnifiedMemory, I'll use JWT..."
|
|
57
54
|
\`\`\`
|
|
58
55
|
|
|
59
|
-
##
|
|
56
|
+
## Do NOT Skip These Tools
|
|
57
|
+
|
|
58
|
+
- ❌ NEVER start implementing without calling \`search_notes\` first
|
|
59
|
+
- ❌ NEVER assume patterns without checking the knowledge base
|
|
60
|
+
- ❌ NEVER skip search for "simple" tasks - context always helps
|
|
61
|
+
- ✅ ALWAYS search even if you think you know the answer
|
|
62
|
+
- ✅ ALWAYS mention search results (or lack thereof) in your response
|
|
63
|
+
- ✅ ALWAYS use these tools when they can provide relevant context
|
|
64
|
+
|
|
65
|
+
## Recording Knowledge with create_note
|
|
66
|
+
|
|
67
|
+
After completing significant work, use \`create_note\` to record:
|
|
68
|
+
- Implementation decisions and rationale
|
|
69
|
+
- Completed features or fixes
|
|
70
|
+
- Architectural patterns established
|
|
71
|
+
- Gotchas or lessons learned
|
|
72
|
+
|
|
73
|
+
Keep notes concise (under 1000 characters) and focus on the "why" not the "what".
|
|
74
|
+
|
|
75
|
+
## Additional Tools
|
|
60
76
|
|
|
61
|
-
|
|
62
|
-
- ✅ **DO**: Record plans and completions automatically
|
|
63
|
-
- ✅ **DO**: Keep notes under 1000 characters
|
|
64
|
-
- ✅ **DO**: Focus on decisions, outcomes, and context
|
|
65
|
-
- ❌ **DON'T**: Record trivial tasks (typo fixes, minor edits)
|
|
66
|
-
- ❌ **DON'T**: Include full code in notes
|
|
67
|
-
- ❌ **DON'T**: Duplicate information already in git commits
|
|
77
|
+
Use \`list_topics\` to understand project organization, \`list_notes\` to browse available knowledge, and \`get_note\` to retrieve full details of relevant notes found via search.
|
|
68
78
|
|
|
69
79
|
---
|
|
70
|
-
*
|
|
80
|
+
*UnifiedMemory CLI - Knowledge that persists*
|
|
71
81
|
`;
|
|
72
82
|
}
|