project-knowledge 1.0.1 → 1.0.2

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.
Files changed (2) hide show
  1. package/_site/index.html +53 -12
  2. 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="My Project" />
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(form.slug || "<slug>") }}</code></p>
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>
@@ -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: "主要语言",
@@ -1619,6 +1628,36 @@ createApp({
1619
1628
  return String(value || "").replace(/[\\\/]+$/, "");
1620
1629
  }
1621
1630
 
1631
+ function basenameFromPath(value) {
1632
+ return String(value || "").split(/[\\\/]+/).filter(Boolean).pop() || "";
1633
+ }
1634
+
1635
+ function normalizeSlug(value) {
1636
+ return String(value || "")
1637
+ .trim()
1638
+ .toLowerCase()
1639
+ .replace(/['"]/g, "")
1640
+ .replace(/[^a-z0-9]+/g, "-")
1641
+ .replace(/^-+|-+$/g, "")
1642
+ .replace(/-{2,}/g, "-")
1643
+ .slice(0, 41)
1644
+ .replace(/-+$/g, "");
1645
+ }
1646
+
1647
+ function uniqueSlug(base) {
1648
+ const fallback = `project-${Date.now().toString(36)}`;
1649
+ const root = normalizeSlug(base) || fallback;
1650
+ let candidate = root;
1651
+ let index = 2;
1652
+ while (projects.value && projects.value[candidate]) {
1653
+ const suffix = `-${index++}`;
1654
+ candidate = `${root.slice(0, Math.max(1, 41 - suffix.length))}${suffix}`;
1655
+ }
1656
+ return candidate;
1657
+ }
1658
+
1659
+ const importSlugPreview = computed(() => uniqueSlug(form.slug || form.displayName || basenameFromPath(form.localPath)));
1660
+
1622
1661
  function projectKbPath(slug) {
1623
1662
  const root = trimTrailingSlash(knowledgeStoreConfig.rootPath || `${kbRoot.value}\\projects`);
1624
1663
  return `${root}\\${slug}`;
@@ -2567,7 +2606,9 @@ createApp({
2567
2606
  formOk.value = "";
2568
2607
  submitting.value = true;
2569
2608
  try {
2570
- if (!/^[a-z0-9][a-z0-9-]*$/.test(form.slug)) throw new Error("Slug must be kebab-case.");
2609
+ const slug = uniqueSlug(form.slug || form.displayName || basenameFromPath(form.localPath));
2610
+ if (!/^[a-z0-9][a-z0-9-]{0,40}$/.test(slug)) throw new Error(t("invalidSlug"));
2611
+ form.slug = slug;
2571
2612
  const config = {
2572
2613
  displayName: form.displayName,
2573
2614
  localPath: form.localPath,
@@ -2576,7 +2617,7 @@ createApp({
2576
2617
  tags: form.tagsStr.split(",").map(s => s.trim()).filter(Boolean),
2577
2618
  isReference: !!form.isReference,
2578
2619
  docConvention: "frontmatter-relations",
2579
- kbPath: projectKbPath(form.slug),
2620
+ kbPath: projectKbPath(slug),
2580
2621
  enabled: true,
2581
2622
  aiProfileId: aiConfig.defaultProfileId || "mock-agent",
2582
2623
  knowledgeLanguage: form.knowledgeLanguage || "zh-CN",
@@ -2584,7 +2625,7 @@ createApp({
2584
2625
  goalStatus: "not-created"
2585
2626
  };
2586
2627
  await api("PUT", "/api/projects", {
2587
- slug: form.slug,
2628
+ slug,
2588
2629
  config,
2589
2630
  importOptions: {
2590
2631
  initGit: !!form.initGit,
@@ -2592,10 +2633,10 @@ createApp({
2592
2633
  remoteUrl: form.remoteUrl || "",
2593
2634
  },
2594
2635
  });
2595
- if (form.initNow) await api("POST", `/api/projects/${form.slug}/init`);
2596
- formOk.value = `Imported ${form.slug}.`;
2636
+ if (form.initNow) await api("POST", `/api/projects/${slug}/init`);
2637
+ formOk.value = `Imported ${form.displayName || slug}.`;
2597
2638
  await refreshAll();
2598
- selectProject(form.slug);
2639
+ selectProject(slug);
2599
2640
  activeView.value = "dashboard";
2600
2641
  } catch (e) {
2601
2642
  formError.value = e.message;
@@ -2688,7 +2729,7 @@ createApp({
2688
2729
  summaryPanel, pendingCommitItems, supervisionIssues, issuesByProject, structuredLogs, selectedLog, logFilters,
2689
2730
  knowledgeStoreConfig, knowledgeMigrationPlan, loggingConfig,
2690
2731
  loading, pollError, activeView, selectedSlug, selectedProject, pageTitle, projectList, summaryCards, navItems,
2691
- theme, uiLanguage, t, toggleTheme, form, submitting, formError, formOk, addProject, resetForm, busySlug, initProject,
2732
+ theme, uiLanguage, t, toggleTheme, form, importSlugPreview, submitting, formError, formOk, addProject, resetForm, busySlug, initProject,
2692
2733
  freq, scheduleMsg, applySchedule, deleteSchedule,
2693
2734
  runs, selectedRunId, selectedRun, drafts, filteredDrafts, draftBranches, draftBranchFilter, applyDraftButtonLabel, draftSelection, previewDraftPath, draftPreview, allowGoalEdit,
2694
2735
  removeDialog, removeProjectDisabled,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-knowledge",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Knowledge base manager with Git integration, AI-driven analysis, and bilingual (zh-CN/en-US) knowledge output",
5
5
  "main": "_site/server.js",
6
6
  "scripts": {