@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 +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/panels/SkillsBrowsePanel.d.ts +15 -0
- package/dist/panels/SkillsBrowsePanel.d.ts.map +1 -0
- package/dist/panels/skills/hooks/useSkillsBrowseData.d.ts +18 -0
- package/dist/panels/skills/hooks/useSkillsBrowseData.d.ts.map +1 -0
- package/dist/panels/skills/hooks/useSkillsData.d.ts.map +1 -1
- package/dist/panels/skills/utils/skillsUtils.d.ts +37 -0
- package/dist/panels/skills/utils/skillsUtils.d.ts.map +1 -0
- package/dist/panels.bundle.js +451 -6
- package/dist/panels.bundle.js.map +1 -1
- package/package.json +1 -1
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.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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;
|
|
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"}
|
package/dist/panels.bundle.js
CHANGED
|
@@ -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("[
|
|
2766
|
+
console.log("[skillsUtils] Loaded metadata for skill:", skillDirName, metadata);
|
|
2768
2767
|
} catch (error) {
|
|
2769
|
-
console.debug("[
|
|
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
|