@kawacode/mcp 5.0.4 → 5.1.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/README.md +52 -62
- package/build/services/muninn-ipc.d.ts +1 -1
- package/build/services/muninn-ipc.js +1 -1
- package/build/tools/evolve-decisions.d.ts +0 -6
- package/build/tools/evolve-decisions.js +1 -3
- package/build/tools/evolve-decisions.js.map +1 -1
- package/build/tools/get-session-decisions.d.ts +1 -0
- package/build/tools/get-session-decisions.js.map +1 -1
- package/build/tools/index.d.ts +3 -6
- package/build/tools/infer-history.d.ts +2 -6
- package/build/tools/infer-history.js +26 -12
- package/build/tools/infer-history.js.map +1 -1
- package/build/tools/record-decision.d.ts +6 -0
- package/build/tools/record-decision.js +2 -0
- package/build/tools/record-decision.js.map +1 -1
- package/build/tools/resolve-origin.js +1 -0
- package/build/tools/resolve-origin.js.map +1 -1
- package/package.json +1 -1
- package/build/services/active-intent-store.d.ts +0 -36
- package/build/services/active-intent-store.js +0 -45
- package/build/services/active-intent-store.js.map +0 -1
- package/build/services/kawa-api.d.ts +0 -131
- package/build/services/kawa-api.js +0 -239
- package/build/services/kawa-api.js.map +0 -1
- package/build/services/repo-encryption.d.ts +0 -46
- package/build/services/repo-encryption.js +0 -92
- package/build/services/repo-encryption.js.map +0 -1
- package/build/services/storage-decryption.d.ts +0 -52
- package/build/services/storage-decryption.js +0 -162
- package/build/services/storage-decryption.js.map +0 -1
- package/build/tools/get-project-context.d.ts +0 -82
- package/build/tools/get-project-context.js +0 -73
- package/build/tools/get-project-context.js.map +0 -1
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Storage decryption service for reading auth tokens from Muninn's encrypted storage.
|
|
3
|
-
*
|
|
4
|
-
* This module replicates Muninn's storage encryption scheme to read the auth token
|
|
5
|
-
* from ~/.kawa-code/.storage.caw without requiring manual env var configuration.
|
|
6
|
-
*
|
|
7
|
-
* Encryption details (must match Muninn's encryption.rs):
|
|
8
|
-
* - Key derivation: username:hostname with salt "kawa-storage-encryption-v1"
|
|
9
|
-
* - Algorithm: PBKDF2-HMAC-SHA256, 100,000 iterations
|
|
10
|
-
* - Cipher: AES-256-GCM
|
|
11
|
-
* - Format: hex(iv):hex(ciphertext):hex(auth_tag)
|
|
12
|
-
*/
|
|
13
|
-
import * as crypto from 'crypto';
|
|
14
|
-
import * as fs from 'fs';
|
|
15
|
-
import * as os from 'os';
|
|
16
|
-
import * as path from 'path';
|
|
17
|
-
/**
|
|
18
|
-
* Derive storage encryption key from username and hostname
|
|
19
|
-
*
|
|
20
|
-
* Matches Muninn's derive_storage_key() implementation:
|
|
21
|
-
* - Key material: "username:hostname"
|
|
22
|
-
* - Salt: "kawa-storage-encryption-v1"
|
|
23
|
-
* - Algorithm: PBKDF2-HMAC-SHA256
|
|
24
|
-
* - Iterations: 100,000
|
|
25
|
-
* - Key length: 32 bytes
|
|
26
|
-
*/
|
|
27
|
-
function deriveStorageKey() {
|
|
28
|
-
const username = process.env.USER || process.env.USERNAME || 'unknown';
|
|
29
|
-
const hostname = os.hostname() || 'unknown';
|
|
30
|
-
const keyMaterial = `${username}:${hostname}`;
|
|
31
|
-
const salt = 'kawa-storage-encryption-v1';
|
|
32
|
-
// PBKDF2-HMAC-SHA256, 100,000 iterations, 32-byte output
|
|
33
|
-
return crypto.pbkdf2Sync(keyMaterial, salt, 100_000, 32, 'sha256');
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Decrypt storage file content
|
|
37
|
-
*
|
|
38
|
-
* Format: hex(iv):hex(ciphertext_with_auth_tag):hex(auth_tag)
|
|
39
|
-
* The ciphertext includes the auth tag at the end (last 16 bytes).
|
|
40
|
-
* AES-GCM verifies the auth tag automatically during decryption.
|
|
41
|
-
*/
|
|
42
|
-
function decryptStorage(encryptedData) {
|
|
43
|
-
const key = deriveStorageKey();
|
|
44
|
-
// Parse format: hex(iv):hex(ciphertext):hex(auth_tag)
|
|
45
|
-
const parts = encryptedData.split(':');
|
|
46
|
-
if (parts.length !== 3) {
|
|
47
|
-
throw new Error('Invalid encrypted storage format (expected 3 parts)');
|
|
48
|
-
}
|
|
49
|
-
const iv = Buffer.from(parts[0], 'hex');
|
|
50
|
-
const ciphertextWithTag = Buffer.from(parts[1], 'hex');
|
|
51
|
-
const authTag = Buffer.from(parts[2], 'hex');
|
|
52
|
-
// Verify IV length
|
|
53
|
-
if (iv.length !== 12) {
|
|
54
|
-
throw new Error(`Invalid IV length (expected 12, got ${iv.length})`);
|
|
55
|
-
}
|
|
56
|
-
// Verify auth tag length
|
|
57
|
-
if (authTag.length !== 16) {
|
|
58
|
-
throw new Error(`Invalid auth tag length (expected 16, got ${authTag.length})`);
|
|
59
|
-
}
|
|
60
|
-
// Create decipher for AES-256-GCM
|
|
61
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
|
|
62
|
-
decipher.setAuthTag(authTag);
|
|
63
|
-
// Decrypt (note: ciphertextWithTag includes the auth tag at the end, but we
|
|
64
|
-
// extract just the ciphertext portion for decryption since we set the auth tag separately)
|
|
65
|
-
const ciphertext = ciphertextWithTag.subarray(0, ciphertextWithTag.length - 16);
|
|
66
|
-
let plaintext = decipher.update(ciphertext, undefined, 'utf8');
|
|
67
|
-
plaintext += decipher.final('utf8');
|
|
68
|
-
return plaintext;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Check if content is in encrypted storage format
|
|
72
|
-
*
|
|
73
|
-
* Encrypted format: hex(iv):hex(ciphertext):hex(auth_tag)
|
|
74
|
-
* All three parts should be valid hex strings
|
|
75
|
-
*/
|
|
76
|
-
function isEncryptedStorage(content) {
|
|
77
|
-
const parts = content.split(':');
|
|
78
|
-
if (parts.length !== 3) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
// All parts should be valid hex (even length, only hex chars)
|
|
82
|
-
return parts.every(part => {
|
|
83
|
-
return part.length > 0 &&
|
|
84
|
-
part.length % 2 === 0 &&
|
|
85
|
-
/^[0-9a-fA-F]+$/.test(part);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Get the storage file path
|
|
90
|
-
*
|
|
91
|
-
* Returns ~/.kawa-code/.storage.caw
|
|
92
|
-
*/
|
|
93
|
-
function getStoragePath() {
|
|
94
|
-
const homeDir = os.homedir();
|
|
95
|
-
return path.join(homeDir, '.kawa-code', '.storage.caw');
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Read and decrypt the storage file
|
|
99
|
-
*
|
|
100
|
-
* Returns the parsed storage data or null if unavailable/corrupted.
|
|
101
|
-
* Handles both encrypted and legacy unencrypted formats.
|
|
102
|
-
*/
|
|
103
|
-
export function readStorage() {
|
|
104
|
-
try {
|
|
105
|
-
const storagePath = getStoragePath();
|
|
106
|
-
if (!fs.existsSync(storagePath)) {
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
const content = fs.readFileSync(storagePath, 'utf8').trim();
|
|
110
|
-
if (!content) {
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
// Decrypt if encrypted, otherwise treat as legacy plaintext JSON
|
|
114
|
-
let plaintext;
|
|
115
|
-
if (isEncryptedStorage(content)) {
|
|
116
|
-
try {
|
|
117
|
-
plaintext = decryptStorage(content);
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
120
|
-
console.error('Failed to decrypt storage (hostname/username may have changed):', err);
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
// Legacy unencrypted format
|
|
126
|
-
plaintext = content;
|
|
127
|
-
}
|
|
128
|
-
// Parse JSON
|
|
129
|
-
const data = JSON.parse(plaintext);
|
|
130
|
-
return data;
|
|
131
|
-
}
|
|
132
|
-
catch (err) {
|
|
133
|
-
console.error('Failed to read storage file:', err);
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Extract auth token from storage
|
|
139
|
-
*
|
|
140
|
-
* Returns the access token if available, otherwise null.
|
|
141
|
-
*/
|
|
142
|
-
export function getAuthTokenFromStorage() {
|
|
143
|
-
const storage = readStorage();
|
|
144
|
-
if (!storage?.auth?.tokens?.access?.token) {
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
return storage.auth.tokens.access.token;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Get full auth data from storage (user + tokens)
|
|
151
|
-
*/
|
|
152
|
-
export function getAuthFromStorage() {
|
|
153
|
-
const storage = readStorage();
|
|
154
|
-
if (!storage?.auth?.user || !storage?.auth?.tokens) {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
user: storage.auth.user,
|
|
159
|
-
tokens: storage.auth.tokens
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
//# sourceMappingURL=storage-decryption.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage-decryption.js","sourceRoot":"","sources":["../../src/services/storage-decryption.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export declare const getProjectContextSchema: z.ZodObject<{
|
|
3
|
-
repoOrigin: z.ZodString;
|
|
4
|
-
repoPath: z.ZodString;
|
|
5
|
-
maxDecisions: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
6
|
-
maxTeamIntents: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
7
|
-
includeTeamIntents: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
8
|
-
}, "strip", z.ZodTypeAny, {
|
|
9
|
-
repoOrigin: string;
|
|
10
|
-
repoPath: string;
|
|
11
|
-
maxDecisions: number;
|
|
12
|
-
maxTeamIntents: number;
|
|
13
|
-
includeTeamIntents: boolean;
|
|
14
|
-
}, {
|
|
15
|
-
repoOrigin: string;
|
|
16
|
-
repoPath: string;
|
|
17
|
-
maxDecisions?: number | undefined;
|
|
18
|
-
maxTeamIntents?: number | undefined;
|
|
19
|
-
includeTeamIntents?: boolean | undefined;
|
|
20
|
-
}>;
|
|
21
|
-
export type GetProjectContextInput = z.infer<typeof getProjectContextSchema>;
|
|
22
|
-
export interface ActiveIntent {
|
|
23
|
-
id: string;
|
|
24
|
-
title: string;
|
|
25
|
-
description: string;
|
|
26
|
-
templateType: string;
|
|
27
|
-
status: string;
|
|
28
|
-
branch: string;
|
|
29
|
-
}
|
|
30
|
-
export interface TeamIntent {
|
|
31
|
-
id: string;
|
|
32
|
-
title: string;
|
|
33
|
-
author: string;
|
|
34
|
-
status: string;
|
|
35
|
-
templateType: string;
|
|
36
|
-
}
|
|
37
|
-
export interface RecentDecision {
|
|
38
|
-
intentId: string;
|
|
39
|
-
type: string;
|
|
40
|
-
summary: string;
|
|
41
|
-
}
|
|
42
|
-
export interface GetProjectContextResponse {
|
|
43
|
-
projectOrigin: string;
|
|
44
|
-
projectPath: string;
|
|
45
|
-
activeIntent: ActiveIntent | null;
|
|
46
|
-
teamIntents: TeamIntent[];
|
|
47
|
-
teamIntentCount: number;
|
|
48
|
-
recentDecisions: RecentDecision[];
|
|
49
|
-
summary: {
|
|
50
|
-
hasActiveIntent: boolean;
|
|
51
|
-
activeIntentTitle: string | null;
|
|
52
|
-
teamMembersWorking: number;
|
|
53
|
-
teamIntentsShown: number;
|
|
54
|
-
teamIntentsTotal: number;
|
|
55
|
-
recentDecisionCount: number;
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
export declare function getProjectContext(input: GetProjectContextInput): Promise<GetProjectContextResponse>;
|
|
59
|
-
export declare const getProjectContextTool: {
|
|
60
|
-
name: string;
|
|
61
|
-
description: string;
|
|
62
|
-
inputSchema: z.ZodObject<{
|
|
63
|
-
repoOrigin: z.ZodString;
|
|
64
|
-
repoPath: z.ZodString;
|
|
65
|
-
maxDecisions: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
66
|
-
maxTeamIntents: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
67
|
-
includeTeamIntents: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
68
|
-
}, "strip", z.ZodTypeAny, {
|
|
69
|
-
repoOrigin: string;
|
|
70
|
-
repoPath: string;
|
|
71
|
-
maxDecisions: number;
|
|
72
|
-
maxTeamIntents: number;
|
|
73
|
-
includeTeamIntents: boolean;
|
|
74
|
-
}, {
|
|
75
|
-
repoOrigin: string;
|
|
76
|
-
repoPath: string;
|
|
77
|
-
maxDecisions?: number | undefined;
|
|
78
|
-
maxTeamIntents?: number | undefined;
|
|
79
|
-
includeTeamIntents?: boolean | undefined;
|
|
80
|
-
}>;
|
|
81
|
-
handler: typeof getProjectContext;
|
|
82
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { request } from '../services/muninn-ipc.js';
|
|
3
|
-
import { resolveOrigin } from './resolve-origin.js';
|
|
4
|
-
export const getProjectContextSchema = z.object({
|
|
5
|
-
repoOrigin: z.string().describe('Git remote origin URL (e.g., git@github.com:user/repo.git)'),
|
|
6
|
-
repoPath: z.string().describe('Local path to the repository root'),
|
|
7
|
-
maxDecisions: z.number().optional().default(3).describe('Maximum number of recent decisions to return'),
|
|
8
|
-
maxTeamIntents: z.number().optional().default(5).describe('Maximum number of team intents to return'),
|
|
9
|
-
includeTeamIntents: z.boolean().optional().default(true).describe('Whether to include team intents')
|
|
10
|
-
});
|
|
11
|
-
export async function getProjectContext(input) {
|
|
12
|
-
const actualOrigin = resolveOrigin(input.repoOrigin, input.repoPath);
|
|
13
|
-
const res = await request('claude-code', 'project-context', {
|
|
14
|
-
repoOrigin: actualOrigin,
|
|
15
|
-
maxDecisions: input.maxDecisions,
|
|
16
|
-
maxTeamIntents: input.maxTeamIntents,
|
|
17
|
-
includeTeamIntents: input.includeTeamIntents,
|
|
18
|
-
});
|
|
19
|
-
// Transform Muninn response to MCP response format
|
|
20
|
-
const activeIntent = res.activeIntent
|
|
21
|
-
? {
|
|
22
|
-
id: res.activeIntent.id || '',
|
|
23
|
-
title: res.activeIntent.title || '',
|
|
24
|
-
description: res.activeIntent.description || '',
|
|
25
|
-
templateType: res.activeIntent.templateType || 'feature',
|
|
26
|
-
status: res.activeIntent.status || 'active',
|
|
27
|
-
branch: res.activeIntent.branch || ''
|
|
28
|
-
}
|
|
29
|
-
: null;
|
|
30
|
-
const teamIntents = (res.teamIntents || []).map((i) => ({
|
|
31
|
-
id: i.id || '',
|
|
32
|
-
title: i.title || '',
|
|
33
|
-
author: i.author || i.authorName || 'Unknown',
|
|
34
|
-
status: i.status || 'active',
|
|
35
|
-
templateType: i.templateType || 'feature',
|
|
36
|
-
}));
|
|
37
|
-
const recentDecisions = (res.recentDecisions || []).map((d) => ({
|
|
38
|
-
intentId: d.intentId || '',
|
|
39
|
-
type: d.decisionType || d.type || '',
|
|
40
|
-
summary: d.summary || '',
|
|
41
|
-
}));
|
|
42
|
-
const uniqueAuthors = new Set(teamIntents.map(i => i.author));
|
|
43
|
-
return {
|
|
44
|
-
projectOrigin: actualOrigin,
|
|
45
|
-
projectPath: input.repoPath,
|
|
46
|
-
activeIntent,
|
|
47
|
-
teamIntents,
|
|
48
|
-
teamIntentCount: teamIntents.length,
|
|
49
|
-
recentDecisions,
|
|
50
|
-
summary: {
|
|
51
|
-
hasActiveIntent: activeIntent !== null,
|
|
52
|
-
activeIntentTitle: activeIntent?.title || null,
|
|
53
|
-
teamMembersWorking: uniqueAuthors.size,
|
|
54
|
-
teamIntentsShown: teamIntents.length,
|
|
55
|
-
teamIntentsTotal: res.teamIntentsTotal || teamIntents.length,
|
|
56
|
-
recentDecisionCount: recentDecisions.length
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
export const getProjectContextTool = {
|
|
61
|
-
name: 'get_project_context',
|
|
62
|
-
description: `Get project status overview before starting work. CALL THIS AT THE START OF EVERY CODING SESSION.
|
|
63
|
-
|
|
64
|
-
Returns a lightweight status check:
|
|
65
|
-
- **Active intent**: What you're currently working on (id, title, status)
|
|
66
|
-
- **Team intents**: What teammates are working on (titles only, see summary for total count)
|
|
67
|
-
- **Recent decisions**: Summary-only (type + one-liner) — use get_relevant_context for full rationale
|
|
68
|
-
|
|
69
|
-
This is a **status check**, not a knowledge dump. For task-specific context (full decision rationale, file-level conflicts), call get_relevant_context after exploring the user's request.`,
|
|
70
|
-
inputSchema: getProjectContextSchema,
|
|
71
|
-
handler: getProjectContext
|
|
72
|
-
};
|
|
73
|
-
//# sourceMappingURL=get-project-context.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"get-project-context.js","sourceRoot":"","sources":["../../src/tools/get-project-context.ts"],"names":[],"mappings":"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"}
|