@industry-theme/agent-panels 0.2.22 → 0.2.23

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/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  import { type SkillsListPanelProps } from './panels/SkillsListPanel';
2
+ import { SkillsBrowsePanel } from './panels/SkillsBrowsePanel';
2
3
  import { type SkillDetailPanelProps } from './panels/SkillDetailPanel';
3
4
  import type { PanelDefinition } from './types';
4
5
  import type { Skill } from './panels/skills/hooks/useSkillsData';
5
6
  export type { SkillsListPanelProps, SkillDetailPanelProps, Skill };
7
+ export { SkillsBrowsePanel };
6
8
  /**
7
9
  * Export array of panel definitions.
8
10
  * This is the required export for panel extensions.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACtF,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGzF,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,SAAS,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAGjE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,eAAe,EA6GnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,qBAGzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,qBAG3B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGzF,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,SAAS,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAGjE,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,eAAe,EAwInC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,qBAGzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,qBAG3B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import type { PanelComponentProps } from '../types';
3
+ /**
4
+ * SkillsBrowsePanel - A panel for browsing Agent Skills from GitHub repositories
5
+ *
6
+ * This panel shows:
7
+ * - List/grid of available skills from a GitHub repository
8
+ * - Search functionality to filter skills
9
+ * - Skill metadata (name, description, capabilities)
10
+ * - Click to select and emit events for detail views
11
+ *
12
+ * Note: This panel does NOT show global/installed skills - it's specifically for browsing remote repositories
13
+ */
14
+ export declare const SkillsBrowsePanel: React.FC<PanelComponentProps>;
15
+ //# sourceMappingURL=SkillsBrowsePanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SkillsBrowsePanel.d.ts","sourceRoot":"","sources":["../../src/panels/SkillsBrowsePanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAKpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA4V3D,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { PanelContextValue } from '../../../types';
2
+ import type { Skill } from './useSkillsData';
3
+ interface UseSkillsBrowseDataParams {
4
+ context: PanelContextValue;
5
+ }
6
+ interface UseSkillsBrowseDataReturn {
7
+ skills: Skill[];
8
+ isLoading: boolean;
9
+ error: string | null;
10
+ refreshSkills: () => Promise<void>;
11
+ }
12
+ /**
13
+ * Hook to discover and read SKILL.md files from GitHub repositories
14
+ * This hook is specifically for browse mode and does NOT include global skills
15
+ */
16
+ export declare const useSkillsBrowseData: ({ context, }: UseSkillsBrowseDataParams) => UseSkillsBrowseDataReturn;
17
+ export {};
18
+ //# sourceMappingURL=useSkillsBrowseData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSkillsBrowseData.d.ts","sourceRoot":"","sources":["../../../../src/panels/skills/hooks/useSkillsBrowseData.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAS7C,UAAU,yBAAyB;IACjC,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,UAAU,yBAAyB;IACjC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,cAEjC,yBAAyB,KAAG,yBAgG9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSkillsData.d.ts","sourceRoot":"","sources":["../../../../src/panels/skills/hooks/useSkillsData.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,MAAM,WAAW,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,eAAe,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE5B,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAEzC,qBAAqB,EAAE,qBAAqB,CAAC;CAC9C;AAKD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAsXD;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,cAE3B,mBAAmB,KAAG,mBAwHxB,CAAC"}
1
+ {"version":3,"file":"useSkillsData.d.ts","sourceRoot":"","sources":["../../../../src/panels/skills/hooks/useSkillsData.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AASxD,MAAM,MAAM,WAAW,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,eAAe,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE5B,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAEzC,qBAAqB,EAAE,qBAAqB,CAAC;CAC9C;AAKD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,UAAU,mBAAmB;IAC3B,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAqHD;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,cAE3B,mBAAmB,KAAG,mBAwHxB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { FileTree } from '@principal-ai/repository-abstraction';
2
+ import type { Skill, SkillSource, FrontmatterValidation } from '../hooks/useSkillsData';
3
+ /**
4
+ * Helper function to determine skill source and priority from path
5
+ */
6
+ export declare const determineSkillSource: (path: string) => {
7
+ source: SkillSource;
8
+ priority: 1 | 2 | 3 | 4 | 5;
9
+ };
10
+ /**
11
+ * Helper function to find skill markdown files from the FileTree's allFiles array
12
+ * Looks for any .md files in .agent/skills/ or .claude/skills/ directories (local mode)
13
+ * or SKILL.md files anywhere in the tree (browser mode for GitHub repositories)
14
+ */
15
+ export declare const findSkillFiles: (fileTree: FileTree, isBrowserMode?: boolean) => string[];
16
+ /**
17
+ * Helper function to analyze skill folder structure
18
+ */
19
+ export declare const analyzeSkillStructure: (fileTree: FileTree, skillPath: string) => {
20
+ skillFolderPath: string;
21
+ hasScripts: boolean;
22
+ hasReferences: boolean;
23
+ hasAssets: boolean;
24
+ scriptFiles: string[];
25
+ referenceFiles: string[];
26
+ assetFiles: string[];
27
+ };
28
+ /**
29
+ * Helper function to validate YAML frontmatter structure and required fields
30
+ * Now validates gracefully - considers skills valid even with missing required fields
31
+ */
32
+ export declare const validateFrontmatter: (content: string) => FrontmatterValidation;
33
+ /**
34
+ * Helper function to parse skill markdown content and extract metadata
35
+ */
36
+ export declare const parseSkillContent: (content: string, path: string, fileTree: FileTree, fileSystemAdapter?: any, isBrowserMode?: boolean) => Promise<Skill>;
37
+ //# sourceMappingURL=skillsUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillsUtils.d.ts","sourceRoot":"","sources":["../../../../src/panels/skills/utils/skillsUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAExF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,KAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;CAWrG,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,QAAQ,EAAE,gBAAe,OAAe,KAAG,MAAM,EAyBzF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,QAAQ,EAAE,WAAW,MAAM;;;;;;;;CAkD1E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,KAAG,qBAgErD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,UAAU,QAAQ,EAClB,oBAAoB,GAAG,EACvB,gBAAe,OAAe,KAC7B,OAAO,CAAC,KAAK,CA2Ef,CAAC"}
@@ -2618,7 +2618,6 @@ const __iconNode = [
2618
2618
  ]
2619
2619
  ];
2620
2620
  const Zap = createLucideIcon("zap", __iconNode);
2621
- const EMPTY_SKILLS_ARRAY = [];
2622
2621
  const determineSkillSource = (path2) => {
2623
2622
  if (path2.includes(".agent/skills/")) {
2624
2623
  return { source: "project-universal", priority: 1 };
@@ -2758,15 +2757,15 @@ const parseSkillContent = async (content2, path2, fileTree, fileSystemAdapter, i
2758
2757
  }
2759
2758
  const structure = analyzeSkillStructure(fileTree, path2);
2760
2759
  const { source: source2, priority } = determineSkillSource(path2);
2761
- let metadata;
2760
+ let metadata = void 0;
2762
2761
  if (!isBrowserMode && fileSystemAdapter && structure.skillFolderPath) {
2763
2762
  try {
2764
2763
  const metadataPath = `${structure.skillFolderPath}/.metadata.json`;
2765
2764
  const metadataContent = await fileSystemAdapter.readFile(metadataPath);
2766
2765
  metadata = JSON.parse(metadataContent);
2767
- console.log("[useSkillsData] Loaded metadata for skill:", skillDirName, metadata);
2766
+ console.log("[skillsUtils] Loaded metadata for skill:", skillDirName, metadata);
2768
2767
  } catch (error) {
2769
- console.debug("[useSkillsData] No metadata file for skill:", skillDirName);
2768
+ console.debug("[skillsUtils] No metadata file for skill:", skillDirName);
2770
2769
  }
2771
2770
  }
2772
2771
  const frontmatterValidation = validateFrontmatter(content2);
@@ -2785,6 +2784,7 @@ const parseSkillContent = async (content2, path2, fileTree, fileSystemAdapter, i
2785
2784
  frontmatterValidation
2786
2785
  };
2787
2786
  };
2787
+ const EMPTY_SKILLS_ARRAY$1 = [];
2788
2788
  const getDeduplicationKey = (skill) => {
2789
2789
  var _a, _b, _c;
2790
2790
  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)) {
@@ -2859,14 +2859,14 @@ const useSkillsData = ({
2859
2859
  context
2860
2860
  }) => {
2861
2861
  var _a, _b, _c;
2862
- const [skills, setSkills] = useState(EMPTY_SKILLS_ARRAY);
2862
+ const [skills, setSkills] = useState(EMPTY_SKILLS_ARRAY$1);
2863
2863
  const [isLoading, setIsLoading] = useState(true);
2864
2864
  const [error, setError] = useState(null);
2865
2865
  const fileTreeSlice = context.getSlice("fileTree");
2866
2866
  const fileTree = fileTreeSlice == null ? void 0 : fileTreeSlice.data;
2867
2867
  const fileTreeSha = fileTree == null ? void 0 : fileTree.sha;
2868
2868
  const globalSkillsSlice = context.getSlice("globalSkills");
2869
- const globalSkills = ((_a = globalSkillsSlice == null ? void 0 : globalSkillsSlice.data) == null ? void 0 : _a.skills) ?? EMPTY_SKILLS_ARRAY;
2869
+ const globalSkills = ((_a = globalSkillsSlice == null ? void 0 : globalSkillsSlice.data) == null ? void 0 : _a.skills) ?? EMPTY_SKILLS_ARRAY$1;
2870
2870
  const globalSkillsCount = globalSkills.length;
2871
2871
  const repoPath = (_b = context.currentScope.repository) == null ? void 0 : _b.path;
2872
2872
  const fileSystem = (_c = context.adapters) == null ? void 0 : _c.fileSystem;
@@ -3779,6 +3779,425 @@ const SkillsListPanel = ({
3779
3779
  }
3780
3780
  );
3781
3781
  };
3782
+ const EMPTY_SKILLS_ARRAY = [];
3783
+ const useSkillsBrowseData = ({
3784
+ context
3785
+ }) => {
3786
+ var _a, _b;
3787
+ const [skills, setSkills] = useState(EMPTY_SKILLS_ARRAY);
3788
+ const [isLoading, setIsLoading] = useState(true);
3789
+ const [error, setError] = useState(null);
3790
+ const fileTreeSlice = context.getSlice("fileTree");
3791
+ const fileTree = fileTreeSlice == null ? void 0 : fileTreeSlice.data;
3792
+ const fileTreeSha = fileTree == null ? void 0 : fileTree.sha;
3793
+ const repoPath = (_a = context.currentScope.repository) == null ? void 0 : _a.path;
3794
+ const fileSystem = (_b = context.adapters) == null ? void 0 : _b.fileSystem;
3795
+ const lastLoadedSha = useRef(void 0);
3796
+ const loadSkills = useCallback(async () => {
3797
+ if (fileTreeSha === lastLoadedSha.current) {
3798
+ console.log("[useSkillsBrowseData] Skipping reload - data unchanged (SHA:", fileTreeSha, ")");
3799
+ return;
3800
+ }
3801
+ console.log("[useSkillsBrowseData] Loading skills from GitHub repo - SHA:", fileTreeSha);
3802
+ setIsLoading(true);
3803
+ setError(null);
3804
+ try {
3805
+ let repoSkills = [];
3806
+ if (fileTree && (fileSystem == null ? void 0 : fileSystem.readFile) && repoPath) {
3807
+ const isGithubRepo = !repoPath.startsWith("/");
3808
+ if (!isGithubRepo) {
3809
+ console.warn("[useSkillsBrowseData] Not a GitHub repo, skipping skill load");
3810
+ setSkills(EMPTY_SKILLS_ARRAY);
3811
+ lastLoadedSha.current = fileTreeSha;
3812
+ setIsLoading(false);
3813
+ return;
3814
+ }
3815
+ console.log("[useSkillsBrowseData] GitHub repo detected:", repoPath);
3816
+ const skillPaths = findSkillFiles(fileTree, true);
3817
+ console.log("[useSkillsBrowseData] Found skill paths:", skillPaths);
3818
+ const skillPromises = skillPaths.map(async (skillPath) => {
3819
+ try {
3820
+ const content2 = await fileSystem.readFile(skillPath);
3821
+ return parseSkillContent(content2, skillPath, fileTree, fileSystem, true);
3822
+ } catch (err) {
3823
+ console.error(`[useSkillsBrowseData] Failed to read skill at ${skillPath}:`, err);
3824
+ return null;
3825
+ }
3826
+ });
3827
+ repoSkills = (await Promise.all(skillPromises)).filter(
3828
+ (skill) => skill !== null
3829
+ );
3830
+ }
3831
+ console.log("[useSkillsBrowseData] Total skills loaded:", repoSkills.length);
3832
+ setSkills(repoSkills);
3833
+ lastLoadedSha.current = fileTreeSha;
3834
+ } catch (err) {
3835
+ const errorMessage = err instanceof Error ? err.message : "Failed to load skills";
3836
+ setError(errorMessage);
3837
+ console.error("[useSkillsBrowseData] Error loading skills:", err);
3838
+ } finally {
3839
+ setIsLoading(false);
3840
+ }
3841
+ }, [fileTree, fileTreeSha, repoPath, fileSystem]);
3842
+ const refreshSkills = useCallback(async () => {
3843
+ lastLoadedSha.current = void 0;
3844
+ await loadSkills();
3845
+ }, [loadSkills]);
3846
+ useEffect(() => {
3847
+ loadSkills();
3848
+ }, [loadSkills]);
3849
+ return {
3850
+ skills,
3851
+ isLoading,
3852
+ error,
3853
+ refreshSkills
3854
+ };
3855
+ };
3856
+ const SkillsBrowsePanel = ({
3857
+ context,
3858
+ events
3859
+ }) => {
3860
+ const { theme: theme2 } = useTheme();
3861
+ const panelRef = useRef(null);
3862
+ const [selectedSkillId, setSelectedSkillId] = useState(null);
3863
+ const [searchQuery, setSearchQuery] = useState("");
3864
+ const [isRefreshing, setIsRefreshing] = useState(false);
3865
+ const { skills, isLoading, error, refreshSkills } = useSkillsBrowseData({ context });
3866
+ gt("skills-browse", events, () => {
3867
+ var _a;
3868
+ return (_a = panelRef.current) == null ? void 0 : _a.focus();
3869
+ });
3870
+ useEffect(() => {
3871
+ const unsubscribeInstalled = events.on("skill:installed", () => {
3872
+ console.log("[SkillsBrowsePanel] Skill installed, refreshing...");
3873
+ refreshSkills();
3874
+ });
3875
+ const unsubscribeUninstalled = events.on("skill:uninstalled", () => {
3876
+ console.log("[SkillsBrowsePanel] Skill uninstalled, refreshing...");
3877
+ refreshSkills();
3878
+ });
3879
+ return () => {
3880
+ unsubscribeInstalled();
3881
+ unsubscribeUninstalled();
3882
+ };
3883
+ }, [events, refreshSkills]);
3884
+ const filteredSkills = useMemo(() => {
3885
+ let filtered = skills;
3886
+ if (searchQuery.trim()) {
3887
+ const query = searchQuery.toLowerCase().trim();
3888
+ filtered = filtered.filter((skill) => {
3889
+ var _a, _b;
3890
+ if (skill.name.toLowerCase().includes(query)) return true;
3891
+ if ((_a = skill.description) == null ? void 0 : _a.toLowerCase().includes(query)) return true;
3892
+ if ((_b = skill.capabilities) == null ? void 0 : _b.some((cap2) => cap2.toLowerCase().includes(query)))
3893
+ return true;
3894
+ if (skill.path.toLowerCase().includes(query)) return true;
3895
+ return false;
3896
+ });
3897
+ }
3898
+ return filtered;
3899
+ }, [skills, searchQuery]);
3900
+ const handleSkillClick = (skill) => {
3901
+ setSelectedSkillId(skill.id);
3902
+ if (events) {
3903
+ events.emit({
3904
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3905
+ type: "skill:selected",
3906
+ source: "skills-browse-panel",
3907
+ timestamp: Date.now(),
3908
+ payload: { skillId: skill.id, skill }
3909
+ });
3910
+ }
3911
+ };
3912
+ const handleRefresh = async () => {
3913
+ setIsRefreshing(true);
3914
+ if (events) {
3915
+ events.emit({
3916
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3917
+ type: "skills:refresh",
3918
+ source: "skills-browse-panel",
3919
+ timestamp: Date.now(),
3920
+ payload: {}
3921
+ });
3922
+ }
3923
+ try {
3924
+ await refreshSkills();
3925
+ } finally {
3926
+ setIsRefreshing(false);
3927
+ }
3928
+ };
3929
+ return /* @__PURE__ */ jsxs(
3930
+ "div",
3931
+ {
3932
+ ref: panelRef,
3933
+ tabIndex: -1,
3934
+ style: {
3935
+ padding: "clamp(12px, 3vw, 20px)",
3936
+ fontFamily: theme2.fonts.body,
3937
+ height: "100%",
3938
+ boxSizing: "border-box",
3939
+ display: "flex",
3940
+ flexDirection: "column",
3941
+ gap: "16px",
3942
+ overflow: "hidden",
3943
+ backgroundColor: theme2.colors.background,
3944
+ color: theme2.colors.text,
3945
+ outline: "none"
3946
+ },
3947
+ children: [
3948
+ /* @__PURE__ */ jsxs(
3949
+ "div",
3950
+ {
3951
+ style: {
3952
+ flexShrink: 0,
3953
+ display: "flex",
3954
+ alignItems: "center",
3955
+ justifyContent: "space-between",
3956
+ gap: "12px",
3957
+ flexWrap: "wrap"
3958
+ },
3959
+ children: [
3960
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [
3961
+ /* @__PURE__ */ jsx(
3962
+ "h2",
3963
+ {
3964
+ style: {
3965
+ margin: 0,
3966
+ fontSize: theme2.fontSizes[4],
3967
+ color: theme2.colors.text
3968
+ },
3969
+ children: /* @__PURE__ */ jsx(
3970
+ "a",
3971
+ {
3972
+ href: "https://agentskills.io/",
3973
+ target: "_blank",
3974
+ rel: "noopener noreferrer",
3975
+ style: {
3976
+ color: "inherit",
3977
+ textDecoration: "none"
3978
+ },
3979
+ onMouseEnter: (e) => e.currentTarget.style.textDecoration = "underline",
3980
+ onMouseLeave: (e) => e.currentTarget.style.textDecoration = "none",
3981
+ children: "Browse Skills"
3982
+ }
3983
+ )
3984
+ }
3985
+ ),
3986
+ !isLoading && /* @__PURE__ */ jsxs(
3987
+ "span",
3988
+ {
3989
+ style: {
3990
+ fontSize: theme2.fontSizes[1],
3991
+ color: theme2.colors.textSecondary,
3992
+ background: theme2.colors.backgroundSecondary,
3993
+ padding: "4px 10px",
3994
+ borderRadius: theme2.radii[1]
3995
+ },
3996
+ children: [
3997
+ filteredSkills.length,
3998
+ " ",
3999
+ filteredSkills.length === 1 ? "skill" : "skills"
4000
+ ]
4001
+ }
4002
+ )
4003
+ ] }),
4004
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px", flex: "1 1 200px", maxWidth: "400px" }, children: [
4005
+ /* @__PURE__ */ jsxs(
4006
+ "div",
4007
+ {
4008
+ style: {
4009
+ position: "relative",
4010
+ flex: 1,
4011
+ minWidth: "150px"
4012
+ },
4013
+ children: [
4014
+ /* @__PURE__ */ jsx(
4015
+ Search,
4016
+ {
4017
+ size: 16,
4018
+ color: theme2.colors.textSecondary,
4019
+ style: {
4020
+ position: "absolute",
4021
+ left: "10px",
4022
+ top: "50%",
4023
+ transform: "translateY(-50%)",
4024
+ pointerEvents: "none"
4025
+ }
4026
+ }
4027
+ ),
4028
+ /* @__PURE__ */ jsx(
4029
+ "input",
4030
+ {
4031
+ type: "text",
4032
+ placeholder: "Search skills...",
4033
+ value: searchQuery,
4034
+ onChange: (e) => setSearchQuery(e.target.value),
4035
+ style: {
4036
+ width: "100%",
4037
+ padding: "8px 32px 8px 32px",
4038
+ fontSize: theme2.fontSizes[1],
4039
+ fontFamily: theme2.fonts.body,
4040
+ border: `1px solid ${theme2.colors.border}`,
4041
+ borderRadius: theme2.radii[2],
4042
+ background: theme2.colors.backgroundSecondary,
4043
+ color: theme2.colors.text,
4044
+ outline: "none",
4045
+ boxSizing: "border-box"
4046
+ }
4047
+ }
4048
+ ),
4049
+ searchQuery && /* @__PURE__ */ jsx(
4050
+ "button",
4051
+ {
4052
+ onClick: () => setSearchQuery(""),
4053
+ style: {
4054
+ position: "absolute",
4055
+ right: "6px",
4056
+ top: "50%",
4057
+ transform: "translateY(-50%)",
4058
+ background: "transparent",
4059
+ border: "none",
4060
+ padding: "4px",
4061
+ cursor: "pointer",
4062
+ display: "flex",
4063
+ alignItems: "center",
4064
+ justifyContent: "center",
4065
+ color: theme2.colors.textSecondary
4066
+ },
4067
+ "aria-label": "Clear search",
4068
+ children: /* @__PURE__ */ jsx(X, { size: 14 })
4069
+ }
4070
+ )
4071
+ ]
4072
+ }
4073
+ ),
4074
+ /* @__PURE__ */ jsx(
4075
+ "button",
4076
+ {
4077
+ onClick: handleRefresh,
4078
+ disabled: isRefreshing || isLoading,
4079
+ style: {
4080
+ background: theme2.colors.backgroundSecondary,
4081
+ border: `1px solid ${theme2.colors.border}`,
4082
+ borderRadius: theme2.radii[1],
4083
+ padding: "8px",
4084
+ cursor: isRefreshing ? "wait" : "pointer",
4085
+ display: "flex",
4086
+ alignItems: "center",
4087
+ justifyContent: "center",
4088
+ transition: "all 0.2s ease"
4089
+ },
4090
+ title: "Refresh skills",
4091
+ children: /* @__PURE__ */ jsx(
4092
+ RefreshCw,
4093
+ {
4094
+ size: 16,
4095
+ color: theme2.colors.textSecondary,
4096
+ style: {
4097
+ animation: isRefreshing ? "spin 1s linear infinite" : "none"
4098
+ }
4099
+ }
4100
+ )
4101
+ }
4102
+ )
4103
+ ] })
4104
+ ]
4105
+ }
4106
+ ),
4107
+ error && /* @__PURE__ */ jsxs(
4108
+ "div",
4109
+ {
4110
+ style: {
4111
+ flexShrink: 0,
4112
+ padding: "12px",
4113
+ background: `${theme2.colors.error}20`,
4114
+ border: `1px solid ${theme2.colors.error}`,
4115
+ borderRadius: theme2.radii[2],
4116
+ display: "flex",
4117
+ alignItems: "center",
4118
+ gap: "8px",
4119
+ color: theme2.colors.error,
4120
+ fontSize: theme2.fontSizes[1]
4121
+ },
4122
+ children: [
4123
+ /* @__PURE__ */ jsx(CircleAlert, { size: 16 }),
4124
+ /* @__PURE__ */ jsx("span", { children: error })
4125
+ ]
4126
+ }
4127
+ ),
4128
+ /* @__PURE__ */ jsx(
4129
+ "div",
4130
+ {
4131
+ style: {
4132
+ flex: 1,
4133
+ overflowY: "auto",
4134
+ minHeight: 0
4135
+ },
4136
+ children: isLoading ? /* @__PURE__ */ jsx(
4137
+ "div",
4138
+ {
4139
+ style: {
4140
+ height: "100%",
4141
+ display: "flex",
4142
+ alignItems: "center",
4143
+ justifyContent: "center",
4144
+ color: theme2.colors.textSecondary,
4145
+ fontSize: theme2.fontSizes[2]
4146
+ },
4147
+ children: "Loading skills from repository..."
4148
+ }
4149
+ ) : filteredSkills.length === 0 ? /* @__PURE__ */ jsxs(
4150
+ "div",
4151
+ {
4152
+ style: {
4153
+ height: "100%",
4154
+ display: "flex",
4155
+ flexDirection: "column",
4156
+ alignItems: "center",
4157
+ justifyContent: "center",
4158
+ gap: "16px",
4159
+ color: theme2.colors.textSecondary,
4160
+ padding: "24px"
4161
+ },
4162
+ children: [
4163
+ /* @__PURE__ */ jsx(FileCode, { size: 48, color: theme2.colors.border }),
4164
+ /* @__PURE__ */ jsxs("div", { style: { textAlign: "center" }, children: [
4165
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: theme2.fontSizes[2] }, children: searchQuery ? "No skills match your search" : "No skills found in this repository" }),
4166
+ /* @__PURE__ */ jsx("p", { style: { margin: "8px 0 0 0", fontSize: theme2.fontSizes[1] }, children: searchQuery ? "Try a different search term" : "This repository does not contain any SKILL.md files" })
4167
+ ] })
4168
+ ]
4169
+ }
4170
+ ) : /* @__PURE__ */ jsx(
4171
+ "div",
4172
+ {
4173
+ style: {
4174
+ display: "grid",
4175
+ gridTemplateColumns: "repeat(auto-fill, minmax(250px, 1fr))",
4176
+ gap: "16px",
4177
+ padding: "4px"
4178
+ },
4179
+ children: filteredSkills.map((skill) => /* @__PURE__ */ jsx(
4180
+ SkillCard,
4181
+ {
4182
+ skill,
4183
+ onClick: handleSkillClick,
4184
+ isSelected: selectedSkillId === skill.id
4185
+ },
4186
+ skill.id
4187
+ ))
4188
+ }
4189
+ )
4190
+ }
4191
+ ),
4192
+ /* @__PURE__ */ jsx("style", { children: `
4193
+ @keyframes spin {
4194
+ to { transform: rotate(360deg); }
4195
+ }
4196
+ ` })
4197
+ ]
4198
+ }
4199
+ );
4200
+ };
3782
4201
  var MarkdownSourceType$1;
