@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.
@@ -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"}