@bis-code/study-dash 0.2.2 → 0.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/.claude-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/server/dist/bundle.mjs +23689 -2079
- package/server/dist/dashboard/api.d.ts +3 -1
- package/server/dist/dashboard/api.js +14 -2
- package/server/dist/dashboard/api.js.map +1 -1
- package/server/dist/dashboard/server.d.ts +3 -1
- package/server/dist/dashboard/server.js +10 -3
- package/server/dist/dashboard/server.js.map +1 -1
- package/server/dist/index.js +5 -1
- package/server/dist/index.js.map +1 -1
- package/server/dist/services/resources.d.ts +16 -0
- package/server/dist/services/resources.js +27 -0
- package/server/dist/services/resources.js.map +1 -0
- package/server/dist/storage/schema.d.ts +1 -1
- package/server/dist/storage/schema.js +11 -0
- package/server/dist/storage/schema.js.map +1 -1
- package/server/dist/tools/resources.d.ts +4 -0
- package/server/dist/tools/resources.js +50 -0
- package/server/dist/tools/resources.js.map +1 -0
- package/server/dist/types.d.ts +8 -0
- package/server/package.json +9 -2
|
@@ -3,12 +3,14 @@ import type { CurriculumService } from '../services/curriculum.js';
|
|
|
3
3
|
import type { QAService } from '../services/qa.js';
|
|
4
4
|
import type { VizService } from '../services/viz.js';
|
|
5
5
|
import type { ExerciseService } from '../services/exercises.js';
|
|
6
|
+
import type { ResourceService } from '../services/resources.js';
|
|
6
7
|
export declare function writeJSON(res: ServerResponse, data: unknown, status?: number): void;
|
|
7
8
|
export declare function parseBody(req: IncomingMessage): Promise<unknown>;
|
|
8
9
|
export declare function extractId(url: string, prefix: string): number | null;
|
|
9
10
|
export declare function handleSubjects(curriculumSvc: CurriculumService): (_req: IncomingMessage, res: ServerResponse) => void;
|
|
10
11
|
export declare function handlePhases(curriculumSvc: CurriculumService): (req: IncomingMessage, res: ServerResponse) => void;
|
|
11
|
-
export declare function handleTopic(curriculumSvc: CurriculumService, qaSvc: QAService): (req: IncomingMessage, res: ServerResponse) => void;
|
|
12
|
+
export declare function handleTopic(curriculumSvc: CurriculumService, qaSvc: QAService, resourceSvc: ResourceService): (req: IncomingMessage, res: ServerResponse) => void;
|
|
13
|
+
export declare function handleTopicResources(resourceSvc: ResourceService): (req: IncomingMessage, res: ServerResponse) => void;
|
|
12
14
|
export declare function handleTopicViz(vizSvc: VizService): (req: IncomingMessage, res: ServerResponse) => void;
|
|
13
15
|
export declare function handleTopicExercises(exerciseSvc: ExerciseService): (req: IncomingMessage, res: ServerResponse) => void;
|
|
14
16
|
export declare function handleRunTests(exerciseSvc: ExerciseService): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
@@ -52,7 +52,7 @@ export function handlePhases(curriculumSvc) {
|
|
|
52
52
|
writeJSON(res, phases);
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
export function handleTopic(curriculumSvc, qaSvc) {
|
|
55
|
+
export function handleTopic(curriculumSvc, qaSvc, resourceSvc) {
|
|
56
56
|
return (req, res) => {
|
|
57
57
|
const id = extractId(req.url ?? '', '/api/topics/');
|
|
58
58
|
if (id === null) {
|
|
@@ -65,7 +65,19 @@ export function handleTopic(curriculumSvc, qaSvc) {
|
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
const entries = qaSvc.listEntries(id);
|
|
68
|
-
|
|
68
|
+
const resources = resourceSvc.listForTopic(id);
|
|
69
|
+
writeJSON(res, { ...topic, entries, resources });
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function handleTopicResources(resourceSvc) {
|
|
73
|
+
return (req, res) => {
|
|
74
|
+
const id = extractId(req.url ?? '', '/api/topics/');
|
|
75
|
+
if (id === null) {
|
|
76
|
+
writeError(res, 400, 'Invalid topic ID');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const resources = resourceSvc.listForTopic(id);
|
|
80
|
+
writeJSON(res, resources);
|
|
69
81
|
};
|
|
70
82
|
}
|
|
71
83
|
export function handleTopicViz(vizSvc) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/dashboard/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/dashboard/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,15 +2,17 @@ import type { CurriculumService } from '../services/curriculum.js';
|
|
|
2
2
|
import type { QAService } from '../services/qa.js';
|
|
3
3
|
import type { VizService } from '../services/viz.js';
|
|
4
4
|
import type { ExerciseService } from '../services/exercises.js';
|
|
5
|
+
import type { ResourceService } from '../services/resources.js';
|
|
5
6
|
export declare class DashboardServer {
|
|
6
7
|
private curriculumSvc;
|
|
7
8
|
private qaSvc;
|
|
8
9
|
private vizSvc;
|
|
9
10
|
private exerciseSvc;
|
|
11
|
+
private resourceSvc;
|
|
10
12
|
private port;
|
|
11
13
|
private sseClients;
|
|
12
14
|
private httpServer;
|
|
13
|
-
constructor(curriculumSvc: CurriculumService, qaSvc: QAService, vizSvc: VizService, exerciseSvc: ExerciseService, port: number);
|
|
15
|
+
constructor(curriculumSvc: CurriculumService, qaSvc: QAService, vizSvc: VizService, exerciseSvc: ExerciseService, resourceSvc: ResourceService, port: number);
|
|
14
16
|
start(): void;
|
|
15
17
|
stop(): void;
|
|
16
18
|
notify(): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
|
-
import { handleSubjects, handlePhases, handleTopic, handleTopicViz, handleTopicExercises, handleRunTests, handleSubmitQuiz, handleSearch, writeJSON, } from './api.js';
|
|
2
|
+
import { handleSubjects, handlePhases, handleTopic, handleTopicViz, handleTopicExercises, handleTopicResources, handleRunTests, handleSubmitQuiz, handleSearch, writeJSON, } from './api.js';
|
|
3
3
|
// ── Embedded static content ──
|
|
4
4
|
// esbuild --loader:.html=text inlines these as strings at bundle time.
|
|
5
5
|
// @ts-ignore — esbuild text loader
|
|
@@ -19,14 +19,16 @@ export class DashboardServer {
|
|
|
19
19
|
qaSvc;
|
|
20
20
|
vizSvc;
|
|
21
21
|
exerciseSvc;
|
|
22
|
+
resourceSvc;
|
|
22
23
|
port;
|
|
23
24
|
sseClients = new Set();
|
|
24
25
|
httpServer = null;
|
|
25
|
-
constructor(curriculumSvc, qaSvc, vizSvc, exerciseSvc, port) {
|
|
26
|
+
constructor(curriculumSvc, qaSvc, vizSvc, exerciseSvc, resourceSvc, port) {
|
|
26
27
|
this.curriculumSvc = curriculumSvc;
|
|
27
28
|
this.qaSvc = qaSvc;
|
|
28
29
|
this.vizSvc = vizSvc;
|
|
29
30
|
this.exerciseSvc = exerciseSvc;
|
|
31
|
+
this.resourceSvc = resourceSvc;
|
|
30
32
|
this.port = port;
|
|
31
33
|
}
|
|
32
34
|
start() {
|
|
@@ -114,9 +116,14 @@ export class DashboardServer {
|
|
|
114
116
|
handleTopicExercises(this.exerciseSvc)(req, res);
|
|
115
117
|
return;
|
|
116
118
|
}
|
|
119
|
+
// GET /api/topics/:id/resources
|
|
120
|
+
if (method === 'GET' && /^\/api\/topics\/\d+\/resources$/.test(path)) {
|
|
121
|
+
handleTopicResources(this.resourceSvc)(req, res);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
117
124
|
// GET /api/topics/:id
|
|
118
125
|
if (method === 'GET' && /^\/api\/topics\/\d+$/.test(path)) {
|
|
119
|
-
handleTopic(this.curriculumSvc, this.qaSvc)(req, res);
|
|
126
|
+
handleTopic(this.curriculumSvc, this.qaSvc, this.resourceSvc)(req, res);
|
|
120
127
|
return;
|
|
121
128
|
}
|
|
122
129
|
// POST /api/exercises/:id/run
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
package/server/dist/index.js
CHANGED
|
@@ -7,10 +7,12 @@ import { CurriculumService } from './services/curriculum.js';
|
|
|
7
7
|
import { QAService } from './services/qa.js';
|
|
8
8
|
import { VizService } from './services/viz.js';
|
|
9
9
|
import { ExerciseService } from './services/exercises.js';
|
|
10
|
+
import { ResourceService } from './services/resources.js';
|
|
10
11
|
import { registerCurriculumTools } from './tools/curriculum.js';
|
|
11
12
|
import { registerQATools } from './tools/qa.js';
|
|
12
13
|
import { registerVizTools } from './tools/viz.js';
|
|
13
14
|
import { registerExerciseTools } from './tools/exercises.js';
|
|
15
|
+
import { registerResourceTools } from './tools/resources.js';
|
|
14
16
|
import { DashboardServer } from './dashboard/server.js';
|
|
15
17
|
const fileStore = new FileStore();
|
|
16
18
|
const db = new Database(fileStore.dbPath);
|
|
@@ -19,14 +21,16 @@ const curriculumSvc = new CurriculumService(db);
|
|
|
19
21
|
const qaSvc = new QAService(db);
|
|
20
22
|
const vizSvc = new VizService(db);
|
|
21
23
|
const exerciseSvc = new ExerciseService(db, fileStore);
|
|
24
|
+
const resourceSvc = new ResourceService(db);
|
|
22
25
|
const port = Number(db.getSetting('dashboard_port') ?? '19282');
|
|
23
|
-
const dashboard = new DashboardServer(curriculumSvc, qaSvc, vizSvc, exerciseSvc, port);
|
|
26
|
+
const dashboard = new DashboardServer(curriculumSvc, qaSvc, vizSvc, exerciseSvc, resourceSvc, port);
|
|
24
27
|
const notify = () => dashboard.notify();
|
|
25
28
|
const server = new McpServer({ name: 'study-dash', version: '0.1.0' });
|
|
26
29
|
registerCurriculumTools(server, curriculumSvc, sessions, notify);
|
|
27
30
|
registerQATools(server, qaSvc, sessions, notify);
|
|
28
31
|
registerVizTools(server, vizSvc, sessions, notify);
|
|
29
32
|
registerExerciseTools(server, exerciseSvc, sessions, notify);
|
|
33
|
+
registerResourceTools(server, resourceSvc, sessions, notify);
|
|
30
34
|
dashboard.start();
|
|
31
35
|
async function run() {
|
|
32
36
|
const transport = new StdioServerTransport();
|
package/server/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;AAClC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAC1C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEjD,MAAM,aAAa,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;AAChD,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;AAChC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;AAClC,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Database } from '../storage/db.js';
|
|
2
|
+
import type { Resource } from '../types.js';
|
|
3
|
+
interface ImportResourceInput {
|
|
4
|
+
topic_id: number;
|
|
5
|
+
title: string;
|
|
6
|
+
url: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class ResourceService {
|
|
9
|
+
private db;
|
|
10
|
+
constructor(db: Database);
|
|
11
|
+
addResource(topicId: number, title: string, url: string, source?: string): Resource;
|
|
12
|
+
listForTopic(topicId: number): Resource[];
|
|
13
|
+
importResources(resources: ImportResourceInput[]): number;
|
|
14
|
+
deleteResource(id: number): void;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class ResourceService {
|
|
2
|
+
db;
|
|
3
|
+
constructor(db) {
|
|
4
|
+
this.db = db;
|
|
5
|
+
}
|
|
6
|
+
addResource(topicId, title, url, source = 'manual') {
|
|
7
|
+
const result = this.db.raw.prepare('INSERT INTO resources (topic_id, title, url, source) VALUES (?, ?, ?, ?)').run(topicId, title, url, source);
|
|
8
|
+
return this.db.raw.prepare('SELECT * FROM resources WHERE id = ?').get(result.lastInsertRowid);
|
|
9
|
+
}
|
|
10
|
+
listForTopic(topicId) {
|
|
11
|
+
return this.db.raw.prepare('SELECT * FROM resources WHERE topic_id = ? ORDER BY created_at ASC, id ASC').all(topicId);
|
|
12
|
+
}
|
|
13
|
+
importResources(resources) {
|
|
14
|
+
const insert = this.db.raw.prepare('INSERT INTO resources (topic_id, title, url, source) VALUES (?, ?, ?, ?)');
|
|
15
|
+
const tx = this.db.raw.transaction((items) => {
|
|
16
|
+
for (const r of items) {
|
|
17
|
+
insert.run(r.topic_id, r.title, r.url, 'import');
|
|
18
|
+
}
|
|
19
|
+
return items.length;
|
|
20
|
+
});
|
|
21
|
+
return tx(resources);
|
|
22
|
+
}
|
|
23
|
+
deleteResource(id) {
|
|
24
|
+
this.db.raw.prepare('DELETE FROM resources WHERE id = ?').run(id);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/services/resources.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,EAAY;QAAZ,OAAE,GAAF,EAAE,CAAU;IAAG,CAAC;IAEpC,WAAW,CAAC,OAAe,EAAE,KAAa,EAAE,GAAW,EAAE,SAAiB,QAAQ;QAChF,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAChC,0EAA0E,CAC3E,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAa,CAAC;IAC7G,CAAC;IAED,YAAY,CAAC,OAAe;QAC1B,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CACxB,4EAA4E,CAC7E,CAAC,GAAG,CAAC,OAAO,CAAe,CAAC;IAC/B,CAAC;IAED,eAAe,CAAC,SAAgC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAChC,0EAA0E,CAC3E,CAAC;QACF,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAA4B,EAAE,EAAE;YAClE,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IAED,cAAc,CAAC,EAAU;QACvB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;CACF"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const schema = "\nPRAGMA foreign_keys=ON;\n\nCREATE TABLE IF NOT EXISTS subjects (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n language TEXT NOT NULL DEFAULT '',\n source TEXT NOT NULL DEFAULT 'manual'\n CHECK (source IN ('manual','roadmap','pdf')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS phases (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n subject_id INTEGER NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n sort_order INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE INDEX IF NOT EXISTS idx_phases_subject ON phases(subject_id);\n\nCREATE TABLE IF NOT EXISTS topics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n phase_id INTEGER NOT NULL REFERENCES phases(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n sort_order INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'todo'\n CHECK (status IN ('todo','in_progress','done')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_topics_phase ON topics(phase_id);\nCREATE INDEX IF NOT EXISTS idx_topics_status ON topics(status);\n\nCREATE TABLE IF NOT EXISTS entries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK (kind IN ('question','answer','note')),\n content TEXT NOT NULL DEFAULT '',\n session_id TEXT NOT NULL DEFAULT '',\n question_id INTEGER REFERENCES entries(id) ON DELETE SET NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_entries_topic ON entries(topic_id);\nCREATE INDEX IF NOT EXISTS idx_entries_session ON entries(session_id);\n\nCREATE TABLE IF NOT EXISTS visualizations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,\n title TEXT NOT NULL DEFAULT '',\n steps_json TEXT NOT NULL DEFAULT '[]',\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_viz_topic ON visualizations(topic_id);\n\nCREATE TABLE IF NOT EXISTS exercises (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,\n title TEXT NOT NULL DEFAULT '',\n type TEXT NOT NULL DEFAULT 'coding'\n CHECK (type IN ('coding','quiz','project','assignment')),\n description TEXT NOT NULL DEFAULT '',\n difficulty TEXT NOT NULL DEFAULT 'medium'\n CHECK (difficulty IN ('easy','medium','hard')),\n est_minutes INTEGER NOT NULL DEFAULT 0,\n source TEXT NOT NULL DEFAULT 'ai'\n CHECK (source IN ('ai','pdf_import')),\n starter_code TEXT NOT NULL DEFAULT '',\n test_content TEXT NOT NULL DEFAULT '',\n quiz_json TEXT NOT NULL DEFAULT '{}',\n file_path TEXT NOT NULL DEFAULT '',\n status TEXT NOT NULL DEFAULT 'pending'\n CHECK (status IN ('pending','in_progress','passed','failed')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_exercises_topic ON exercises(topic_id);\nCREATE INDEX IF NOT EXISTS idx_exercises_status ON exercises(status);\n\nCREATE TABLE IF NOT EXISTS exercise_results (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n exercise_id INTEGER NOT NULL REFERENCES exercises(id) ON DELETE CASCADE,\n test_name TEXT NOT NULL DEFAULT '',\n passed INTEGER NOT NULL DEFAULT 0,\n output TEXT NOT NULL DEFAULT '',\n ran_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_results_exercise ON exercise_results(exercise_id);\n\nCREATE TABLE IF NOT EXISTS settings (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL DEFAULT ''\n);\n\n-- FTS5 virtual table for full-text search over entries\nCREATE VIRTUAL TABLE IF NOT EXISTS entries_fts\n USING fts5(content, content='entries', content_rowid='id');\n\n-- Sync triggers: keep entries_fts up to date with entries\nCREATE TRIGGER IF NOT EXISTS entries_ai\n AFTER INSERT ON entries BEGIN\n INSERT INTO entries_fts(rowid, content) VALUES (new.id, new.content);\n END;\n\nCREATE TRIGGER IF NOT EXISTS entries_ad\n AFTER DELETE ON entries BEGIN\n INSERT INTO entries_fts(entries_fts, rowid, content)\n VALUES ('delete', old.id, old.content);\n END;\n\nCREATE TRIGGER IF NOT EXISTS entries_au\n AFTER UPDATE ON entries BEGIN\n INSERT INTO entries_fts(entries_fts, rowid, content)\n VALUES ('delete', old.id, old.content);\n INSERT INTO entries_fts(rowid, content) VALUES (new.id, new.content);\n END;\n";
|
|
1
|
+
export declare const schema = "\nPRAGMA foreign_keys=ON;\n\nCREATE TABLE IF NOT EXISTS subjects (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n slug TEXT NOT NULL UNIQUE,\n language TEXT NOT NULL DEFAULT '',\n source TEXT NOT NULL DEFAULT 'manual'\n CHECK (source IN ('manual','roadmap','pdf')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS phases (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n subject_id INTEGER NOT NULL REFERENCES subjects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n sort_order INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE INDEX IF NOT EXISTS idx_phases_subject ON phases(subject_id);\n\nCREATE TABLE IF NOT EXISTS topics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n phase_id INTEGER NOT NULL REFERENCES phases(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n sort_order INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'todo'\n CHECK (status IN ('todo','in_progress','done')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_topics_phase ON topics(phase_id);\nCREATE INDEX IF NOT EXISTS idx_topics_status ON topics(status);\n\nCREATE TABLE IF NOT EXISTS entries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK (kind IN ('question','answer','note')),\n content TEXT NOT NULL DEFAULT '',\n session_id TEXT NOT NULL DEFAULT '',\n question_id INTEGER REFERENCES entries(id) ON DELETE SET NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_entries_topic ON entries(topic_id);\nCREATE INDEX IF NOT EXISTS idx_entries_session ON entries(session_id);\n\nCREATE TABLE IF NOT EXISTS visualizations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,\n title TEXT NOT NULL DEFAULT '',\n steps_json TEXT NOT NULL DEFAULT '[]',\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_viz_topic ON visualizations(topic_id);\n\nCREATE TABLE IF NOT EXISTS exercises (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,\n title TEXT NOT NULL DEFAULT '',\n type TEXT NOT NULL DEFAULT 'coding'\n CHECK (type IN ('coding','quiz','project','assignment')),\n description TEXT NOT NULL DEFAULT '',\n difficulty TEXT NOT NULL DEFAULT 'medium'\n CHECK (difficulty IN ('easy','medium','hard')),\n est_minutes INTEGER NOT NULL DEFAULT 0,\n source TEXT NOT NULL DEFAULT 'ai'\n CHECK (source IN ('ai','pdf_import')),\n starter_code TEXT NOT NULL DEFAULT '',\n test_content TEXT NOT NULL DEFAULT '',\n quiz_json TEXT NOT NULL DEFAULT '{}',\n file_path TEXT NOT NULL DEFAULT '',\n status TEXT NOT NULL DEFAULT 'pending'\n CHECK (status IN ('pending','in_progress','passed','failed')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_exercises_topic ON exercises(topic_id);\nCREATE INDEX IF NOT EXISTS idx_exercises_status ON exercises(status);\n\nCREATE TABLE IF NOT EXISTS exercise_results (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n exercise_id INTEGER NOT NULL REFERENCES exercises(id) ON DELETE CASCADE,\n test_name TEXT NOT NULL DEFAULT '',\n passed INTEGER NOT NULL DEFAULT 0,\n output TEXT NOT NULL DEFAULT '',\n ran_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_results_exercise ON exercise_results(exercise_id);\n\nCREATE TABLE IF NOT EXISTS resources (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,\n title TEXT NOT NULL DEFAULT '',\n url TEXT NOT NULL DEFAULT '',\n source TEXT NOT NULL DEFAULT 'manual'\n CHECK (source IN ('manual','auto','import')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_resources_topic ON resources(topic_id);\n\nCREATE TABLE IF NOT EXISTS settings (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL DEFAULT ''\n);\n\n-- FTS5 virtual table for full-text search over entries\nCREATE VIRTUAL TABLE IF NOT EXISTS entries_fts\n USING fts5(content, content='entries', content_rowid='id');\n\n-- Sync triggers: keep entries_fts up to date with entries\nCREATE TRIGGER IF NOT EXISTS entries_ai\n AFTER INSERT ON entries BEGIN\n INSERT INTO entries_fts(rowid, content) VALUES (new.id, new.content);\n END;\n\nCREATE TRIGGER IF NOT EXISTS entries_ad\n AFTER DELETE ON entries BEGIN\n INSERT INTO entries_fts(entries_fts, rowid, content)\n VALUES ('delete', old.id, old.content);\n END;\n\nCREATE TRIGGER IF NOT EXISTS entries_au\n AFTER UPDATE ON entries BEGIN\n INSERT INTO entries_fts(entries_fts, rowid, content)\n VALUES ('delete', old.id, old.content);\n INSERT INTO entries_fts(rowid, content) VALUES (new.id, new.content);\n END;\n";
|
|
2
2
|
/** Future migrations appended here in order (v1 is baseline — empty). */
|
|
3
3
|
export declare const migrations: string[];
|
|
@@ -93,6 +93,17 @@ CREATE TABLE IF NOT EXISTS exercise_results (
|
|
|
93
93
|
|
|
94
94
|
CREATE INDEX IF NOT EXISTS idx_results_exercise ON exercise_results(exercise_id);
|
|
95
95
|
|
|
96
|
+
CREATE TABLE IF NOT EXISTS resources (
|
|
97
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
98
|
+
topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,
|
|
99
|
+
title TEXT NOT NULL DEFAULT '',
|
|
100
|
+
url TEXT NOT NULL DEFAULT '',
|
|
101
|
+
source TEXT NOT NULL DEFAULT 'manual'
|
|
102
|
+
CHECK (source IN ('manual','auto','import')),
|
|
103
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
104
|
+
);
|
|
105
|
+
CREATE INDEX IF NOT EXISTS idx_resources_topic ON resources(topic_id);
|
|
106
|
+
|
|
96
107
|
CREATE TABLE IF NOT EXISTS settings (
|
|
97
108
|
key TEXT PRIMARY KEY,
|
|
98
109
|
value TEXT NOT NULL DEFAULT ''
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqIrB,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,UAAU,GAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ResourceService } from '../services/resources.js';
|
|
3
|
+
import type { SessionState } from '../types.js';
|
|
4
|
+
export declare function registerResourceTools(server: McpServer, svc: ResourceService, sessions: Map<string, SessionState>, notify: () => void): void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
function getSession(sessions, sessionId) {
|
|
3
|
+
const key = sessionId || '_default';
|
|
4
|
+
if (!sessions.has(key)) {
|
|
5
|
+
sessions.set(key, { subjectId: null, topicId: null });
|
|
6
|
+
}
|
|
7
|
+
return sessions.get(key);
|
|
8
|
+
}
|
|
9
|
+
function err(text) {
|
|
10
|
+
return { content: [{ type: 'text', text }], isError: true };
|
|
11
|
+
}
|
|
12
|
+
function ok(text) {
|
|
13
|
+
return { content: [{ type: 'text', text }] };
|
|
14
|
+
}
|
|
15
|
+
export function registerResourceTools(server, svc, sessions, notify) {
|
|
16
|
+
// 1. learn_add_resource
|
|
17
|
+
server.tool('learn_add_resource', 'Add a reference link to the active topic (or a specific topic by ID)', {
|
|
18
|
+
title: z.string().describe('Resource title'),
|
|
19
|
+
url: z.string().describe('Resource URL'),
|
|
20
|
+
topic_id: z.number().optional().describe('Topic ID (defaults to active topic)'),
|
|
21
|
+
session_id: z.string().optional(),
|
|
22
|
+
}, async ({ title, url, topic_id, session_id }) => {
|
|
23
|
+
const tid = topic_id ?? getSession(sessions, session_id).topicId;
|
|
24
|
+
if (tid === null) {
|
|
25
|
+
return err('No active topic. Use learn_set_topic first or provide topic_id.');
|
|
26
|
+
}
|
|
27
|
+
const resource = svc.addResource(tid, title, url, 'manual');
|
|
28
|
+
notify();
|
|
29
|
+
return ok(`Added resource "${resource.title}" (id=${resource.id}) to topic ${tid}`);
|
|
30
|
+
});
|
|
31
|
+
// 2. learn_import_resources
|
|
32
|
+
server.tool('learn_import_resources', 'Bulk import resource links from a JSON array of {topic_id, title, url} objects', {
|
|
33
|
+
resources_json: z.string().describe('JSON array of {topic_id: number, title: string, url: string}'),
|
|
34
|
+
}, async ({ resources_json }) => {
|
|
35
|
+
let resources;
|
|
36
|
+
try {
|
|
37
|
+
resources = JSON.parse(resources_json);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return err('Invalid JSON');
|
|
41
|
+
}
|
|
42
|
+
if (!Array.isArray(resources)) {
|
|
43
|
+
return err('Expected a JSON array');
|
|
44
|
+
}
|
|
45
|
+
const count = svc.importResources(resources);
|
|
46
|
+
notify();
|
|
47
|
+
return ok(`Imported ${count} resources`);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/tools/resources.ts"],"names":[],"mappings":"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"}
|
package/server/dist/types.d.ts
CHANGED
|
@@ -38,6 +38,14 @@ export interface Visualization {
|
|
|
38
38
|
steps_json: string;
|
|
39
39
|
created_at: string;
|
|
40
40
|
}
|
|
41
|
+
export interface Resource {
|
|
42
|
+
id: number;
|
|
43
|
+
topic_id: number;
|
|
44
|
+
title: string;
|
|
45
|
+
url: string;
|
|
46
|
+
source: 'manual' | 'auto' | 'import';
|
|
47
|
+
created_at: string;
|
|
48
|
+
}
|
|
41
49
|
export interface VizStep {
|
|
42
50
|
html: string;
|
|
43
51
|
description: string;
|
package/server/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "study-dash-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc && chmod +x dist/index.js",
|
|
14
|
-
"bundle": "
|
|
14
|
+
"bundle": "node build.mjs",
|
|
15
15
|
"dev": "tsc --watch",
|
|
16
16
|
"test": "vitest run",
|
|
17
17
|
"test:watch": "vitest"
|
|
@@ -22,9 +22,16 @@
|
|
|
22
22
|
"zod": "^3.25.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
+
"@rollup/plugin-commonjs": "^29.0.2",
|
|
26
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
27
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
28
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
25
29
|
"@types/better-sqlite3": "^7.6.0",
|
|
26
30
|
"@types/node": "^22",
|
|
27
31
|
"esbuild": "^0.27.4",
|
|
32
|
+
"rollup": "^4.60.0",
|
|
33
|
+
"rollup-plugin-string": "^3.0.0",
|
|
34
|
+
"tslib": "^2.8.1",
|
|
28
35
|
"typescript": "^5.3.3",
|
|
29
36
|
"vitest": "^2.1.8"
|
|
30
37
|
}
|