@vue-skuilder/cli 0.1.23 → 0.1.25
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/mcp-server.js +2 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/standalone-ui-template/package.json +2 -2
- package/dist/standalone-ui-template/src/views/AdminRegisterQuestionsView.vue +226 -38
- package/dist/studio-ui-src/package.json +2 -2
- package/package.json +10 -10
- package/src/mcp-server.ts +2 -2
- package/tsconfig.json +2 -1
package/dist/mcp-server.js
CHANGED
|
@@ -26,8 +26,8 @@ async function main() {
|
|
|
26
26
|
options: {
|
|
27
27
|
COUCHDB_SERVER_URL: process.env.COUCHDB_SERVER_URL || `localhost:${port}`,
|
|
28
28
|
COUCHDB_SERVER_PROTOCOL: process.env.COUCHDB_SERVER_PROTOCOL || 'http',
|
|
29
|
-
COUCHDB_USERNAME: 'admin',
|
|
30
|
-
COUCHDB_PASSWORD: 'password',
|
|
29
|
+
COUCHDB_USERNAME: process.env.COUCHDB_USERNAME || 'admin',
|
|
30
|
+
COUCHDB_PASSWORD: process.env.COUCHDB_PASSWORD || 'password',
|
|
31
31
|
COURSE_IDS: [courseId], // Limit to specific course
|
|
32
32
|
localStoragePrefix: 'mcp-server',
|
|
33
33
|
},
|
package/dist/mcp-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,wDAAwD;AAExD,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,oBAAoB,EAAE,CAAC;AAEvB,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;YACvD,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;YAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAEpE,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;QAE3C,uDAAuD;QACvD,uFAAuF;QACvF,MAAM,aAAa,GAAG;YACpB,IAAI,EAAE,OAAgB;YACtB,OAAO,EAAE;gBACP,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,aAAa,IAAI,EAAE;gBACzE,uBAAuB,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,MAAM;gBACtE,gBAAgB,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.25",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist-lib/questions.cjs.js",
|
|
9
9
|
"module": "./dist-lib/questions.mjs",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"vue-tsc": "^1.8.0",
|
|
59
59
|
"wait-on": "8.0.2"
|
|
60
60
|
},
|
|
61
|
-
"stableVersion": "0.1.
|
|
61
|
+
"stableVersion": "0.1.25"
|
|
62
62
|
}
|
|
@@ -5,8 +5,22 @@
|
|
|
5
5
|
Register Question Types
|
|
6
6
|
</v-card-title>
|
|
7
7
|
|
|
8
|
+
<!-- Access Denied -->
|
|
9
|
+
<v-alert v-if="!isAuthorized" type="error" variant="tonal" class="ma-4">
|
|
10
|
+
<v-alert-title>Access Denied</v-alert-title>
|
|
11
|
+
<p class="mb-2">
|
|
12
|
+
This admin page requires authentication with an authorized account.
|
|
13
|
+
</p>
|
|
14
|
+
<p v-if="!authStore.isLoggedIn" class="mb-2">
|
|
15
|
+
Please <a href="#" @click.prevent="authStore.setLoginDialog(true)">log in</a> to continue.
|
|
16
|
+
</p>
|
|
17
|
+
<p v-else class="mb-2">
|
|
18
|
+
Your account ({{ currentUsername }}) does not have admin privileges.
|
|
19
|
+
</p>
|
|
20
|
+
</v-alert>
|
|
21
|
+
|
|
8
22
|
<!-- Static Mode Warning -->
|
|
9
|
-
<v-alert v-if="isStaticMode" type="warning" variant="tonal" class="ma-4">
|
|
23
|
+
<v-alert v-else-if="isStaticMode" type="warning" variant="tonal" class="ma-4">
|
|
10
24
|
<v-alert-title>Static Mode Detected</v-alert-title>
|
|
11
25
|
<p class="mb-2">
|
|
12
26
|
Question type registration is not available in static mode.
|
|
@@ -21,7 +35,7 @@
|
|
|
21
35
|
</v-alert>
|
|
22
36
|
|
|
23
37
|
<!-- Loading State -->
|
|
24
|
-
<v-card-text v-else-if="loading">
|
|
38
|
+
<v-card-text v-else-if="isAuthorized && loading">
|
|
25
39
|
<v-progress-circular indeterminate color="primary" />
|
|
26
40
|
<span class="ml-4">Loading question type data...</span>
|
|
27
41
|
</v-card-text>
|
|
@@ -37,47 +51,138 @@
|
|
|
37
51
|
<!-- Current State -->
|
|
38
52
|
<div class="mb-6">
|
|
39
53
|
<h3 class="text-h6 mb-2">Current CourseConfig</h3>
|
|
40
|
-
<v-
|
|
41
|
-
<v-
|
|
42
|
-
<
|
|
43
|
-
<v-icon>mdi-shape</v-icon>
|
|
44
|
-
</template>
|
|
45
|
-
<v-list-item-title>
|
|
54
|
+
<v-expansion-panels variant="accordion">
|
|
55
|
+
<v-expansion-panel>
|
|
56
|
+
<v-expansion-panel-title>
|
|
57
|
+
<v-icon class="mr-2">mdi-shape</v-icon>
|
|
46
58
|
{{ currentDataShapeCount }} DataShapes registered
|
|
47
|
-
</v-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
</v-expansion-panel-title>
|
|
60
|
+
<v-expansion-panel-text>
|
|
61
|
+
<v-list v-if="courseConfig?.dataShapes?.length" density="compact">
|
|
62
|
+
<v-list-item
|
|
63
|
+
v-for="ds in courseConfig.dataShapes"
|
|
64
|
+
:key="ds.name"
|
|
65
|
+
>
|
|
66
|
+
<template #default>
|
|
67
|
+
<v-list-item-title class="font-weight-medium">
|
|
68
|
+
{{ ds.name }}
|
|
69
|
+
</v-list-item-title>
|
|
70
|
+
<v-list-item-subtitle>
|
|
71
|
+
{{ ds.questionTypes?.length || 0 }} question types |
|
|
72
|
+
Schema: {{ ds.serializedZodSchema ? 'Yes' : 'No' }}
|
|
73
|
+
</v-list-item-subtitle>
|
|
74
|
+
</template>
|
|
75
|
+
<template #append>
|
|
76
|
+
<v-btn
|
|
77
|
+
icon="mdi-delete"
|
|
78
|
+
size="small"
|
|
79
|
+
variant="text"
|
|
80
|
+
color="error"
|
|
81
|
+
:loading="removing"
|
|
82
|
+
@click="confirmRemoveDataShape(ds.name)"
|
|
83
|
+
/>
|
|
84
|
+
</template>
|
|
85
|
+
</v-list-item>
|
|
86
|
+
</v-list>
|
|
87
|
+
<div v-else class="text-medium-emphasis pa-2">
|
|
88
|
+
No DataShapes registered
|
|
89
|
+
</div>
|
|
90
|
+
</v-expansion-panel-text>
|
|
91
|
+
</v-expansion-panel>
|
|
92
|
+
<v-expansion-panel>
|
|
93
|
+
<v-expansion-panel-title>
|
|
94
|
+
<v-icon class="mr-2">mdi-help-circle</v-icon>
|
|
54
95
|
{{ currentQuestionTypeCount }} QuestionTypes registered
|
|
55
|
-
</v-
|
|
56
|
-
|
|
57
|
-
|
|
96
|
+
</v-expansion-panel-title>
|
|
97
|
+
<v-expansion-panel-text>
|
|
98
|
+
<v-list v-if="courseConfig?.questionTypes?.length" density="compact">
|
|
99
|
+
<v-list-item
|
|
100
|
+
v-for="qt in courseConfig.questionTypes"
|
|
101
|
+
:key="qt.name"
|
|
102
|
+
>
|
|
103
|
+
<template #default>
|
|
104
|
+
<v-list-item-title class="font-weight-medium">
|
|
105
|
+
{{ qt.name }}
|
|
106
|
+
</v-list-item-title>
|
|
107
|
+
<v-list-item-subtitle>
|
|
108
|
+
Views: {{ qt.viewList?.join(', ') || 'none' }} |
|
|
109
|
+
DataShapes: {{ qt.dataShapeList?.join(', ') || 'none' }}
|
|
110
|
+
</v-list-item-subtitle>
|
|
111
|
+
</template>
|
|
112
|
+
<template #append>
|
|
113
|
+
<v-btn
|
|
114
|
+
icon="mdi-delete"
|
|
115
|
+
size="small"
|
|
116
|
+
variant="text"
|
|
117
|
+
color="error"
|
|
118
|
+
:loading="removing"
|
|
119
|
+
@click="confirmRemoveQuestionType(qt.name)"
|
|
120
|
+
/>
|
|
121
|
+
</template>
|
|
122
|
+
</v-list-item>
|
|
123
|
+
</v-list>
|
|
124
|
+
<div v-else class="text-medium-emphasis pa-2">
|
|
125
|
+
No QuestionTypes registered
|
|
126
|
+
</div>
|
|
127
|
+
</v-expansion-panel-text>
|
|
128
|
+
</v-expansion-panel>
|
|
129
|
+
</v-expansion-panels>
|
|
58
130
|
</div>
|
|
59
131
|
|
|
60
132
|
<!-- Custom Questions -->
|
|
61
133
|
<div class="mb-6">
|
|
62
134
|
<h3 class="text-h6 mb-2">From allCustomQuestions()</h3>
|
|
63
|
-
<v-
|
|
64
|
-
<v-
|
|
65
|
-
<
|
|
66
|
-
<v-icon>mdi-shape</v-icon>
|
|
67
|
-
</template>
|
|
68
|
-
<v-list-item-title>
|
|
135
|
+
<v-expansion-panels variant="accordion">
|
|
136
|
+
<v-expansion-panel>
|
|
137
|
+
<v-expansion-panel-title>
|
|
138
|
+
<v-icon class="mr-2">mdi-shape</v-icon>
|
|
69
139
|
{{ processedDataShapes.length }} DataShapes found
|
|
70
|
-
</v-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
140
|
+
</v-expansion-panel-title>
|
|
141
|
+
<v-expansion-panel-text>
|
|
142
|
+
<v-list v-if="processedDataShapes.length" density="compact">
|
|
143
|
+
<v-list-item
|
|
144
|
+
v-for="ds in processedDataShapes"
|
|
145
|
+
:key="`${ds.course}.${ds.name}`"
|
|
146
|
+
>
|
|
147
|
+
<v-list-item-title class="font-weight-medium">
|
|
148
|
+
{{ ds.course }}.{{ ds.name }}
|
|
149
|
+
</v-list-item-title>
|
|
150
|
+
<v-list-item-subtitle>
|
|
151
|
+
Fields: {{ ds.dataShape?.fields?.map(f => f.name).join(', ') || 'none' }}
|
|
152
|
+
</v-list-item-subtitle>
|
|
153
|
+
</v-list-item>
|
|
154
|
+
</v-list>
|
|
155
|
+
<div v-else class="text-medium-emphasis pa-2">
|
|
156
|
+
No DataShapes found in allCustomQuestions()
|
|
157
|
+
</div>
|
|
158
|
+
</v-expansion-panel-text>
|
|
159
|
+
</v-expansion-panel>
|
|
160
|
+
<v-expansion-panel>
|
|
161
|
+
<v-expansion-panel-title>
|
|
162
|
+
<v-icon class="mr-2">mdi-help-circle</v-icon>
|
|
77
163
|
{{ processedQuestions.length }} QuestionTypes found
|
|
78
|
-
</v-
|
|
79
|
-
|
|
80
|
-
|
|
164
|
+
</v-expansion-panel-title>
|
|
165
|
+
<v-expansion-panel-text>
|
|
166
|
+
<v-list v-if="processedQuestions.length" density="compact">
|
|
167
|
+
<v-list-item
|
|
168
|
+
v-for="q in processedQuestions"
|
|
169
|
+
:key="`${q.course}.${q.name}`"
|
|
170
|
+
>
|
|
171
|
+
<v-list-item-title class="font-weight-medium">
|
|
172
|
+
{{ q.course }}.{{ q.name }}
|
|
173
|
+
</v-list-item-title>
|
|
174
|
+
<v-list-item-subtitle>
|
|
175
|
+
DataShapes: {{ q.dataShapes?.map(ds => ds.name).join(', ') || 'none' }} |
|
|
176
|
+
Views: {{ q.views?.length || 0 }}
|
|
177
|
+
</v-list-item-subtitle>
|
|
178
|
+
</v-list-item>
|
|
179
|
+
</v-list>
|
|
180
|
+
<div v-else class="text-medium-emphasis pa-2">
|
|
181
|
+
No QuestionTypes found in allCustomQuestions()
|
|
182
|
+
</div>
|
|
183
|
+
</v-expansion-panel-text>
|
|
184
|
+
</v-expansion-panel>
|
|
185
|
+
</v-expansion-panels>
|
|
81
186
|
</div>
|
|
82
187
|
|
|
83
188
|
<!-- Changes Preview -->
|
|
@@ -114,7 +219,7 @@
|
|
|
114
219
|
</v-card-text>
|
|
115
220
|
|
|
116
221
|
<!-- Actions -->
|
|
117
|
-
<v-card-actions v-if="!isStaticMode && !loading && !error">
|
|
222
|
+
<v-card-actions v-if="isAuthorized && !isStaticMode && !loading && !error">
|
|
118
223
|
<v-spacer />
|
|
119
224
|
<v-btn
|
|
120
225
|
color="primary"
|
|
@@ -134,6 +239,7 @@ import { ref, computed, onMounted } from 'vue';
|
|
|
134
239
|
import { getDataLayer } from '@vue-skuilder/db';
|
|
135
240
|
import {
|
|
136
241
|
registerCustomQuestionTypes,
|
|
242
|
+
removeCustomQuestionTypes,
|
|
137
243
|
processCustomQuestionsData,
|
|
138
244
|
isDataShapeRegistered,
|
|
139
245
|
isQuestionTypeRegistered,
|
|
@@ -142,14 +248,29 @@ import {
|
|
|
142
248
|
type ProcessedDataShape,
|
|
143
249
|
type ProcessedQuestionData,
|
|
144
250
|
} from '@vue-skuilder/db';
|
|
145
|
-
import { useAuthStore } from '@vue-skuilder/common-ui';
|
|
251
|
+
import { useAuthStore, getCurrentUser } from '@vue-skuilder/common-ui';
|
|
146
252
|
import { allCustomQuestions } from '../questions';
|
|
147
253
|
import config from '../../skuilder.config.json';
|
|
148
254
|
|
|
255
|
+
// Admin usernames that can access this page
|
|
256
|
+
const ADMIN_USERNAMES = ['admin'];
|
|
257
|
+
|
|
258
|
+
// Auth state
|
|
259
|
+
const authStore = useAuthStore();
|
|
260
|
+
const currentUsername = ref<string | null>(null);
|
|
261
|
+
|
|
262
|
+
// Check if user is authorized (logged in + admin username)
|
|
263
|
+
const isAuthorized = computed(() => {
|
|
264
|
+
if (!authStore.isLoggedIn) return false;
|
|
265
|
+
if (!currentUsername.value) return false;
|
|
266
|
+
return ADMIN_USERNAMES.includes(currentUsername.value);
|
|
267
|
+
});
|
|
268
|
+
|
|
149
269
|
// State
|
|
150
270
|
const loading = ref(true);
|
|
151
271
|
const error = ref<string | null>(null);
|
|
152
272
|
const registering = ref(false);
|
|
273
|
+
const removing = ref(false);
|
|
153
274
|
const successMessage = ref<string | null>(null);
|
|
154
275
|
|
|
155
276
|
const courseConfig = ref<any>(null);
|
|
@@ -284,10 +405,77 @@ async function registerQuestions() {
|
|
|
284
405
|
}
|
|
285
406
|
}
|
|
286
407
|
|
|
408
|
+
async function confirmRemoveDataShape(name: string) {
|
|
409
|
+
if (!confirm(`Remove DataShape "${name}"? This cannot be undone.`)) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
await removeItems([name], []);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
async function confirmRemoveQuestionType(name: string) {
|
|
416
|
+
if (!confirm(`Remove QuestionType "${name}"? This cannot be undone.`)) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
await removeItems([], [name]);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
async function removeItems(dataShapeNames: string[], questionTypeNames: string[]) {
|
|
423
|
+
if (!courseConfig.value) {
|
|
424
|
+
error.value = 'Missing course config for removal';
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
try {
|
|
429
|
+
removing.value = true;
|
|
430
|
+
error.value = null;
|
|
431
|
+
successMessage.value = null;
|
|
432
|
+
|
|
433
|
+
const courseId = config.course;
|
|
434
|
+
if (!courseId) {
|
|
435
|
+
throw new Error('No course ID configured');
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const courseDB = getDataLayer().getCourseDB(courseId);
|
|
439
|
+
|
|
440
|
+
const result = await removeCustomQuestionTypes(
|
|
441
|
+
dataShapeNames,
|
|
442
|
+
questionTypeNames,
|
|
443
|
+
courseConfig.value,
|
|
444
|
+
courseDB
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
if (result.success) {
|
|
448
|
+
successMessage.value = `Successfully removed ${result.removedCount} items`;
|
|
449
|
+
// Reload data to show updated state
|
|
450
|
+
await loadData();
|
|
451
|
+
} else {
|
|
452
|
+
error.value = result.errorMessage || 'Removal failed';
|
|
453
|
+
}
|
|
454
|
+
} catch (err) {
|
|
455
|
+
error.value = err instanceof Error ? err.message : String(err);
|
|
456
|
+
console.error('[AdminRegisterQuestions] Removal failed:', err);
|
|
457
|
+
} finally {
|
|
458
|
+
removing.value = false;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
287
462
|
// Lifecycle
|
|
288
|
-
onMounted(() => {
|
|
289
|
-
|
|
463
|
+
onMounted(async () => {
|
|
464
|
+
// Check authorization first
|
|
465
|
+
try {
|
|
466
|
+
const user = await getCurrentUser();
|
|
467
|
+
if (user) {
|
|
468
|
+
currentUsername.value = user.getUsername();
|
|
469
|
+
}
|
|
470
|
+
} catch (err) {
|
|
471
|
+
console.error('[AdminRegisterQuestions] Failed to get current user:', err);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// Only load data if authorized and not in static mode
|
|
475
|
+
if (isAuthorized.value && !isStaticMode.value) {
|
|
290
476
|
loadData();
|
|
477
|
+
} else {
|
|
478
|
+
loading.value = false;
|
|
291
479
|
}
|
|
292
480
|
});
|
|
293
481
|
</script>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.25",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"dev": "vite",
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"vite": "^7.0.0",
|
|
33
33
|
"vue-tsc": "^1.8.0"
|
|
34
34
|
},
|
|
35
|
-
"stableVersion": "0.1.
|
|
35
|
+
"stableVersion": "0.1.25"
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.25",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"description": "CLI scaffolding tool for vue-skuilder projects",
|
|
9
9
|
"bin": {
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
],
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@mdi/font": "^7.3.67",
|
|
48
|
-
"@vue-skuilder/common": "0.1.
|
|
49
|
-
"@vue-skuilder/common-ui": "0.1.
|
|
50
|
-
"@vue-skuilder/courseware": "0.1.
|
|
51
|
-
"@vue-skuilder/db": "0.1.
|
|
52
|
-
"@vue-skuilder/edit-ui": "0.1.
|
|
53
|
-
"@vue-skuilder/express": "0.1.
|
|
54
|
-
"@vue-skuilder/mcp": "0.1.
|
|
48
|
+
"@vue-skuilder/common": "0.1.25",
|
|
49
|
+
"@vue-skuilder/common-ui": "0.1.25",
|
|
50
|
+
"@vue-skuilder/courseware": "0.1.25",
|
|
51
|
+
"@vue-skuilder/db": "0.1.25",
|
|
52
|
+
"@vue-skuilder/edit-ui": "0.1.25",
|
|
53
|
+
"@vue-skuilder/express": "0.1.25",
|
|
54
|
+
"@vue-skuilder/mcp": "0.1.25",
|
|
55
55
|
"chalk": "^5.3.0",
|
|
56
56
|
"commander": "^11.0.0",
|
|
57
57
|
"fs-extra": "^11.2.0",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@types/node": "^22",
|
|
71
71
|
"@types/serve-static": "^1.15.0",
|
|
72
72
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
73
|
-
"@vue-skuilder/studio-ui": "0.1.
|
|
73
|
+
"@vue-skuilder/studio-ui": "0.1.25",
|
|
74
74
|
"cypress": "^15.6.0",
|
|
75
75
|
"typescript": "~5.9.3",
|
|
76
76
|
"vite": "^7.0.0",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"node": ">=18.0.0"
|
|
82
82
|
},
|
|
83
83
|
"packageManager": "yarn@4.12.0",
|
|
84
|
-
"stableVersion": "0.1.
|
|
84
|
+
"stableVersion": "0.1.25"
|
|
85
85
|
}
|
package/src/mcp-server.ts
CHANGED
|
@@ -31,8 +31,8 @@ async function main() {
|
|
|
31
31
|
options: {
|
|
32
32
|
COUCHDB_SERVER_URL: process.env.COUCHDB_SERVER_URL || `localhost:${port}`,
|
|
33
33
|
COUCHDB_SERVER_PROTOCOL: process.env.COUCHDB_SERVER_PROTOCOL || 'http',
|
|
34
|
-
COUCHDB_USERNAME: 'admin',
|
|
35
|
-
COUCHDB_PASSWORD: 'password',
|
|
34
|
+
COUCHDB_USERNAME: process.env.COUCHDB_USERNAME || 'admin',
|
|
35
|
+
COUCHDB_PASSWORD: process.env.COUCHDB_PASSWORD || 'password',
|
|
36
36
|
COURSE_IDS: [courseId], // Limit to specific course
|
|
37
37
|
localStoragePrefix: 'mcp-server',
|
|
38
38
|
},
|