@rigstate/mcp 0.4.2 → 0.4.3
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/.agent/skills/client-side-notification-logger/SKILL.md +139 -0
- package/.agent/skills/react-state-counter/SKILL.md +73 -0
- package/.agent/skills/rigstate-evolutionary-refactor/SKILL.md +40 -0
- package/.agent/skills/rigstate-integrity-gate/SKILL.md +55 -0
- package/.agent/skills/rigstate-legacy-renovator/SKILL.md +12 -0
- package/.agent/skills/sec-auth-04/SKILL.md +22 -0
- package/.agent/skills/sec-key-01/SKILL.md +21 -0
- package/.agent/skills/sec-rls-01/SKILL.md +22 -0
- package/.agent/skills/sec-sql-01/SKILL.md +23 -0
- package/.agent/skills/sec-ui-01/SKILL.md +21 -0
- package/.cursor/rules/rigstate-database.mdc +89 -0
- package/.cursor/rules/rigstate-guardian.mdc +43 -0
- package/.cursor/rules/rigstate-identity.mdc +45 -0
- package/.cursor/rules/rigstate-roadmap.mdc +9 -0
- package/.cursor/rules/rigstate-workflow.mdc +323 -0
- package/.cursorrules +402 -0
- package/AGENTS.md +34 -0
- package/dist/index.js +2604 -3067
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/roadmap.json +815 -21
- package/src/index.ts +16 -1765
- package/src/lib/context-engine.ts +85 -0
- package/src/lib/curator/actions/fortress.ts +77 -0
- package/src/lib/curator/actions/query.ts +73 -0
- package/src/lib/curator/actions/stats.ts +70 -0
- package/src/lib/curator/actions/submit.ts +190 -0
- package/src/lib/curator/index.ts +10 -0
- package/src/lib/curator/schemas.ts +37 -0
- package/src/lib/schemas.ts +191 -0
- package/src/lib/types.ts +102 -261
- package/src/server/core.ts +40 -0
- package/src/server/factory.ts +78 -0
- package/src/server/telemetry.ts +122 -0
- package/src/server/types.ts +21 -0
- package/src/tools/analyze-database-performance.ts +157 -0
- package/src/tools/arch-tools.ts +16 -0
- package/src/tools/audit-integrity-gate.ts +166 -0
- package/src/tools/check-rules-sync.ts +20 -0
- package/src/tools/complete-roadmap-task.ts +88 -31
- package/src/tools/curator-tools.ts +74 -0
- package/src/tools/get-latest-decisions.ts +22 -0
- package/src/tools/get-next-roadmap-step.ts +21 -0
- package/src/tools/get-project-context.ts +35 -1
- package/src/tools/index.ts +7 -0
- package/src/tools/list-features.ts +4 -1
- package/src/tools/list-roadmap-tasks.ts +21 -0
- package/src/tools/planning-tools.ts +40 -0
- package/src/tools/query-brain.ts +25 -1
- package/src/tools/run-architecture-audit.ts +23 -0
- package/src/tools/save-decision.ts +26 -0
- package/src/tools/security-checks.ts +241 -0
- package/src/tools/security-tools.ts +88 -18
- package/src/tools/submit-idea.ts +25 -0
- package/src/tools/sync-ide-rules.ts +35 -3
- package/src/tools/teacher-mode.ts +92 -13
- package/src/tools/update-roadmap.ts +24 -0
|
@@ -1,4 +1,29 @@
|
|
|
1
|
+
|
|
1
2
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
3
|
+
import { IntegrityGateResponse, ReleaseManifest } from '../lib/types.js';
|
|
4
|
+
import { registry } from '../lib/tool-registry.js';
|
|
5
|
+
import { CompleteRoadmapTaskInputSchema } from '../lib/schemas.js';
|
|
6
|
+
|
|
7
|
+
// ============================================
|
|
8
|
+
// Tool Registration
|
|
9
|
+
// ============================================
|
|
10
|
+
|
|
11
|
+
registry.register({
|
|
12
|
+
name: 'complete_roadmap_task',
|
|
13
|
+
description: `Finalizes a roadmap task. Generates a Release Manifest and triggers the Sovereign Harvesting protocol.`,
|
|
14
|
+
schema: CompleteRoadmapTaskInputSchema,
|
|
15
|
+
handler: async (args, context) => {
|
|
16
|
+
const result = await completeRoadmapTask(
|
|
17
|
+
context.supabase,
|
|
18
|
+
args.projectId,
|
|
19
|
+
args.summary,
|
|
20
|
+
args.taskId,
|
|
21
|
+
args.gitDiff,
|
|
22
|
+
args.integrityGate
|
|
23
|
+
);
|
|
24
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
25
|
+
}
|
|
26
|
+
});
|
|
2
27
|
|
|
3
28
|
export interface CompleteRoadmapTaskResponse {
|
|
4
29
|
success: boolean;
|
|
@@ -11,7 +36,8 @@ export async function completeRoadmapTask(
|
|
|
11
36
|
projectId: string,
|
|
12
37
|
summary: string,
|
|
13
38
|
taskId?: string,
|
|
14
|
-
gitDiff?: string
|
|
39
|
+
gitDiff?: string,
|
|
40
|
+
integrityGate?: IntegrityGateResponse
|
|
15
41
|
): Promise<CompleteRoadmapTaskResponse> {
|
|
16
42
|
|
|
17
43
|
// 1. Identify the task
|
|
@@ -35,16 +61,36 @@ export async function completeRoadmapTask(
|
|
|
35
61
|
}
|
|
36
62
|
}
|
|
37
63
|
|
|
38
|
-
// 2.
|
|
64
|
+
// 2. Generate Release Manifest if Integrity Gate info is present
|
|
65
|
+
let metadata: any = {};
|
|
66
|
+
if (integrityGate) {
|
|
67
|
+
const securityCheck = integrityGate.checks.find(c => (c as any).check === 'SECURITY');
|
|
68
|
+
const performanceCheck = integrityGate.checks.find(c => (c as any).check === 'PERFORMANCE');
|
|
69
|
+
|
|
70
|
+
const manifest: ReleaseManifest = {
|
|
71
|
+
executive_summary: summary,
|
|
72
|
+
security_certificate: {
|
|
73
|
+
status: securityCheck?.status === 'PASS' ? 'PASSED' : (securityCheck?.status === 'FAIL' ? 'FAILED' : 'WARNING'),
|
|
74
|
+
message: securityCheck?.message || 'No security audit performed.',
|
|
75
|
+
unsecured_tables: securityCheck?.details || []
|
|
76
|
+
},
|
|
77
|
+
performance_report: {
|
|
78
|
+
status: performanceCheck?.status === 'PASS' ? 'PASSED' : (performanceCheck?.status === 'FAIL' ? 'FAILED' : 'WARNING'),
|
|
79
|
+
message: performanceCheck?.message || 'No performance audit performed.',
|
|
80
|
+
issues_found: performanceCheck?.details ? (Array.isArray(performanceCheck.details) ? performanceCheck.details.length : 0) : 0
|
|
81
|
+
},
|
|
82
|
+
timestamp: new Date().toISOString()
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
metadata.release_manifest = manifest;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 3. Update the Task Status
|
|
39
89
|
const { error: updateError } = await supabase
|
|
40
90
|
.from('roadmap_chunks')
|
|
41
91
|
.update({
|
|
42
92
|
status: 'COMPLETED',
|
|
43
|
-
completed_at: new Date().toISOString()
|
|
44
|
-
// We could store the summary directly on the chunk if there's a column,
|
|
45
|
-
// but mission_reports is the proper place for detailed logs.
|
|
46
|
-
// Let's check if we can update metadata or similar.
|
|
47
|
-
// For now, let's assume mission_reports is the way.
|
|
93
|
+
completed_at: new Date().toISOString()
|
|
48
94
|
})
|
|
49
95
|
.eq('id', targetTaskId);
|
|
50
96
|
|
|
@@ -52,26 +98,7 @@ export async function completeRoadmapTask(
|
|
|
52
98
|
throw new Error(`Failed to update task status: ${updateError.message}`);
|
|
53
99
|
}
|
|
54
100
|
|
|
55
|
-
//
|
|
56
|
-
// Check if 'mission_reports' table exists and has the schema we expect.
|
|
57
|
-
// Based on previous code in index.ts (Frank Watcher):
|
|
58
|
-
/*
|
|
59
|
-
await supabase.from('mission_reports').insert({
|
|
60
|
-
bridge_id: task.id, // We might not have a bridge_id if this is direct from IDE
|
|
61
|
-
project_id: task.project_id,
|
|
62
|
-
task_id: task.task_id,
|
|
63
|
-
human_summary: humanSummary,
|
|
64
|
-
technical_summary: technicalSummary,
|
|
65
|
-
...
|
|
66
|
-
});
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
// We'll insert a report. Since we don't have a bridge_id (this didn't come from the agent bridge queue),
|
|
70
|
-
// we'll leave it null if allowed, or we might need to create a dummy bridge entry?
|
|
71
|
-
// Let's assume bridge_id is nullable or we just skip it.
|
|
72
|
-
// If bridge_id is required, we might need to fake one or just log to a 'notes' field on roadmap_chunk if available.
|
|
73
|
-
// Let's try to insert into mission_reports first.
|
|
74
|
-
|
|
101
|
+
// 4. Create a Mission Report entry with the Manifest
|
|
75
102
|
const { error: reportError } = await supabase
|
|
76
103
|
.from('mission_reports')
|
|
77
104
|
.insert({
|
|
@@ -79,18 +106,48 @@ export async function completeRoadmapTask(
|
|
|
79
106
|
task_id: targetTaskId,
|
|
80
107
|
human_summary: summary,
|
|
81
108
|
technical_summary: gitDiff || 'Completed via IDE Direct Connection.',
|
|
82
|
-
|
|
109
|
+
metadata: metadata
|
|
83
110
|
});
|
|
84
111
|
|
|
85
112
|
if (reportError) {
|
|
86
113
|
console.warn('Failed to save mission report:', reportError.message);
|
|
87
|
-
|
|
88
|
-
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 5. SOVEREIGN HARVESTING: Trigger Reflection & Skill Extraction (Brynjar)
|
|
117
|
+
// Fire and forget - don't block completion on harvesting
|
|
118
|
+
try {
|
|
119
|
+
const apiKey = process.env.RIGSTATE_API_KEY;
|
|
120
|
+
// Default to localhost for development if not set
|
|
121
|
+
const apiUrl = process.env.RIGSTATE_API_URL || 'http://localhost:3000';
|
|
122
|
+
|
|
123
|
+
// In local dev, we might not have an API key set, so we allow it if it's localhost
|
|
124
|
+
const isLocal = apiUrl.includes('localhost') || apiUrl.includes('127.0.0.1');
|
|
125
|
+
|
|
126
|
+
if (apiKey || isLocal) {
|
|
127
|
+
fetch(`${apiUrl}/api/v1/skills/harvest`, {
|
|
128
|
+
method: 'POST',
|
|
129
|
+
headers: {
|
|
130
|
+
'Content-Type': 'application/json',
|
|
131
|
+
...(apiKey ? { 'Authorization': `Bearer ${apiKey}` } : {})
|
|
132
|
+
},
|
|
133
|
+
body: JSON.stringify({
|
|
134
|
+
projectId,
|
|
135
|
+
taskId: targetTaskId,
|
|
136
|
+
summary,
|
|
137
|
+
technicalSummary: gitDiff || 'Completed via IDE Direct Connection.',
|
|
138
|
+
metadata: metadata
|
|
139
|
+
})
|
|
140
|
+
}).catch(e => console.error('Harvesting failed (silent):', e));
|
|
141
|
+
}
|
|
142
|
+
} catch (e) {
|
|
143
|
+
// Harvesting is non-critical, fail silently
|
|
89
144
|
}
|
|
90
145
|
|
|
91
146
|
return {
|
|
92
147
|
success: true,
|
|
93
148
|
taskId: targetTaskId!,
|
|
94
|
-
message:
|
|
149
|
+
message: integrityGate
|
|
150
|
+
? `Task completed! 🎖️ Release Manifest generated and attached.`
|
|
151
|
+
: `Task completed successfully! Summary saved.`
|
|
95
152
|
};
|
|
96
153
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 8.5: The Curator Protocol
|
|
3
|
+
* MCP Tools for Curator Operations
|
|
4
|
+
*
|
|
5
|
+
* Sigrid's Tools for Global Knowledge Curation.
|
|
6
|
+
* These tools enable AI agents to contribute to and query the global antidote registry.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { registry } from '../lib/tool-registry.js';
|
|
10
|
+
import {
|
|
11
|
+
queryGlobalAntidotes,
|
|
12
|
+
submitSignal,
|
|
13
|
+
getCuratorStats,
|
|
14
|
+
checkFortress,
|
|
15
|
+
QueryGlobalAntidotesSchema,
|
|
16
|
+
SubmitSignalSchema,
|
|
17
|
+
GetCuratorStatsSchema,
|
|
18
|
+
CheckFortressSchema
|
|
19
|
+
} from '../lib/curator/index.js';
|
|
20
|
+
|
|
21
|
+
// ============================================
|
|
22
|
+
// Tool Registration
|
|
23
|
+
// ============================================
|
|
24
|
+
|
|
25
|
+
registry.register({
|
|
26
|
+
name: 'query_global_antidotes',
|
|
27
|
+
description: `Sigrid's Tool: Query the Global Antidotes Registry.
|
|
28
|
+
Search for cross-platform intelligence signals (antidotes) that encode best practices.
|
|
29
|
+
Use this to find relevant security, architecture, UX, and performance guidelines.`,
|
|
30
|
+
schema: QueryGlobalAntidotesSchema,
|
|
31
|
+
handler: async (args, context) => {
|
|
32
|
+
const result = await queryGlobalAntidotes(context.supabase, context.userId, args);
|
|
33
|
+
return { content: [{ type: 'text', text: result.formatted }] };
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
registry.register({
|
|
38
|
+
name: 'submit_curator_signal',
|
|
39
|
+
description: `Sigrid's Tool: Submit a new signal to the Curator Protocol.
|
|
40
|
+
When you discover a best practice or anti-pattern during development, submit it as a signal.
|
|
41
|
+
Signals are processed through a trust-scoring pipeline and may be promoted to global antidotes.
|
|
42
|
+
Note: All submissions go through quarantine for human review.`,
|
|
43
|
+
schema: SubmitSignalSchema,
|
|
44
|
+
handler: async (args, context) => {
|
|
45
|
+
const result = await submitSignal(context.supabase, context.userId, args);
|
|
46
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
registry.register({
|
|
51
|
+
name: 'get_curator_stats',
|
|
52
|
+
description: `Get statistics about the Curator Registry.
|
|
53
|
+
Shows total antidotes, fortress rules, pending quarantine, and today's curation activity.`,
|
|
54
|
+
schema: GetCuratorStatsSchema,
|
|
55
|
+
handler: async (args, context) => {
|
|
56
|
+
const result = await getCuratorStats(context.supabase, context.userId, args);
|
|
57
|
+
return { content: [{ type: 'text', text: result.formatted }] };
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
registry.register({
|
|
62
|
+
name: 'check_fortress_rules',
|
|
63
|
+
description: `Sigrid's Tool: Check an instruction against Fortress Rules.
|
|
64
|
+
Before submitting a signal, use this to verify it doesn't conflict with immutable security rules.
|
|
65
|
+
Fortress rules can NEVER be overridden by any signal.`,
|
|
66
|
+
schema: CheckFortressSchema,
|
|
67
|
+
handler: async (args, context) => {
|
|
68
|
+
const result = await checkFortress(context.supabase, context.userId, args);
|
|
69
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Export functions for historical compatibility if any tests use them directly
|
|
74
|
+
export { queryGlobalAntidotes, submitSignal, getCuratorStats, checkFortress };
|
|
@@ -7,6 +7,28 @@
|
|
|
7
7
|
|
|
8
8
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
9
9
|
import type { DecisionsResponse, CouncilSession, RoadmapStep } from '../lib/types.js';
|
|
10
|
+
import { registry } from '../lib/tool-registry.js';
|
|
11
|
+
import { GetLatestDecisionsInputSchema } from '../lib/schemas.js';
|
|
12
|
+
|
|
13
|
+
// ============================================
|
|
14
|
+
// Tool Registration
|
|
15
|
+
// ============================================
|
|
16
|
+
|
|
17
|
+
registry.register({
|
|
18
|
+
name: 'get_latest_decisions',
|
|
19
|
+
description: `Fetches the most recent ADRs and decisions from The Council,
|
|
20
|
+
including active roadmap steps and council session feedback.`,
|
|
21
|
+
schema: GetLatestDecisionsInputSchema,
|
|
22
|
+
handler: async (args, context) => {
|
|
23
|
+
const result = await getLatestDecisions(
|
|
24
|
+
context.supabase,
|
|
25
|
+
context.userId,
|
|
26
|
+
args.projectId,
|
|
27
|
+
args.limit
|
|
28
|
+
);
|
|
29
|
+
return { content: [{ type: 'text', text: result.summary }] };
|
|
30
|
+
}
|
|
31
|
+
});
|
|
10
32
|
|
|
11
33
|
export async function getLatestDecisions(
|
|
12
34
|
supabase: SupabaseClient,
|
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
|
|
2
2
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
3
3
|
import type { RoadmapChunk } from '../lib/types.js';
|
|
4
|
+
import { registry } from '../lib/tool-registry.js';
|
|
5
|
+
import { GetNextRoadmapStepInputSchema } from '../lib/schemas.js';
|
|
6
|
+
|
|
7
|
+
// ============================================
|
|
8
|
+
// Tool Registration
|
|
9
|
+
// ============================================
|
|
10
|
+
|
|
11
|
+
registry.register({
|
|
12
|
+
name: 'get_next_roadmap_step',
|
|
13
|
+
description: `Fetches the next logical step from the roadmap for a project.
|
|
14
|
+
Useful for transitioning between tasks.`,
|
|
15
|
+
schema: GetNextRoadmapStepInputSchema,
|
|
16
|
+
handler: async (args, context) => {
|
|
17
|
+
const result = await getNextRoadmapStep(
|
|
18
|
+
context.supabase,
|
|
19
|
+
args.projectId,
|
|
20
|
+
args.currentStepId
|
|
21
|
+
);
|
|
22
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
23
|
+
}
|
|
24
|
+
});
|
|
4
25
|
|
|
5
26
|
export interface GetNextRoadmapStepResponse {
|
|
6
27
|
nextStep: RoadmapChunk | null;
|
|
@@ -7,6 +7,23 @@
|
|
|
7
7
|
|
|
8
8
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
9
9
|
import type { ProjectContextResponse, TechStackInfo } from '../lib/types.js';
|
|
10
|
+
import { injectGlobalContext } from '../lib/context-engine.js';
|
|
11
|
+
import { registry } from '../lib/tool-registry.js';
|
|
12
|
+
import { GetProjectContextInputSchema } from '../lib/schemas.js';
|
|
13
|
+
|
|
14
|
+
// ============================================
|
|
15
|
+
// Tool Registration
|
|
16
|
+
// ============================================
|
|
17
|
+
|
|
18
|
+
registry.register({
|
|
19
|
+
name: 'get_project_context',
|
|
20
|
+
description: `Returns the project type, tech stack, and high-level description for a Rigstate project.`,
|
|
21
|
+
schema: GetProjectContextInputSchema,
|
|
22
|
+
handler: async (args, context) => {
|
|
23
|
+
const result = await getProjectContext(context.supabase, context.userId, args.projectId);
|
|
24
|
+
return { content: [{ type: 'text', text: result.summary }] };
|
|
25
|
+
}
|
|
26
|
+
});
|
|
10
27
|
|
|
11
28
|
// Key libraries we care about for display
|
|
12
29
|
const KEY_LIBS: Record<string, string> = {
|
|
@@ -148,7 +165,7 @@ export async function getProjectContext(
|
|
|
148
165
|
});
|
|
149
166
|
}
|
|
150
167
|
|
|
151
|
-
|
|
168
|
+
const response: ProjectContextResponse = {
|
|
152
169
|
project: {
|
|
153
170
|
id: project.id,
|
|
154
171
|
name: project.name,
|
|
@@ -160,4 +177,21 @@ export async function getProjectContext(
|
|
|
160
177
|
techStack,
|
|
161
178
|
summary: summaryParts.join('\n') || 'No project context available.'
|
|
162
179
|
};
|
|
180
|
+
|
|
181
|
+
// Phase 8.5.5: Inject Global Context (Curator)
|
|
182
|
+
try {
|
|
183
|
+
const curatorContext = await injectGlobalContext(supabase, userId, {
|
|
184
|
+
frameworks: techStack.framework ? [techStack.framework] : [],
|
|
185
|
+
libraries: techStack.keyLibraries
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (curatorContext) {
|
|
189
|
+
response.summary += `\n\n=== CURATOR INTELLIGENCE ===${curatorContext}`;
|
|
190
|
+
}
|
|
191
|
+
} catch (e: any) {
|
|
192
|
+
console.error('Failed to inject global context:', e);
|
|
193
|
+
response.summary += `\n\n(Curator Context Unavailable: ${e.message})`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return response;
|
|
163
197
|
}
|
package/src/tools/index.ts
CHANGED
|
@@ -15,3 +15,10 @@ export { submitIdea } from './submit-idea.js';
|
|
|
15
15
|
export { updateRoadmap } from './update-roadmap.js';
|
|
16
16
|
export { runArchitectureAudit } from './run-architecture-audit.js';
|
|
17
17
|
|
|
18
|
+
// Curator Protocol (Phase 8.5 - Sigrid's Tools)
|
|
19
|
+
export {
|
|
20
|
+
queryGlobalAntidotes,
|
|
21
|
+
submitSignal,
|
|
22
|
+
getCuratorStats,
|
|
23
|
+
checkFortress
|
|
24
|
+
} from './curator-tools.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { ToolDefinition } from '../lib/tool-registry.js';
|
|
2
|
+
import { ToolDefinition, registry } from '../lib/tool-registry.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Input Schema for List Features
|
|
@@ -65,3 +65,6 @@ Useful for understanding the strategic context and major milestones.`,
|
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
+
registry.register(listFeaturesTool);
|
|
69
|
+
|
|
70
|
+
|
|
@@ -6,6 +6,27 @@
|
|
|
6
6
|
|
|
7
7
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
8
8
|
import type { ListRoadmapTasksResponse } from '../lib/types.js';
|
|
9
|
+
import { registry } from '../lib/tool-registry.js';
|
|
10
|
+
import { ListRoadmapTasksInputSchema } from '../lib/schemas.js';
|
|
11
|
+
|
|
12
|
+
// ============================================
|
|
13
|
+
// Tool Registration
|
|
14
|
+
// ============================================
|
|
15
|
+
|
|
16
|
+
registry.register({
|
|
17
|
+
name: 'list_roadmap_tasks',
|
|
18
|
+
description: `Lists all actionable tasks for a project that are not yet COMPLETED.
|
|
19
|
+
Shows active and locked steps with their step numbers.`,
|
|
20
|
+
schema: ListRoadmapTasksInputSchema,
|
|
21
|
+
handler: async (args, context) => {
|
|
22
|
+
const result = await listRoadmapTasks(
|
|
23
|
+
context.supabase,
|
|
24
|
+
context.userId,
|
|
25
|
+
args.projectId
|
|
26
|
+
);
|
|
27
|
+
return { content: [{ type: 'text', text: result.formatted }] };
|
|
28
|
+
}
|
|
29
|
+
});
|
|
9
30
|
|
|
10
31
|
export async function listRoadmapTasks(
|
|
11
32
|
supabase: SupabaseClient,
|
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
2
|
import { SaveToProjectBrainInput, UpdateRoadmapStatusInput, AddRoadmapChunkInput } from '../lib/types.js';
|
|
3
|
+
import { registry } from '../lib/tool-registry.js';
|
|
4
|
+
import {
|
|
5
|
+
SaveToProjectBrainInputSchema,
|
|
6
|
+
UpdateRoadmapStatusInputSchema,
|
|
7
|
+
AddRoadmapChunkInputSchema
|
|
8
|
+
} from '../lib/schemas.js';
|
|
9
|
+
|
|
10
|
+
// ============================================
|
|
11
|
+
// Tool Registration
|
|
12
|
+
// ============================================
|
|
13
|
+
|
|
14
|
+
registry.register({
|
|
15
|
+
name: 'save_to_project_brain',
|
|
16
|
+
description: `Maja's Tool: Persists knowledge, decisions, and lessons learned to the Project Brain.`,
|
|
17
|
+
schema: SaveToProjectBrainInputSchema,
|
|
18
|
+
handler: async (args, context) => {
|
|
19
|
+
const result = await saveToProjectBrain(context.supabase, context.userId, args);
|
|
20
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
registry.register({
|
|
25
|
+
name: 'update_roadmap_status',
|
|
26
|
+
description: `Kine's Tool: Updates the status of a roadmap task and notifies Scribe system.`,
|
|
27
|
+
schema: UpdateRoadmapStatusInputSchema,
|
|
28
|
+
handler: async (args, context) => {
|
|
29
|
+
const result = await updateRoadmapStatus(context.supabase, context.userId, args);
|
|
30
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
registry.register({
|
|
35
|
+
name: 'add_roadmap_chunk',
|
|
36
|
+
description: `Kine's Tool: Adds a new task/chunk to the roadmap for feature decomposition.`,
|
|
37
|
+
schema: AddRoadmapChunkInputSchema,
|
|
38
|
+
handler: async (args, context) => {
|
|
39
|
+
const result = await addRoadmapChunk(context.supabase, context.userId, args);
|
|
40
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
41
|
+
}
|
|
42
|
+
});
|
|
3
43
|
|
|
4
44
|
/**
|
|
5
45
|
* Maja's Tool: Save to Project Brain
|
package/src/tools/query-brain.ts
CHANGED
|
@@ -8,9 +8,33 @@
|
|
|
8
8
|
|
|
9
9
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
10
10
|
import type { BrainQueryResponse, MemoryRecord } from '../lib/types.js';
|
|
11
|
+
import { registry } from '../lib/tool-registry.js';
|
|
12
|
+
import { QueryBrainInputSchema } from '../lib/schemas.js';
|
|
13
|
+
|
|
14
|
+
// ============================================
|
|
15
|
+
// Tool Registration
|
|
16
|
+
// ============================================
|
|
17
|
+
|
|
18
|
+
registry.register({
|
|
19
|
+
name: 'query_brain',
|
|
20
|
+
description: `Takes a natural language query and performs semantic search
|
|
21
|
+
against the project's memories (RAG), returning relevant
|
|
22
|
+
architecture rules, decisions, and constraints.`,
|
|
23
|
+
schema: QueryBrainInputSchema,
|
|
24
|
+
handler: async (args, context) => {
|
|
25
|
+
const result = await queryBrain(
|
|
26
|
+
context.supabase,
|
|
27
|
+
context.userId,
|
|
28
|
+
args.projectId,
|
|
29
|
+
args.query,
|
|
30
|
+
args.limit,
|
|
31
|
+
args.threshold
|
|
32
|
+
);
|
|
33
|
+
return { content: [{ type: 'text', text: result.formatted }] };
|
|
34
|
+
}
|
|
35
|
+
});
|
|
11
36
|
|
|
12
37
|
// Simple embedding generation using text normalization
|
|
13
|
-
// In production, this would call an embedding API like OpenAI
|
|
14
38
|
async function generateQueryEmbedding(query: string): Promise<number[]> {
|
|
15
39
|
// For MCP server, we'll use the match_memories_text RPC if available,
|
|
16
40
|
// or fall back to keyword-based search.
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
9
9
|
import type { ArchitectureAuditResponse, AuditViolation } from '../lib/types.js';
|
|
10
|
+
import { registry } from '../lib/tool-registry.js';
|
|
11
|
+
import { RunArchitectureAuditInputSchema } from '../lib/schemas.js';
|
|
10
12
|
|
|
11
13
|
// Vulnerability patterns for static analysis
|
|
12
14
|
const VULNERABILITY_PATTERNS: {
|
|
@@ -80,6 +82,27 @@ function extractLineNumber(content: string, match: RegExpMatchArray): number {
|
|
|
80
82
|
return (upToMatch.match(/\n/g) || []).length + 1;
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
// ============================================
|
|
86
|
+
// Tool Registration
|
|
87
|
+
// ============================================
|
|
88
|
+
|
|
89
|
+
registry.register({
|
|
90
|
+
name: 'run_architecture_audit',
|
|
91
|
+
description: `Audits code against project memories and architecture rules.
|
|
92
|
+
Returns violations or "Pass" status.`,
|
|
93
|
+
schema: RunArchitectureAuditInputSchema,
|
|
94
|
+
handler: async (args, context) => {
|
|
95
|
+
const result = await runArchitectureAudit(
|
|
96
|
+
context.supabase,
|
|
97
|
+
context.userId,
|
|
98
|
+
args.projectId,
|
|
99
|
+
args.filePath,
|
|
100
|
+
args.content
|
|
101
|
+
);
|
|
102
|
+
return { content: [{ type: 'text', text: result.summary }] };
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
83
106
|
export async function runArchitectureAudit(
|
|
84
107
|
supabase: SupabaseClient,
|
|
85
108
|
userId: string,
|
|
@@ -7,6 +7,32 @@
|
|
|
7
7
|
|
|
8
8
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
9
9
|
import type { SaveDecisionResponse } from '../lib/types.js';
|
|
10
|
+
import { registry } from '../lib/tool-registry.js';
|
|
11
|
+
import { SaveDecisionInputSchema } from '../lib/schemas.js';
|
|
12
|
+
|
|
13
|
+
// ============================================
|
|
14
|
+
// Tool Registration
|
|
15
|
+
// ============================================
|
|
16
|
+
|
|
17
|
+
registry.register({
|
|
18
|
+
name: 'save_decision',
|
|
19
|
+
description: `Saves a new decision/ADR to the project's brain (project_memories).
|
|
20
|
+
High-importance memory for architectural decisions.`,
|
|
21
|
+
schema: SaveDecisionInputSchema,
|
|
22
|
+
handler: async (args, context) => {
|
|
23
|
+
const result = await saveDecision(
|
|
24
|
+
context.supabase,
|
|
25
|
+
context.userId,
|
|
26
|
+
args.projectId,
|
|
27
|
+
args.title,
|
|
28
|
+
args.decision,
|
|
29
|
+
args.rationale,
|
|
30
|
+
args.category,
|
|
31
|
+
args.tags
|
|
32
|
+
);
|
|
33
|
+
return { content: [{ type: 'text', text: result.message }] };
|
|
34
|
+
}
|
|
35
|
+
});
|
|
10
36
|
|
|
11
37
|
export async function saveDecision(
|
|
12
38
|
supabase: SupabaseClient,
|