3783
4202
  ((MarkdownSourceType2) => {
3784
4203
  MarkdownSourceType2["WORKSPACE_FILE"] = "workspace_file";
@@ -51051,6 +51470,31 @@ const panels = [
51051
51470
  console.log("Skills List Panel unmounting");
51052
51471
  }
51053
51472
  },
51473
+ {
51474
+ metadata: {
51475
+ id: "industry-theme.skills-browse",
51476
+ name: "Browse Skills",
51477
+ icon: "🔍",
51478
+ version: "0.1.0",
51479
+ author: "Principal ADE",
51480
+ description: "Browse Agent Skills from GitHub repositories",
51481
+ slices: ["fileTree"]
51482
+ // Only needs fileTree, not globalSkills
51483
+ },
51484
+ component: SkillsBrowsePanel,
51485
+ // Optional: Called when this specific panel is mounted
51486
+ onMount: async (context) => {
51487
+ var _a;
51488
+ console.log(
51489
+ "Skills Browse Panel mounted",
51490
+ (_a = context.currentScope.repository) == null ? void 0 : _a.path
51491
+ );
51492
+ },
51493
+ // Optional: Called when this specific panel is unmounted
51494
+ onUnmount: async (_context) => {
51495
+ console.log("Skills Browse Panel unmounting");
51496
+ }
51497
+ },
51054
51498
  {
51055
51499
  metadata: {
51056
51500
  id: "industry-theme.skill-detail",
@@ -51134,6 +51578,7 @@ const onPackageUnload = async () => {
51134
51578
  console.log("Panel package unloading - Agent Panels Extension");
51135
51579
  };
51136
51580
  export {
51581
+ SkillsBrowsePanel,
51137
51582
  onPackageLoad,
51138
51583
  onPackageUnload,
51139
51584
  panels