@industry-theme/agent-panels 0.2.14 → 0.2.16

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.
@@ -2723,6 +2723,76 @@ const parseSkillContent = async (content2, path2, fileTree, fileSystemAdapter, i
2723
2723
  frontmatterValidation
2724
2724
  };
2725
2725
  };
2726
+ const getDeduplicationKey = (skill) => {
2727
+ var _a, _b, _c;
2728
+ if (((_a = skill.metadata) == null ? void 0 : _a.owner) && ((_b = skill.metadata) == null ? void 0 : _b.repo) && ((_c = skill.metadata) == null ? void 0 : _c.skillPath)) {
2729
+ return `github:${skill.metadata.owner}/${skill.metadata.repo}/${skill.metadata.skillPath}`;
2730
+ }
2731
+ const normalizedName = skill.name.toLowerCase().replace(/\s+/g, "-");
2732
+ return `name:${normalizedName}`;
2733
+ };
2734
+ const comparePriority = (skill1, skill2) => {
2735
+ var _a, _b;
2736
+ if (skill1.priority !== skill2.priority) {
2737
+ return skill1.priority < skill2.priority;
2738
+ }
2739
+ const time1 = ((_a = skill1.metadata) == null ? void 0 : _a.installedAt) ? new Date(skill1.metadata.installedAt).getTime() : 0;
2740
+ const time2 = ((_b = skill2.metadata) == null ? void 0 : _b.installedAt) ? new Date(skill2.metadata.installedAt).getTime() : 0;
2741
+ return time1 > time2;
2742
+ };
2743
+ const skillToInstallation = (skill) => ({
2744
+ path: skill.path,
2745
+ source: skill.source,
2746
+ priority: skill.priority,
2747
+ skillFolderPath: skill.skillFolderPath,
2748
+ metadata: skill.metadata
2749
+ });
2750
+ const deduplicateSkills = (skills, isBrowserMode = false) => {
2751
+ if (isBrowserMode) {
2752
+ console.log("[useSkillsData] Browser mode detected, skipping deduplication");
2753
+ return skills;
2754
+ }
2755
+ if (skills.length === 0) {
2756
+ return skills;
2757
+ }
2758
+ const skillGroups = /* @__PURE__ */ new Map();
2759
+ for (const skill of skills) {
2760
+ const key = getDeduplicationKey(skill);
2761
+ const group = skillGroups.get(key) || [];
2762
+ group.push(skill);
2763
+ skillGroups.set(key, group);
2764
+ }
2765
+ console.log("[useSkillsData] Deduplication found", skillGroups.size, "unique skills from", skills.length, "total");
2766
+ const deduplicatedSkills = [];
2767
+ for (const [key, group] of skillGroups.entries()) {
2768
+ if (group.length === 1) {
2769
+ deduplicatedSkills.push({
2770
+ ...group[0],
2771
+ installedLocations: [skillToInstallation(group[0])]
2772
+ });
2773
+ continue;
2774
+ }
2775
+ const sortedByPriority = [...group].sort(
2776
+ (a, b) => comparePriority(a, b) ? -1 : 1
2777
+ );
2778
+ const primary = sortedByPriority[0];
2779
+ const installations = group.map(skillToInstallation);
2780
+ installations.sort((a, b) => a.priority - b.priority);
2781
+ console.log(
2782
+ "[useSkillsData] Deduplicated skill:",
2783
+ primary.name,
2784
+ "from",
2785
+ group.length,
2786
+ "installations. Primary:",
2787
+ primary.source
2788
+ );
2789
+ deduplicatedSkills.push({
2790
+ ...primary,
2791
+ installedLocations: installations
2792
+ });
2793
+ }
2794
+ return deduplicatedSkills;
2795
+ };
2726
2796
  const useSkillsData = ({
2727
2797
  context
2728
2798
  }) => {
@@ -2750,8 +2820,9 @@ const useSkillsData = ({
2750
2820
  setError(null);
2751
2821
  try {
2752
2822
  let localSkills = [];
2823
+ let isBrowserMode = false;
2753
2824
  if (fileTree && (fileSystem == null ? void 0 : fileSystem.readFile) && repoPath) {
2754
- const isBrowserMode = !repoPath.startsWith("/");
2825
+ isBrowserMode = !repoPath.startsWith("/");
2755
2826
  console.log("[useSkillsData] fileTree:", fileTree);
2756
2827
  console.log("[useSkillsData] typeof fileTree:", typeof fileTree);
2757
2828
  console.log("[useSkillsData] fileTree keys:", Object.keys(fileTree));
@@ -2774,8 +2845,10 @@ const useSkillsData = ({
2774
2845
  }
2775
2846
  console.log("[useSkillsData] Global skills:", globalSkills);
2776
2847
  const allSkills = [...localSkills, ...globalSkills];
2777
- console.log("[useSkillsData] Total skills:", allSkills.length);
2778
- setSkills(allSkills);
2848
+ console.log("[useSkillsData] Total skills before deduplication:", allSkills.length);
2849
+ const deduplicatedSkills = deduplicateSkills(allSkills, isBrowserMode);
2850
+ console.log("[useSkillsData] Total skills after deduplication:", deduplicatedSkills.length);
2851
+ setSkills(deduplicatedSkills);
2779
2852
  lastLoadedSha.current = fileTreeSha;
2780
2853
  lastGlobalSkillsCount.current = globalSkillsCount;
2781
2854
  } catch (err) {
@@ -2801,7 +2874,7 @@ const useSkillsData = ({
2801
2874
  refreshSkills
2802
2875
  };
2803
2876
  };
2804
- const getSourceConfig = (source2) => {
2877
+ const getSourceConfig$1 = (source2) => {
2805
2878
  switch (source2) {
2806
2879
  case "global-universal":
2807
2880
  return {
@@ -2850,6 +2923,20 @@ const getSourceConfig = (source2) => {
2850
2923
  };
2851
2924
  }
2852
2925
  };
2926
+ const abbreviateSourceName = (source2) => {
2927
+ switch (source2) {
2928
+ case "project-universal":
2929
+ return "Project";
2930
+ case "global-universal":
2931
+ return "Global";
2932
+ case "project-claude":
2933
+ return "Project (Claude)";
2934
+ case "global-claude":
2935
+ return "Global (Claude)";
2936
+ case "project-other":
2937
+ return "Project";
2938
+ }
2939
+ };
2853
2940
  const SkillCard = ({
2854
2941
  skill,
2855
2942
  onClick,
@@ -2857,7 +2944,7 @@ const SkillCard = ({
2857
2944
  }) => {
2858
2945
  var _a, _b, _c, _d, _e2, _f, _g, _h;
2859
2946
  const { theme: theme2 } = useTheme();
2860
- const sourceConfig = getSourceConfig(skill.source);
2947
+ const sourceConfig = getSourceConfig$1(skill.source);
2861
2948
  const [pathCopied, setPathCopied] = React2__default.useState(false);
2862
2949
  const handleCopyPath = async (e) => {
2863
2950
  e.stopPropagation();
@@ -2994,7 +3081,39 @@ Installed: ${skill.metadata.installedAt ? new Date(skill.metadata.installedAt).t
2994
3081
  /* @__PURE__ */ jsx("span", { children: skill.frontmatterValidation.hasStructure ? skill.frontmatterValidation.missingFields.length > 0 ? `Missing: ${skill.frontmatterValidation.missingFields.join(", ")}` : "Invalid Frontmatter" : "No Frontmatter" })
2995
3082
  ]
2996
3083
  }
2997
- )
3084
+ ),
3085
+ skill.installedLocations && skill.installedLocations.length > 1 && (() => {
3086
+ const otherLocations = skill.installedLocations.filter((loc) => loc.path !== skill.path).map((loc) => abbreviateSourceName(loc.source));
3087
+ const uniqueLocations = Array.from(new Set(otherLocations));
3088
+ const locationText = uniqueLocations.join(", ");
3089
+ return /* @__PURE__ */ jsxs(
3090
+ "div",
3091
+ {
3092
+ style: {
3093
+ display: "inline-flex",
3094
+ alignItems: "center",
3095
+ gap: "4px",
3096
+ padding: "2px 6px",
3097
+ borderRadius: theme2.radii[1],
3098
+ backgroundColor: `${theme2.colors.accent}15`,
3099
+ border: `1px solid ${theme2.colors.accent}30`,
3100
+ fontSize: theme2.fontSizes[0],
3101
+ color: theme2.colors.accent,
3102
+ fontWeight: 500,
3103
+ width: "fit-content"
3104
+ },
3105
+ title: `Also installed in:
3106
+ ${skill.installedLocations.filter((loc) => loc.path !== skill.path).map((loc) => `${abbreviateSourceName(loc.source)}: ${loc.path}`).join("\n")}`,
3107
+ children: [
3108
+ /* @__PURE__ */ jsx(Package, { size: 10 }),
3109
+ /* @__PURE__ */ jsxs("span", { children: [
3110
+ "Also in: ",
3111
+ locationText
3112
+ ] })
3113
+ ]
3114
+ }
3115
+ );
3116
+ })()
2998
3117
  ] })
2999
3118
  ] }),
3000
3119
  (skill.hasScripts || skill.hasReferences || skill.hasAssets) && /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap", flexShrink: 0 }, children: [
@@ -3219,6 +3338,15 @@ const SkillsListPanel = ({
3219
3338
  };
3220
3339
  const handleRefresh = async () => {
3221
3340
  setIsRefreshing(true);
3341
+ if (events) {
3342
+ events.emit({
3343
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3344
+ type: "skills:refresh",
3345
+ source: "skills-list-panel",
3346
+ timestamp: Date.now(),
3347
+ payload: {}
3348
+ });
3349
+ }
3222
3350
  try {
3223
3351
  await refreshSkills();
3224
3352
  } finally {
@@ -47723,6 +47851,504 @@ var DocumentView = ({
47723
47851
  editable
47724
47852
  })));
47725
47853
  };
47854
+ function extractHeaders(markdown2) {
47855
+ const headerRegex = /^(#{1,6})\s+(.+)$/gm;
47856
+ const headers = [];
47857
+ let match;
47858
+ while ((match = headerRegex.exec(markdown2)) !== null) {
47859
+ const level = match[1].length;
47860
+ const text2 = match[2].trim();
47861
+ const id = text2.toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]/g, "");
47862
+ headers.push({ level, text: text2, id });
47863
+ }
47864
+ return headers;
47865
+ }
47866
+ const TableOfContents = ({
47867
+ headers,
47868
+ theme: theme2,
47869
+ className = "",
47870
+ onHeaderClick
47871
+ }) => {
47872
+ const [activeId, setActiveId] = React2__default.useState(null);
47873
+ const handleClick = (header) => {
47874
+ setActiveId(header.id);
47875
+ onHeaderClick == null ? void 0 : onHeaderClick(header);
47876
+ const element2 = document.getElementById(header.id);
47877
+ if (element2) {
47878
+ element2.scrollIntoView({ behavior: "smooth", block: "start" });
47879
+ }
47880
+ };
47881
+ if (headers.length === 0) {
47882
+ return null;
47883
+ }
47884
+ return /* @__PURE__ */ jsx(
47885
+ "nav",
47886
+ {
47887
+ className,
47888
+ style: {
47889
+ flex: 1,
47890
+ overflowY: "auto",
47891
+ minHeight: 0,
47892
+ padding: theme2.space[3]
47893
+ },
47894
+ children: /* @__PURE__ */ jsx(
47895
+ "ul",
47896
+ {
47897
+ style: {
47898
+ listStyle: "none",
47899
+ margin: 0,
47900
+ padding: 0
47901
+ },
47902
+ children: headers.map((header, index2) => {
47903
+ const isActive = activeId === header.id;
47904
+ const indentLevel = Math.max(0, header.level - 1);
47905
+ return /* @__PURE__ */ jsx(
47906
+ "li",
47907
+ {
47908
+ style: {
47909
+ marginBottom: theme2.space[1],
47910
+ marginLeft: `${indentLevel * 20}px`
47911
+ },
47912
+ children: /* @__PURE__ */ jsx(
47913
+ "button",
47914
+ {
47915
+ onClick: () => handleClick(header),
47916
+ style: {
47917
+ display: "block",
47918
+ width: "100%",
47919
+ textAlign: "left",
47920
+ background: "none",
47921
+ border: "none",
47922
+ padding: `${theme2.space[1]} ${theme2.space[2]}`,
47923
+ fontSize: header.level === 1 ? theme2.fontSizes[2] : header.level === 2 ? theme2.fontSizes[1] : theme2.fontSizes[0],
47924
+ fontFamily: theme2.fonts.body,
47925
+ color: isActive ? theme2.colors.primary : theme2.colors.text,
47926
+ cursor: "pointer",
47927
+ borderRadius: "4px",
47928
+ transition: "all 0.2s",
47929
+ fontWeight: isActive ? 600 : header.level === 1 ? 600 : header.level === 2 ? 500 : 400,
47930
+ backgroundColor: isActive ? `${theme2.colors.primary}15` : "transparent",
47931
+ borderLeft: isActive ? `2px solid ${theme2.colors.primary}` : "2px solid transparent",
47932
+ opacity: header.level > 3 ? 0.8 : 1
47933
+ },
47934
+ onMouseEnter: (e) => {
47935
+ if (!isActive) {
47936
+ e.currentTarget.style.backgroundColor = `${theme2.colors.border}50`;
47937
+ }
47938
+ },
47939
+ onMouseLeave: (e) => {
47940
+ if (!isActive) {
47941
+ e.currentTarget.style.backgroundColor = "transparent";
47942
+ }
47943
+ },
47944
+ children: header.text
47945
+ }
47946
+ )
47947
+ },
47948
+ `${header.id}-${index2}`
47949
+ );
47950
+ })
47951
+ }
47952
+ )
47953
+ }
47954
+ );
47955
+ };
47956
+ const getSourceConfig = (source2) => {
47957
+ switch (source2) {
47958
+ case "global-universal":
47959
+ return {
47960
+ label: "Global",
47961
+ icon: Globe,
47962
+ color: "#7c3aed",
47963
+ // purple
47964
+ bgColor: "#7c3aed15",
47965
+ borderColor: "#7c3aed30"
47966
+ };
47967
+ case "global-claude":
47968
+ return {
47969
+ label: "Global Claude",
47970
+ icon: Globe,
47971
+ color: "#0891b2",
47972
+ // cyan
47973
+ bgColor: "#0891b215",
47974
+ borderColor: "#0891b230"
47975
+ };
47976
+ case "project-universal":
47977
+ return {
47978
+ label: "Project",
47979
+ icon: Folder,
47980
+ color: "#16a34a",
47981
+ // green
47982
+ bgColor: "#16a34a15",
47983
+ borderColor: "#16a34a30"
47984
+ };
47985
+ case "project-claude":
47986
+ return {
47987
+ label: "Project Claude",
47988
+ icon: Folder,
47989
+ color: "#0284c7",
47990
+ // blue
47991
+ bgColor: "#0284c715",
47992
+ borderColor: "#0284c730"
47993
+ };
47994
+ case "project-other":
47995
+ return {
47996
+ label: "Project",
47997
+ icon: Folder,
47998
+ color: "#64748b",
47999
+ // slate
48000
+ bgColor: "#64748b15",
48001
+ borderColor: "#64748b30"
48002
+ };
48003
+ }
48004
+ };
48005
+ const formatRelativeTime$1 = (dateString) => {
48006
+ try {
48007
+ const date = new Date(dateString);
48008
+ const now = /* @__PURE__ */ new Date();
48009
+ const diffMs = now.getTime() - date.getTime();
48010
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
48011
+ if (diffDays === 0) return "Today";
48012
+ if (diffDays === 1) return "Yesterday";
48013
+ if (diffDays < 7) return `${diffDays} days ago`;
48014
+ if (diffDays < 30) {
48015
+ const weeks = Math.floor(diffDays / 7);
48016
+ return `${weeks} ${weeks === 1 ? "week" : "weeks"} ago`;
48017
+ }
48018
+ if (diffDays < 365) {
48019
+ const months = Math.floor(diffDays / 30);
48020
+ return `${months} ${months === 1 ? "month" : "months"} ago`;
48021
+ }
48022
+ const years = Math.floor(diffDays / 365);
48023
+ return `${years} ${years === 1 ? "year" : "years"} ago`;
48024
+ } catch {
48025
+ return dateString;
48026
+ }
48027
+ };
48028
+ const SkillSidebar = ({
48029
+ headers,
48030
+ metadata,
48031
+ theme: theme2,
48032
+ className = "",
48033
+ onHeaderClick,
48034
+ skill
48035
+ }) => {
48036
+ const [activeTab, setActiveTab] = React2__default.useState("toc");
48037
+ const hasMetadata = metadata.compatibility || metadata["allowed-tools"] && metadata["allowed-tools"].length > 0 || metadata.metadata && Object.keys(metadata.metadata).length > 0 || (skill == null ? void 0 : skill.installedLocations) && skill.installedLocations.length > 1;
48038
+ React2__default.useEffect(() => {
48039
+ if (headers.length === 0 && hasMetadata) {
48040
+ setActiveTab("metadata");
48041
+ }
48042
+ }, [headers.length, hasMetadata]);
48043
+ if (headers.length === 0 && !hasMetadata) {
48044
+ return null;
48045
+ }
48046
+ return /* @__PURE__ */ jsxs(
48047
+ "div",
48048
+ {
48049
+ className,
48050
+ style: {
48051
+ width: "250px",
48052
+ flexShrink: 0,
48053
+ display: "flex",
48054
+ flexDirection: "column",
48055
+ borderRight: `1px solid ${theme2.colors.border}`
48056
+ },
48057
+ children: [
48058
+ /* @__PURE__ */ jsxs(
48059
+ "div",
48060
+ {
48061
+ style: {
48062
+ display: "flex",
48063
+ borderBottom: `1px solid ${theme2.colors.border}`,
48064
+ backgroundColor: theme2.colors.background
48065
+ },
48066
+ children: [
48067
+ headers.length > 0 && /* @__PURE__ */ jsx(
48068
+ "button",
48069
+ {
48070
+ onClick: () => setActiveTab("toc"),
48071
+ style: {
48072
+ flex: 1,
48073
+ padding: theme2.space[2],
48074
+ background: activeTab === "toc" ? theme2.colors.background : "transparent",
48075
+ border: "none",
48076
+ borderBottom: activeTab === "toc" ? `2px solid ${theme2.colors.primary}` : "2px solid transparent",
48077
+ color: activeTab === "toc" ? theme2.colors.primary : theme2.colors.textSecondary,
48078
+ fontFamily: theme2.fonts.heading,
48079
+ fontSize: theme2.fontSizes[1],
48080
+ fontWeight: activeTab === "toc" ? 600 : 500,
48081
+ cursor: "pointer",
48082
+ transition: "all 0.2s"
48083
+ },
48084
+ onMouseEnter: (e) => {
48085
+ if (activeTab !== "toc") {
48086
+ e.currentTarget.style.color = theme2.colors.text;
48087
+ }
48088
+ },
48089
+ onMouseLeave: (e) => {
48090
+ if (activeTab !== "toc") {
48091
+ e.currentTarget.style.color = theme2.colors.textSecondary;
48092
+ }
48093
+ },
48094
+ children: "Contents"
48095
+ }
48096
+ ),
48097
+ hasMetadata && /* @__PURE__ */ jsx(
48098
+ "button",
48099
+ {
48100
+ onClick: () => setActiveTab("metadata"),
48101
+ style: {
48102
+ flex: 1,
48103
+ padding: theme2.space[2],
48104
+ background: activeTab === "metadata" ? theme2.colors.background : "transparent",
48105
+ border: "none",
48106
+ borderBottom: activeTab === "metadata" ? `2px solid ${theme2.colors.primary}` : "2px solid transparent",
48107
+ color: activeTab === "metadata" ? theme2.colors.primary : theme2.colors.textSecondary,
48108
+ fontFamily: theme2.fonts.heading,
48109
+ fontSize: theme2.fontSizes[1],
48110
+ fontWeight: activeTab === "metadata" ? 600 : 500,
48111
+ cursor: "pointer",
48112
+ transition: "all 0.2s"
48113
+ },
48114
+ onMouseEnter: (e) => {
48115
+ if (activeTab !== "metadata") {
48116
+ e.currentTarget.style.color = theme2.colors.text;
48117
+ }
48118
+ },
48119
+ onMouseLeave: (e) => {
48120
+ if (activeTab !== "metadata") {
48121
+ e.currentTarget.style.color = theme2.colors.textSecondary;
48122
+ }
48123
+ },
48124
+ children: "Metadata"
48125
+ }
48126
+ )
48127
+ ]
48128
+ }
48129
+ ),
48130
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, overflowY: "auto", minHeight: 0 }, children: [
48131
+ activeTab === "toc" && headers.length > 0 && /* @__PURE__ */ jsx(
48132
+ TableOfContents,
48133
+ {
48134
+ headers,
48135
+ theme: theme2,
48136
+ onHeaderClick
48137
+ }
48138
+ ),
48139
+ activeTab === "metadata" && hasMetadata && /* @__PURE__ */ jsxs("div", { style: { padding: theme2.space[3] }, children: [
48140
+ metadata.compatibility && /* @__PURE__ */ jsxs("div", { style: { marginBottom: theme2.space[3] }, children: [
48141
+ /* @__PURE__ */ jsx(
48142
+ "div",
48143
+ {
48144
+ style: {
48145
+ fontFamily: theme2.fonts.heading,
48146
+ fontWeight: 600,
48147
+ fontSize: theme2.fontSizes[0],
48148
+ textTransform: "uppercase",
48149
+ letterSpacing: "0.5px",
48150
+ color: theme2.colors.textSecondary,
48151
+ marginBottom: theme2.space[1]
48152
+ },
48153
+ children: "Compatibility"
48154
+ }
48155
+ ),
48156
+ /* @__PURE__ */ jsx("div", { style: { fontSize: theme2.fontSizes[1], color: theme2.colors.text, fontFamily: theme2.fonts.body }, children: metadata.compatibility })
48157
+ ] }),
48158
+ metadata["allowed-tools"] && metadata["allowed-tools"].length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginBottom: theme2.space[3] }, children: [
48159
+ /* @__PURE__ */ jsx(
48160
+ "div",
48161
+ {
48162
+ style: {
48163
+ fontFamily: theme2.fonts.heading,
48164
+ fontWeight: 600,
48165
+ fontSize: theme2.fontSizes[0],
48166
+ textTransform: "uppercase",
48167
+ letterSpacing: "0.5px",
48168
+ color: theme2.colors.textSecondary,
48169
+ marginBottom: theme2.space[1]
48170
+ },
48171
+ children: "Allowed Tools"
48172
+ }
48173
+ ),
48174
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: theme2.space[1] }, children: metadata["allowed-tools"].map((tool, index2) => /* @__PURE__ */ jsx(
48175
+ "span",
48176
+ {
48177
+ style: {
48178
+ display: "inline-block",
48179
+ paddingTop: theme2.space[2],
48180
+ paddingBottom: theme2.space[2],
48181
+ paddingLeft: theme2.space[3],
48182
+ paddingRight: theme2.space[3],
48183
+ background: theme2.colors.primary,
48184
+ color: theme2.colors.background,
48185
+ borderRadius: "4px",
48186
+ fontSize: theme2.fontSizes[0],
48187
+ fontWeight: 500,
48188
+ fontFamily: theme2.fonts.monospace
48189
+ },
48190
+ children: tool
48191
+ },
48192
+ index2
48193
+ )) })
48194
+ ] }),
48195
+ metadata.metadata && Object.keys(metadata.metadata).length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginBottom: theme2.space[3] }, children: [
48196
+ /* @__PURE__ */ jsx(
48197
+ "div",
48198
+ {
48199
+ style: {
48200
+ fontFamily: theme2.fonts.heading,
48201
+ fontWeight: 600,
48202
+ fontSize: theme2.fontSizes[0],
48203
+ textTransform: "uppercase",
48204
+ letterSpacing: "0.5px",
48205
+ color: theme2.colors.textSecondary,
48206
+ marginBottom: theme2.space[1]
48207
+ },
48208
+ children: "Metadata"
48209
+ }
48210
+ ),
48211
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: theme2.space[1] }, children: Object.entries(metadata.metadata).filter(([key]) => key !== "last-updated").map(([key, value]) => /* @__PURE__ */ jsxs("div", { children: [
48212
+ /* @__PURE__ */ jsxs(
48213
+ "div",
48214
+ {
48215
+ style: {
48216
+ fontSize: theme2.fontSizes[0],
48217
+ fontWeight: 600,
48218
+ color: theme2.colors.textSecondary,
48219
+ fontFamily: theme2.fonts.body
48220
+ },
48221
+ children: [
48222
+ key,
48223
+ ":"
48224
+ ]
48225
+ }
48226
+ ),
48227
+ /* @__PURE__ */ jsx(
48228
+ "div",
48229
+ {
48230
+ style: {
48231
+ fontSize: theme2.fontSizes[1],
48232
+ color: theme2.colors.text,
48233
+ fontFamily: theme2.fonts.monospace
48234
+ },
48235
+ children: value
48236
+ }
48237
+ )
48238
+ ] }, key)) })
48239
+ ] }),
48240
+ (skill == null ? void 0 : skill.installedLocations) && skill.installedLocations.length > 1 && /* @__PURE__ */ jsxs("div", { children: [
48241
+ /* @__PURE__ */ jsxs(
48242
+ "div",
48243
+ {
48244
+ style: {
48245
+ fontFamily: theme2.fonts.heading,
48246
+ fontWeight: 600,
48247
+ fontSize: theme2.fontSizes[0],
48248
+ textTransform: "uppercase",
48249
+ letterSpacing: "0.5px",
48250
+ color: theme2.colors.textSecondary,
48251
+ marginBottom: theme2.space[2]
48252
+ },
48253
+ children: [
48254
+ "Installed Locations (",
48255
+ skill.installedLocations.length,
48256
+ ")"
48257
+ ]
48258
+ }
48259
+ ),
48260
+ /* @__PURE__ */ jsx("div", { style: {
48261
+ display: "flex",
48262
+ flexDirection: "column",
48263
+ gap: theme2.space[2]
48264
+ }, children: skill.installedLocations.map((location2, idx) => {
48265
+ var _a, _b, _c;
48266
+ const isPrimary = location2.path === skill.path;
48267
+ const sourceConfig = getSourceConfig(location2.source);
48268
+ return /* @__PURE__ */ jsxs(
48269
+ "div",
48270
+ {
48271
+ style: {
48272
+ padding: theme2.space[2],
48273
+ backgroundColor: isPrimary ? `${theme2.colors.primary}08` : theme2.colors.backgroundSecondary,
48274
+ borderRadius: "6px",
48275
+ border: `1px solid ${isPrimary ? theme2.colors.primary + "40" : theme2.colors.border}`,
48276
+ display: "flex",
48277
+ flexDirection: "column",
48278
+ gap: theme2.space[1]
48279
+ },
48280
+ children: [
48281
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: theme2.space[2], flexWrap: "wrap" }, children: [
48282
+ /* @__PURE__ */ jsxs(
48283
+ "div",
48284
+ {
48285
+ style: {
48286
+ display: "inline-flex",
48287
+ alignItems: "center",
48288
+ gap: "4px",
48289
+ padding: "2px 6px",
48290
+ borderRadius: theme2.radii[1],
48291
+ backgroundColor: sourceConfig.bgColor,
48292
+ border: `1px solid ${sourceConfig.borderColor}`,
48293
+ fontSize: theme2.fontSizes[0],
48294
+ color: sourceConfig.color,
48295
+ fontWeight: 500
48296
+ },
48297
+ children: [
48298
+ /* @__PURE__ */ jsx(sourceConfig.icon, { size: 10 }),
48299
+ /* @__PURE__ */ jsx("span", { children: sourceConfig.label })
48300
+ ]
48301
+ }
48302
+ ),
48303
+ isPrimary && /* @__PURE__ */ jsx("span", { style: {
48304
+ fontSize: theme2.fontSizes[0],
48305
+ color: theme2.colors.primary,
48306
+ fontWeight: 600,
48307
+ fontFamily: theme2.fonts.body
48308
+ }, children: "(Active)" })
48309
+ ] }),
48310
+ /* @__PURE__ */ jsx("div", { style: {
48311
+ fontSize: theme2.fontSizes[0],
48312
+ color: theme2.colors.textSecondary,
48313
+ fontFamily: theme2.fonts.monospace,
48314
+ wordBreak: "break-all"
48315
+ }, children: location2.path }),
48316
+ ((_a = location2.metadata) == null ? void 0 : _a.installedAt) && /* @__PURE__ */ jsxs("div", { style: {
48317
+ fontSize: theme2.fontSizes[0],
48318
+ color: theme2.colors.textMuted,
48319
+ fontFamily: theme2.fonts.body
48320
+ }, children: [
48321
+ "Installed: ",
48322
+ formatRelativeTime$1(location2.metadata.installedAt)
48323
+ ] }),
48324
+ ((_b = location2.metadata) == null ? void 0 : _b.sha) && ((_c = skill.metadata) == null ? void 0 : _c.sha) && location2.metadata.sha !== skill.metadata.sha && /* @__PURE__ */ jsxs("div", { style: {
48325
+ fontSize: theme2.fontSizes[0],
48326
+ color: "#f59e0b",
48327
+ // warning color
48328
+ fontFamily: theme2.fonts.monospace,
48329
+ display: "flex",
48330
+ alignItems: "center",
48331
+ gap: "4px"
48332
+ }, children: [
48333
+ /* @__PURE__ */ jsx(TriangleAlert, { size: 10 }),
48334
+ /* @__PURE__ */ jsxs("span", { children: [
48335
+ "Different version (SHA: ",
48336
+ location2.metadata.sha.substring(0, 7),
48337
+ ")"
48338
+ ] })
48339
+ ] })
48340
+ ]
48341
+ },
48342
+ idx
48343
+ );
48344
+ }) })
48345
+ ] })
48346
+ ] })
48347
+ ] })
48348
+ ]
48349
+ }
48350
+ );
48351
+ };
47726
48352
  const formatRelativeTime = (dateString) => {
47727
48353
  try {
47728
48354
  const date = new Date(dateString);
@@ -47749,7 +48375,8 @@ const formatRelativeTime = (dateString) => {
47749
48375
  const SkillMetadataSection = ({
47750
48376
  metadata,
47751
48377
  theme: theme2,
47752
- structure
48378
+ structure,
48379
+ skill
47753
48380
  }) => {
47754
48381
  var _a, _b, _c, _d, _e2;
47755
48382
  const [expandedSections, setExpandedSections] = React2__default.useState({
@@ -48037,16 +48664,20 @@ const SkillMarkdown = ({
48037
48664
  onWarnings,
48038
48665
  showRawOnError = false,
48039
48666
  containerWidth,
48040
- structure
48667
+ structure,
48668
+ skill
48041
48669
  }) => {
48042
48670
  const [parsed, setParsed] = React2__default.useState(null);
48671
+ const [headers, setHeaders] = React2__default.useState([]);
48043
48672
  React2__default.useEffect(() => {
48044
- const skill = parseSkillMarkdownGraceful(content2);
48045
- setParsed(skill);
48046
- onParsed == null ? void 0 : onParsed(skill);
48047
- if (skill.warnings.length > 0) {
48048
- onWarnings == null ? void 0 : onWarnings(skill.warnings);
48049
- }
48673
+ const skill2 = parseSkillMarkdownGraceful(content2);
48674
+ setParsed(skill2);
48675
+ onParsed == null ? void 0 : onParsed(skill2);
48676
+ if (skill2.warnings.length > 0) {
48677
+ onWarnings == null ? void 0 : onWarnings(skill2.warnings);
48678
+ }
48679
+ const extractedHeaders = extractHeaders(skill2.body);
48680
+ setHeaders(extractedHeaders);
48050
48681
  }, [content2, onParsed, onWarnings]);
48051
48682
  if (!theme2 || !theme2.space) {
48052
48683
  return /* @__PURE__ */ jsx("div", { className, style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsx("div", { style: { padding: "2rem", textAlign: "center", color: "#856404" }, children: "Error: Theme not available. Wrap component in ThemeProvider." }) });
@@ -48083,9 +48714,18 @@ const SkillMarkdown = ({
48083
48714
  background: theme2.colors.background
48084
48715
  },
48085
48716
  children: [
48086
- /* @__PURE__ */ jsx("div", { style: { padding: theme2.space[3], paddingBottom: 0 }, children: /* @__PURE__ */ jsx(SkillMetadataSection, { metadata: parsed.metadata, theme: theme2, structure }) }),
48087
- /* @__PURE__ */ jsx("div", { style: { flex: 1, overflow: "auto", padding: theme2.space[3], paddingTop: 0 }, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: theme2.space[4], alignItems: "flex-start" }, children: [
48088
- /* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx(
48717
+ /* @__PURE__ */ jsx("div", { style: { padding: theme2.space[3], paddingBottom: 0 }, children: /* @__PURE__ */ jsx(SkillMetadataSection, { metadata: parsed.metadata, theme: theme2, structure, skill }) }),
48718
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
48719
+ /* @__PURE__ */ jsx(
48720
+ SkillSidebar,
48721
+ {
48722
+ headers,
48723
+ metadata: parsed.metadata,
48724
+ theme: theme2,
48725
+ skill
48726
+ }
48727
+ ),
48728
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, overflow: "auto", padding: theme2.space[3], paddingTop: 0 }, children: /* @__PURE__ */ jsx(
48089
48729
  IndustryMarkdownSlide,
48090
48730
  {
48091
48731
  content: parsed.body,
@@ -48095,123 +48735,8 @@ const SkillMarkdown = ({
48095
48735
  isVisible: true,
48096
48736
  containerWidth
48097
48737
  }
48098
- ) }),
48099
- (parsed.metadata.compatibility || parsed.metadata["allowed-tools"] || parsed.metadata.metadata) && /* @__PURE__ */ jsxs(
48100
- "div",
48101
- {
48102
- style: {
48103
- width: "300px",
48104
- flexShrink: 0,
48105
- padding: theme2.space[3],
48106
- background: theme2.colors.background,
48107
- position: "sticky",
48108
- top: theme2.space[3]
48109
- },
48110
- children: [
48111
- parsed.metadata.compatibility && /* @__PURE__ */ jsxs("div", { style: { marginBottom: theme2.space[3] }, children: [
48112
- /* @__PURE__ */ jsx(
48113
- "div",
48114
- {
48115
- style: {
48116
- fontFamily: theme2.fonts.heading,
48117
- fontWeight: 600,
48118
- fontSize: theme2.fontSizes[0],
48119
- textTransform: "uppercase",
48120
- letterSpacing: "0.5px",
48121
- color: theme2.colors.textSecondary,
48122
- marginBottom: theme2.space[1]
48123
- },
48124
- children: "Compatibility"
48125
- }
48126
- ),
48127
- /* @__PURE__ */ jsx("div", { style: { fontSize: theme2.fontSizes[1], color: theme2.colors.text, fontFamily: theme2.fonts.body }, children: parsed.metadata.compatibility })
48128
- ] }),
48129
- parsed.metadata["allowed-tools"] && parsed.metadata["allowed-tools"].length > 0 && /* @__PURE__ */ jsxs("div", { style: { marginBottom: theme2.space[3] }, children: [
48130
- /* @__PURE__ */ jsx(
48131
- "div",
48132
- {
48133
- style: {
48134
- fontFamily: theme2.fonts.heading,
48135
- fontWeight: 600,
48136
- fontSize: theme2.fontSizes[0],
48137
- textTransform: "uppercase",
48138
- letterSpacing: "0.5px",
48139
- color: theme2.colors.textSecondary,
48140
- marginBottom: theme2.space[1]
48141
- },
48142
- children: "Allowed Tools"
48143
- }
48144
- ),
48145
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: theme2.space[1] }, children: parsed.metadata["allowed-tools"].map((tool, index2) => /* @__PURE__ */ jsx(
48146
- "span",
48147
- {
48148
- style: {
48149
- display: "inline-block",
48150
- paddingTop: theme2.space[2],
48151
- paddingBottom: theme2.space[2],
48152
- paddingLeft: theme2.space[3],
48153
- paddingRight: theme2.space[3],
48154
- background: theme2.colors.primary,
48155
- color: theme2.colors.background,
48156
- borderRadius: "4px",
48157
- fontSize: theme2.fontSizes[0],
48158
- fontWeight: 500,
48159
- fontFamily: theme2.fonts.monospace
48160
- },
48161
- children: tool
48162
- },
48163
- index2
48164
- )) })
48165
- ] }),
48166
- parsed.metadata.metadata && Object.keys(parsed.metadata.metadata).length > 0 && /* @__PURE__ */ jsxs("div", { children: [
48167
- /* @__PURE__ */ jsx(
48168
- "div",
48169
- {
48170
- style: {
48171
- fontFamily: theme2.fonts.heading,
48172
- fontWeight: 600,
48173
- fontSize: theme2.fontSizes[0],
48174
- textTransform: "uppercase",
48175
- letterSpacing: "0.5px",
48176
- color: theme2.colors.textSecondary,
48177
- marginBottom: theme2.space[1]
48178
- },
48179
- children: "Metadata"
48180
- }
48181
- ),
48182
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: theme2.space[1] }, children: Object.entries(parsed.metadata.metadata).filter(([key]) => key !== "last-updated").map(([key, value]) => /* @__PURE__ */ jsxs("div", { children: [
48183
- /* @__PURE__ */ jsxs(
48184
- "div",
48185
- {
48186
- style: {
48187
- fontSize: theme2.fontSizes[0],
48188
- fontWeight: 600,
48189
- color: theme2.colors.textSecondary,
48190
- fontFamily: theme2.fonts.body
48191
- },
48192
- children: [
48193
- key,
48194
- ":"
48195
- ]
48196
- }
48197
- ),
48198
- /* @__PURE__ */ jsx(
48199
- "div",
48200
- {
48201
- style: {
48202
- fontSize: theme2.fontSizes[1],
48203
- color: theme2.colors.text,
48204
- fontFamily: theme2.fonts.monospace
48205
- },
48206
- children: value
48207
- }
48208
- )
48209
- ] }, key)) })
48210
- ] })
48211
- ]
48212
- }
48213
- )
48214
- ] }) })
48738
+ ) })
48739
+ ] })
48215
48740
  ]
48216
48741
  }
48217
48742
  );
@@ -48366,7 +48891,8 @@ const SkillDetailPanel = ({
48366
48891
  scriptFiles: skill.scriptFiles,
48367
48892
  referenceFiles: skill.referenceFiles,
48368
48893
  assetFiles: skill.assetFiles
48369
- }
48894
+ },
48895
+ skill
48370
48896
  }
48371
48897
  ) }) }) : /* @__PURE__ */ jsx(
48372
48898
  "div",