project-knowledge 1.0.1 → 1.0.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/_site/index.html +67 -16
- package/package.json +1 -1
package/_site/index.html
CHANGED
|
@@ -422,11 +422,12 @@
|
|
|
422
422
|
<h2 class="text-lg font-semibold">{{ t("importProject") }}</h2>
|
|
423
423
|
<p class="mt-1 text-sm muted">{{ t("importHelp") }}</p>
|
|
424
424
|
<div class="mt-5 grid gap-4">
|
|
425
|
-
<label class="grid gap-1 text-sm">{{ t("slug") }}
|
|
426
|
-
<input v-model="form.slug" required pattern="[a-z0-9][a-z0-9\-]*" class="input font-mono" placeholder="my-project" />
|
|
427
|
-
</label>
|
|
428
425
|
<label class="grid gap-1 text-sm">{{ t("displayName") }}
|
|
429
|
-
<input v-model="form.displayName" required class="input" placeholder="
|
|
426
|
+
<input v-model="form.displayName" required class="input" :placeholder="t('displayNamePlaceholder')" />
|
|
427
|
+
</label>
|
|
428
|
+
<label class="grid gap-1 text-sm">{{ t("slug") }} <span class="muted">{{ t("optional") }}</span>
|
|
429
|
+
<input v-model="form.slug" class="input font-mono" placeholder="my-project" />
|
|
430
|
+
<span class="text-xs muted">{{ t("slugHelp") }} <code>{{ importSlugPreview }}</code></span>
|
|
430
431
|
</label>
|
|
431
432
|
<label class="grid gap-1 text-sm">{{ t("localPath") }}
|
|
432
433
|
<input v-model="form.localPath" required class="input font-mono text-xs" placeholder="D:\SanQian.Xu\my-project" />
|
|
@@ -484,7 +485,7 @@
|
|
|
484
485
|
<aside class="panel rounded-xl border p-5">
|
|
485
486
|
<h2 class="font-semibold">{{ t("importTarget") }}</h2>
|
|
486
487
|
<div class="mt-4 space-y-3 text-sm muted">
|
|
487
|
-
<p>{{ t("kbPath") }}: <code>{{ displayProjectKbPath(
|
|
488
|
+
<p>{{ t("kbPath") }}: <code>{{ displayProjectKbPath(importSlugPreview || "<slug>") }}</code></p>
|
|
488
489
|
<p>{{ t("schemaNormalized") }}</p>
|
|
489
490
|
<p>{{ t("gitPopulate") }}</p>
|
|
490
491
|
</div>
|
|
@@ -503,12 +504,12 @@
|
|
|
503
504
|
<div class="mt-5 grid gap-4">
|
|
504
505
|
<label class="grid gap-1 text-sm">
|
|
505
506
|
<span class="field-label">{{ t("defaultProfile") }} <span class="help-dot" :title="t('defaultProfileHelp')" tabindex="0">?</span></span>
|
|
506
|
-
<select v-model="aiConfig.defaultProfileId" class="input">
|
|
507
|
+
<select v-model="aiConfig.defaultProfileId" @change="markAiProfileDirty" class="input">
|
|
507
508
|
<option v-for="p in aiConfig.profiles" :key="p.id" :value="p.id" :disabled="p.enabled === false">{{ profileOptionLabel(p) }}</option>
|
|
508
509
|
</select>
|
|
509
510
|
</label>
|
|
510
511
|
|
|
511
|
-
<div class="panel2 rounded-xl border p-4">
|
|
512
|
+
<div class="panel2 rounded-xl border p-4" @input.capture="markAiProfileDirty" @change.capture="markAiProfileDirty">
|
|
512
513
|
<div class="mb-4 flex items-center justify-between gap-3">
|
|
513
514
|
<h3 class="font-medium">{{ t("profileEditor") }}</h3>
|
|
514
515
|
<div class="flex flex-wrap gap-2">
|
|
@@ -1044,6 +1045,10 @@ const I18N = {
|
|
|
1044
1045
|
reset: "Reset",
|
|
1045
1046
|
slug: "Slug",
|
|
1046
1047
|
displayName: "Display name",
|
|
1048
|
+
displayNamePlaceholder: "Tokens Consumption Leaderboard",
|
|
1049
|
+
optional: "(optional)",
|
|
1050
|
+
slugHelp: "Internal id for URL and folders. Leave blank to auto-generate:",
|
|
1051
|
+
invalidSlug: "Internal id must be lowercase letters, numbers, and hyphens.",
|
|
1047
1052
|
localPath: "Local path",
|
|
1048
1053
|
gitPath: "Git path",
|
|
1049
1054
|
primaryLanguage: "Primary language",
|
|
@@ -1265,6 +1270,10 @@ const I18N = {
|
|
|
1265
1270
|
reset: "重置",
|
|
1266
1271
|
slug: "标识",
|
|
1267
1272
|
displayName: "显示名称",
|
|
1273
|
+
displayNamePlaceholder: "Tokens Consumption Leaderboard",
|
|
1274
|
+
optional: "(可选)",
|
|
1275
|
+
slugHelp: "URL 和目录使用的内部标识。留空会自动生成:",
|
|
1276
|
+
invalidSlug: "内部标识只能使用小写字母、数字和连字符。",
|
|
1268
1277
|
localPath: "本地路径",
|
|
1269
1278
|
gitPath: "Git 路径",
|
|
1270
1279
|
primaryLanguage: "主要语言",
|
|
@@ -1525,6 +1534,7 @@ createApp({
|
|
|
1525
1534
|
const testPrompt = ref("what model are you?");
|
|
1526
1535
|
const testResult = ref("");
|
|
1527
1536
|
const testingProfile = ref(false);
|
|
1537
|
+
const aiProfileFormDirty = ref(false);
|
|
1528
1538
|
const selectedAiProfileId = ref("mock-agent");
|
|
1529
1539
|
const selectedKnowledgeLanguage = ref("zh-CN");
|
|
1530
1540
|
|
|
@@ -1619,6 +1629,36 @@ createApp({
|
|
|
1619
1629
|
return String(value || "").replace(/[\\\/]+$/, "");
|
|
1620
1630
|
}
|
|
1621
1631
|
|
|
1632
|
+
function basenameFromPath(value) {
|
|
1633
|
+
return String(value || "").split(/[\\\/]+/).filter(Boolean).pop() || "";
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
function normalizeSlug(value) {
|
|
1637
|
+
return String(value || "")
|
|
1638
|
+
.trim()
|
|
1639
|
+
.toLowerCase()
|
|
1640
|
+
.replace(/['"]/g, "")
|
|
1641
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
1642
|
+
.replace(/^-+|-+$/g, "")
|
|
1643
|
+
.replace(/-{2,}/g, "-")
|
|
1644
|
+
.slice(0, 41)
|
|
1645
|
+
.replace(/-+$/g, "");
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
function uniqueSlug(base) {
|
|
1649
|
+
const fallback = `project-${Date.now().toString(36)}`;
|
|
1650
|
+
const root = normalizeSlug(base) || fallback;
|
|
1651
|
+
let candidate = root;
|
|
1652
|
+
let index = 2;
|
|
1653
|
+
while (projects.value && projects.value[candidate]) {
|
|
1654
|
+
const suffix = `-${index++}`;
|
|
1655
|
+
candidate = `${root.slice(0, Math.max(1, 41 - suffix.length))}${suffix}`;
|
|
1656
|
+
}
|
|
1657
|
+
return candidate;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
const importSlugPreview = computed(() => uniqueSlug(form.slug || form.displayName || basenameFromPath(form.localPath)));
|
|
1661
|
+
|
|
1622
1662
|
function projectKbPath(slug) {
|
|
1623
1663
|
const root = trimTrailingSlash(knowledgeStoreConfig.rootPath || `${kbRoot.value}\\projects`);
|
|
1624
1664
|
return `${root}\\${slug}`;
|
|
@@ -1744,7 +1784,10 @@ createApp({
|
|
|
1744
1784
|
if (state.logging) Object.assign(loggingConfig, state.logging);
|
|
1745
1785
|
lastRun.value = state.lastRun || lastRun.value;
|
|
1746
1786
|
if (!selectedSlug.value && projectList.value.length) selectProject(projectList.value[0].slug);
|
|
1747
|
-
|
|
1787
|
+
const aiProfileTask = activeView.value === "settings" && aiProfileFormDirty.value
|
|
1788
|
+
? Promise.resolve()
|
|
1789
|
+
: loadAiProfiles(false);
|
|
1790
|
+
await Promise.all([loadJobs(), aiProfileTask, loadIssues()]);
|
|
1748
1791
|
} catch (e) {
|
|
1749
1792
|
pollError.value = e.message;
|
|
1750
1793
|
} finally {
|
|
@@ -2261,6 +2304,11 @@ createApp({
|
|
|
2261
2304
|
timeoutMs: profile.timeoutMs != null ? Number(profile.timeoutMs) : 300000,
|
|
2262
2305
|
});
|
|
2263
2306
|
testResult.value = "";
|
|
2307
|
+
aiProfileFormDirty.value = false;
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
function markAiProfileDirty() {
|
|
2311
|
+
aiProfileFormDirty.value = true;
|
|
2264
2312
|
}
|
|
2265
2313
|
|
|
2266
2314
|
function normalizeProfileId(value) {
|
|
@@ -2363,6 +2411,7 @@ createApp({
|
|
|
2363
2411
|
const parsed = JSON.parse(aiProfilesText.value);
|
|
2364
2412
|
await api("PUT", "/api/ai-profiles", parsed);
|
|
2365
2413
|
aiMessage.value = "AI profiles saved.";
|
|
2414
|
+
aiProfileFormDirty.value = false;
|
|
2366
2415
|
await loadAiProfiles();
|
|
2367
2416
|
} catch (e) {
|
|
2368
2417
|
aiMessage.value = `Save failed: ${e.message}`;
|
|
@@ -2567,7 +2616,9 @@ createApp({
|
|
|
2567
2616
|
formOk.value = "";
|
|
2568
2617
|
submitting.value = true;
|
|
2569
2618
|
try {
|
|
2570
|
-
|
|
2619
|
+
const slug = uniqueSlug(form.slug || form.displayName || basenameFromPath(form.localPath));
|
|
2620
|
+
if (!/^[a-z0-9][a-z0-9-]{0,40}$/.test(slug)) throw new Error(t("invalidSlug"));
|
|
2621
|
+
form.slug = slug;
|
|
2571
2622
|
const config = {
|
|
2572
2623
|
displayName: form.displayName,
|
|
2573
2624
|
localPath: form.localPath,
|
|
@@ -2576,7 +2627,7 @@ createApp({
|
|
|
2576
2627
|
tags: form.tagsStr.split(",").map(s => s.trim()).filter(Boolean),
|
|
2577
2628
|
isReference: !!form.isReference,
|
|
2578
2629
|
docConvention: "frontmatter-relations",
|
|
2579
|
-
kbPath: projectKbPath(
|
|
2630
|
+
kbPath: projectKbPath(slug),
|
|
2580
2631
|
enabled: true,
|
|
2581
2632
|
aiProfileId: aiConfig.defaultProfileId || "mock-agent",
|
|
2582
2633
|
knowledgeLanguage: form.knowledgeLanguage || "zh-CN",
|
|
@@ -2584,7 +2635,7 @@ createApp({
|
|
|
2584
2635
|
goalStatus: "not-created"
|
|
2585
2636
|
};
|
|
2586
2637
|
await api("PUT", "/api/projects", {
|
|
2587
|
-
slug
|
|
2638
|
+
slug,
|
|
2588
2639
|
config,
|
|
2589
2640
|
importOptions: {
|
|
2590
2641
|
initGit: !!form.initGit,
|
|
@@ -2592,10 +2643,10 @@ createApp({
|
|
|
2592
2643
|
remoteUrl: form.remoteUrl || "",
|
|
2593
2644
|
},
|
|
2594
2645
|
});
|
|
2595
|
-
if (form.initNow) await api("POST", `/api/projects/${
|
|
2596
|
-
formOk.value = `Imported ${form.slug}.`;
|
|
2646
|
+
if (form.initNow) await api("POST", `/api/projects/${slug}/init`);
|
|
2647
|
+
formOk.value = `Imported ${form.displayName || slug}.`;
|
|
2597
2648
|
await refreshAll();
|
|
2598
|
-
selectProject(
|
|
2649
|
+
selectProject(slug);
|
|
2599
2650
|
activeView.value = "dashboard";
|
|
2600
2651
|
} catch (e) {
|
|
2601
2652
|
formError.value = e.message;
|
|
@@ -2688,7 +2739,7 @@ createApp({
|
|
|
2688
2739
|
summaryPanel, pendingCommitItems, supervisionIssues, issuesByProject, structuredLogs, selectedLog, logFilters,
|
|
2689
2740
|
knowledgeStoreConfig, knowledgeMigrationPlan, loggingConfig,
|
|
2690
2741
|
loading, pollError, activeView, selectedSlug, selectedProject, pageTitle, projectList, summaryCards, navItems,
|
|
2691
|
-
theme, uiLanguage, t, toggleTheme, form, submitting, formError, formOk, addProject, resetForm, busySlug, initProject,
|
|
2742
|
+
theme, uiLanguage, t, toggleTheme, form, importSlugPreview, submitting, formError, formOk, addProject, resetForm, busySlug, initProject,
|
|
2692
2743
|
freq, scheduleMsg, applySchedule, deleteSchedule,
|
|
2693
2744
|
runs, selectedRunId, selectedRun, drafts, filteredDrafts, draftBranches, draftBranchFilter, applyDraftButtonLabel, draftSelection, previewDraftPath, draftPreview, allowGoalEdit,
|
|
2694
2745
|
removeDialog, removeProjectDisabled,
|
|
@@ -2697,7 +2748,7 @@ createApp({
|
|
|
2697
2748
|
selectProject, isKbInit, isProjectRunning, repoStatusLevel, projectStatusClass, projectIssues,
|
|
2698
2749
|
kbUrl, goalUrl, displayProjectKbPath, formatTime, formatBytes,
|
|
2699
2750
|
profileOptionLabel,
|
|
2700
|
-
refreshAll, loadJobs, loadJobDetail, loadAiProfiles, loadProfileForm, addProfile, deleteCurrentProfile, saveAiProfiles, saveCurrentProfile, testCurrentProfile, setProjectAiProfile, saveProjectSettings,
|
|
2751
|
+
refreshAll, loadJobs, loadJobDetail, loadAiProfiles, loadProfileForm, markAiProfileDirty, addProfile, deleteCurrentProfile, saveAiProfiles, saveCurrentProfile, testCurrentProfile, setProjectAiProfile, saveProjectSettings,
|
|
2701
2752
|
openSummaryPanel, loadPendingCommits, loadIssues, loadStructuredLogs,
|
|
2702
2753
|
loadKnowledgeStoreConfig, saveKnowledgeStoreConfig, previewKnowledgeMigration, executeKnowledgeMigration, loadLoggingConfig, saveLoggingConfig,
|
|
2703
2754
|
validateGit, scanProject, validateKb, migrateV2, migrateV3, runKnowledgeUpdate, runImportPreflight, runJob, loadHookStatus, installHook, uninstallHook,
|
package/package.json
CHANGED