@oka-core/reason 0.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/dist/auth.d.ts +51 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +252 -0
- package/dist/buffer.d.ts +15 -0
- package/dist/buffer.d.ts.map +1 -0
- package/dist/buffer.js +29 -0
- package/dist/client.d.ts +183 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +292 -0
- package/dist/client_ext.d.ts +13 -0
- package/dist/client_ext.d.ts.map +1 -0
- package/dist/client_ext.js +12 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/schemas.d.ts +225 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +106 -0
- package/dist/tools/auth.d.ts +7 -0
- package/dist/tools/auth.d.ts.map +1 -0
- package/dist/tools/auth.js +131 -0
- package/dist/tools/read.d.ts +17 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +578 -0
- package/dist/tools/read_enhanced.d.ts +4 -0
- package/dist/tools/read_enhanced.d.ts.map +1 -0
- package/dist/tools/read_enhanced.js +304 -0
- package/dist/tools/write.d.ts +8 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +120 -0
- package/package.json +65 -0
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// ── Write Tool Inputs ──────────────────────────────────────────────
|
|
3
|
+
export const RecordDecisionInput = z.object({
|
|
4
|
+
description: z.string().min(1),
|
|
5
|
+
rationale: z.string().min(1),
|
|
6
|
+
alternatives_considered: z.array(z.string()).default([]),
|
|
7
|
+
confidence: z.number().min(0).max(1),
|
|
8
|
+
});
|
|
9
|
+
export const RecordExplorationInput = z.object({
|
|
10
|
+
area: z.string().min(1),
|
|
11
|
+
findings: z.string().min(1),
|
|
12
|
+
relevance_score: z.number().min(0).max(1),
|
|
13
|
+
});
|
|
14
|
+
export const RecordDeviationInput = z.object({
|
|
15
|
+
planned_action: z.string().min(1),
|
|
16
|
+
actual_action: z.string().min(1),
|
|
17
|
+
reason: z.string().min(1),
|
|
18
|
+
});
|
|
19
|
+
export const RecordCompletionInput = z.object({
|
|
20
|
+
task_id: z.string().min(1),
|
|
21
|
+
outcome: z.enum(["success", "partial", "failed"]),
|
|
22
|
+
artifacts: z.array(z.string()).default([]),
|
|
23
|
+
quality_signals: z.record(z.string(), z.number()).default({}),
|
|
24
|
+
});
|
|
25
|
+
export const RecordObservationInput = z.object({
|
|
26
|
+
category: z.enum([
|
|
27
|
+
"architecture",
|
|
28
|
+
"bug_pattern",
|
|
29
|
+
"convention",
|
|
30
|
+
"performance",
|
|
31
|
+
"security",
|
|
32
|
+
"workflow",
|
|
33
|
+
"dependency",
|
|
34
|
+
"code_quality",
|
|
35
|
+
"other",
|
|
36
|
+
]),
|
|
37
|
+
summary: z.string().min(1),
|
|
38
|
+
details: z.string().optional(),
|
|
39
|
+
confidence: z.number().min(0).max(1).default(0.7),
|
|
40
|
+
file_patterns: z.array(z.string()).default([]),
|
|
41
|
+
tags: z.array(z.string()).default([]),
|
|
42
|
+
});
|
|
43
|
+
// ── Read Tool Inputs ───────────────────────────────────────────────
|
|
44
|
+
export const GetContextInput = z.object({
|
|
45
|
+
topic: z.string().min(1),
|
|
46
|
+
repo: z.string().optional(),
|
|
47
|
+
file_patterns: z.string().optional(),
|
|
48
|
+
limit: z.number().optional().default(10),
|
|
49
|
+
min_confidence: z.number().optional().default(0.3),
|
|
50
|
+
});
|
|
51
|
+
export const ListLearningsInput = z.object({
|
|
52
|
+
repo: z.string().optional(),
|
|
53
|
+
category: z
|
|
54
|
+
.enum([
|
|
55
|
+
"architecture",
|
|
56
|
+
"bug_pattern",
|
|
57
|
+
"convention",
|
|
58
|
+
"decision",
|
|
59
|
+
"performance",
|
|
60
|
+
"security",
|
|
61
|
+
"workflow",
|
|
62
|
+
"domain_knowledge",
|
|
63
|
+
])
|
|
64
|
+
.optional(),
|
|
65
|
+
status: z
|
|
66
|
+
.enum(["active", "reinforced", "contradicted", "obsolete"])
|
|
67
|
+
.optional(),
|
|
68
|
+
min_confidence: z.number().optional(),
|
|
69
|
+
limit: z.number().optional().default(30),
|
|
70
|
+
});
|
|
71
|
+
export const GetDecisionsInput = z.object({
|
|
72
|
+
repo: z.string().min(1),
|
|
73
|
+
module: z.string().optional(),
|
|
74
|
+
timeframe: z.string().optional(),
|
|
75
|
+
});
|
|
76
|
+
export const GetPatternsInput = z.object({
|
|
77
|
+
repo: z.string().min(1),
|
|
78
|
+
});
|
|
79
|
+
export const SuggestPrioritiesInput = z.object({
|
|
80
|
+
repo: z.string().min(1),
|
|
81
|
+
backlog: z.array(z.string()).min(1),
|
|
82
|
+
});
|
|
83
|
+
// ── Response Types ─────────────────────────────────────────────────
|
|
84
|
+
export const ReasoningEvent = z.object({
|
|
85
|
+
id: z.string(),
|
|
86
|
+
repo: z.string(),
|
|
87
|
+
agent_id: z.string(),
|
|
88
|
+
event_type: z.string(),
|
|
89
|
+
payload: z.record(z.string(), z.unknown()),
|
|
90
|
+
session_id: z.string(),
|
|
91
|
+
timestamp: z.string(),
|
|
92
|
+
});
|
|
93
|
+
export const Learning = z.object({
|
|
94
|
+
id: z.string(),
|
|
95
|
+
repo: z.string(),
|
|
96
|
+
summary: z.string(),
|
|
97
|
+
file_patterns: z.array(z.string()),
|
|
98
|
+
tags: z.array(z.string()),
|
|
99
|
+
confidence: z.number(),
|
|
100
|
+
created_at: z.string(),
|
|
101
|
+
});
|
|
102
|
+
export const QueryResult = (itemSchema) => z.object({
|
|
103
|
+
results: z.array(itemSchema),
|
|
104
|
+
confidence: z.number(),
|
|
105
|
+
source_count: z.number(),
|
|
106
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { OkaClient } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register auth tools on the MCP server.
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerAuthTools(server: McpServer, client: OkaClient): void;
|
|
7
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQ9C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA8I5E"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { deviceAuthLogin, loadStoredCredentials, resolveApiKey, resolveApiKeyWithRefresh, } from "../auth.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register auth tools on the MCP server.
|
|
5
|
+
*/
|
|
6
|
+
export function registerAuthTools(server, client) {
|
|
7
|
+
server.tool("login", "Authenticate with Oka platform via browser login (device auth flow). " +
|
|
8
|
+
"Opens your browser to id.oka.so, waits for you to log in, " +
|
|
9
|
+
"then stores the token locally at ~/.oka/credentials.json. " +
|
|
10
|
+
"Use this when API calls return 401 unauthorized.", {
|
|
11
|
+
auth_server_url: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Auth server URL (default: https://id.oka.so)"),
|
|
15
|
+
client_id: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("OAuth client ID (default: oka-reason-mcp)"),
|
|
19
|
+
}, async (params) => {
|
|
20
|
+
// Check if we have a valid (non-expired) key
|
|
21
|
+
const existing = resolveApiKey();
|
|
22
|
+
if (existing) {
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: "text",
|
|
27
|
+
text: "Already authenticated. Credentials found via env or ~/.oka/credentials.json. To re-login, remove ~/.oka/credentials.json and try again.",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// Token might be expired — try refresh before opening browser
|
|
33
|
+
const stored = loadStoredCredentials();
|
|
34
|
+
if (stored?.refresh_token) {
|
|
35
|
+
const refreshed = await resolveApiKeyWithRefresh();
|
|
36
|
+
if (refreshed) {
|
|
37
|
+
client.updateApiKey(refreshed);
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: "Token was expired but has been refreshed automatically. Credentials updated.",
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const result = await deviceAuthLogin(params.auth_server_url, params.client_id);
|
|
50
|
+
if (result.success) {
|
|
51
|
+
// Reinitialize client with new credentials
|
|
52
|
+
client.updateApiKey(resolveApiKey());
|
|
53
|
+
return {
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: "text",
|
|
57
|
+
text: result.message,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Failed — give user the manual URL
|
|
63
|
+
const lines = [result.message];
|
|
64
|
+
if (result.verification_uri) {
|
|
65
|
+
lines.push(`\nManual URL: ${result.verification_uri}`);
|
|
66
|
+
}
|
|
67
|
+
if (result.user_code) {
|
|
68
|
+
lines.push(`Enter code: ${result.user_code}`);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
return {
|
|
76
|
+
content: [
|
|
77
|
+
{
|
|
78
|
+
type: "text",
|
|
79
|
+
text: `Login error: ${err instanceof Error ? err.message : String(err)}`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
server.tool("whoami", "Check current authentication status — whether the MCP server has valid credentials.", {}, async () => {
|
|
86
|
+
// First try sync resolution
|
|
87
|
+
let key = resolveApiKey();
|
|
88
|
+
// If no key found, try async refresh
|
|
89
|
+
if (!key) {
|
|
90
|
+
key = await resolveApiKeyWithRefresh();
|
|
91
|
+
if (key) {
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
{
|
|
95
|
+
type: "text",
|
|
96
|
+
text: `Authenticated (token was refreshed automatically). Key: ${maskKey(key)}`,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (key) {
|
|
103
|
+
const stored = loadStoredCredentials();
|
|
104
|
+
const expiryInfo = stored?.expires_at
|
|
105
|
+
? ` | Expires: ${new Date(stored.expires_at * 1000).toISOString()}`
|
|
106
|
+
: "";
|
|
107
|
+
const hasRefresh = stored?.refresh_token
|
|
108
|
+
? " | Auto-refresh: enabled"
|
|
109
|
+
: "";
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: `Authenticated. Key: ${maskKey(key)}${expiryInfo}${hasRefresh}`,
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
content: [
|
|
121
|
+
{
|
|
122
|
+
type: "text",
|
|
123
|
+
text: "Not authenticated. Use login to authenticate, or set OKA_API_KEY in your environment.",
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function maskKey(key) {
|
|
130
|
+
return key.length > 12 ? `${key.slice(0, 8)}...${key.slice(-4)}` : "***";
|
|
131
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { OkaClient } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register read tools on the MCP server.
|
|
5
|
+
*
|
|
6
|
+
* Tools:
|
|
7
|
+
* - context — ranked learnings for a topic (flagship query)
|
|
8
|
+
* - learnings — browse institutional knowledge
|
|
9
|
+
* - decisions — decision log
|
|
10
|
+
* - patterns — recurring patterns
|
|
11
|
+
* - suggest — evidence-ranked priorities
|
|
12
|
+
* - backlog — agentic product backlog
|
|
13
|
+
* - priorities — evidence-ranked priorities from approved backlog
|
|
14
|
+
* - consolidate — manually trigger a consolidation run
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerReadTools(server: McpServer, client: OkaClient): void;
|
|
17
|
+
//# sourceMappingURL=read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EACV,SAAS,EAGV,MAAM,cAAc,CAAC;AAoEtB;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA2nB5E"}
|