@forwardimpact/pathway 0.17.0 → 0.17.1
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/package.json
CHANGED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Card Component
|
|
3
|
+
*
|
|
4
|
+
* Unified card component for displaying one or more files with collapsible
|
|
5
|
+
* code panes. Replaces separate agent-card and skill-card patterns with a
|
|
6
|
+
* single bordered surface containing a header and accordion file panes.
|
|
7
|
+
*
|
|
8
|
+
* One component, one DOM pattern, one set of styles.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/* global Prism */
|
|
12
|
+
import { div, span } from "../lib/render.js";
|
|
13
|
+
import { createCopyButton } from "./code-display.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} FileDescriptor
|
|
17
|
+
* @property {string} filename - Display filename for the pane summary
|
|
18
|
+
* @property {string} content - File content to display
|
|
19
|
+
* @property {string} [language="markdown"] - Syntax highlighting language
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Create a file card with header and collapsible file panes.
|
|
24
|
+
*
|
|
25
|
+
* Agent card = createFileCard with 1 file (1 pane, open).
|
|
26
|
+
* Skill card = createFileCard with 1–3 files (accordion).
|
|
27
|
+
*
|
|
28
|
+
* @param {Object} options
|
|
29
|
+
* @param {Array<HTMLElement|string>} options.header - Elements for the card header
|
|
30
|
+
* @param {FileDescriptor[]} options.files - Files to display as collapsible panes
|
|
31
|
+
* @param {number} [options.maxHeight=300] - Max code block height in px
|
|
32
|
+
* @param {number} [options.openIndex=0] - Initially open pane (-1 = all closed)
|
|
33
|
+
* @returns {HTMLElement}
|
|
34
|
+
*/
|
|
35
|
+
export function createFileCard({
|
|
36
|
+
header,
|
|
37
|
+
files,
|
|
38
|
+
maxHeight = 300,
|
|
39
|
+
openIndex = 0,
|
|
40
|
+
}) {
|
|
41
|
+
const card = div(
|
|
42
|
+
{ className: "file-card" },
|
|
43
|
+
div({ className: "file-card-header" }, ...header),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
/** @type {HTMLDetailsElement[]} */
|
|
47
|
+
const panes = [];
|
|
48
|
+
|
|
49
|
+
for (let i = 0; i < files.length; i++) {
|
|
50
|
+
const file = files[i];
|
|
51
|
+
|
|
52
|
+
const details = document.createElement("details");
|
|
53
|
+
details.className = "file-card-pane";
|
|
54
|
+
if (i === openIndex) details.open = true;
|
|
55
|
+
|
|
56
|
+
const summary = document.createElement("summary");
|
|
57
|
+
summary.appendChild(
|
|
58
|
+
span({ className: "file-card-filename" }, file.filename),
|
|
59
|
+
);
|
|
60
|
+
summary.appendChild(
|
|
61
|
+
div({ className: "button-group" }, createCopyButton(file.content)),
|
|
62
|
+
);
|
|
63
|
+
details.appendChild(summary);
|
|
64
|
+
|
|
65
|
+
// Lazy-render code block on first open
|
|
66
|
+
let rendered = false;
|
|
67
|
+
const renderCode = () => {
|
|
68
|
+
if (rendered) return;
|
|
69
|
+
rendered = true;
|
|
70
|
+
const pre = document.createElement("pre");
|
|
71
|
+
pre.className = "code-display";
|
|
72
|
+
if (maxHeight) {
|
|
73
|
+
pre.style.maxHeight = `${maxHeight}px`;
|
|
74
|
+
pre.style.overflowY = "auto";
|
|
75
|
+
}
|
|
76
|
+
const code = document.createElement("code");
|
|
77
|
+
code.className = `language-${file.language || "markdown"}`;
|
|
78
|
+
code.textContent = file.content;
|
|
79
|
+
pre.appendChild(code);
|
|
80
|
+
if (typeof Prism !== "undefined") Prism.highlightElement(code);
|
|
81
|
+
details.appendChild(pre);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
if (i === openIndex) renderCode();
|
|
85
|
+
else
|
|
86
|
+
details.addEventListener("toggle", () => {
|
|
87
|
+
if (details.open) renderCode();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
panes.push(details);
|
|
91
|
+
card.appendChild(details);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Accordion: opening one pane closes others
|
|
95
|
+
for (const pane of panes) {
|
|
96
|
+
pane.addEventListener("toggle", () => {
|
|
97
|
+
if (pane.open) {
|
|
98
|
+
for (const other of panes) {
|
|
99
|
+
if (other !== pane) other.open = false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return card;
|
|
106
|
+
}
|
package/src/css/bundles/app.css
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
@import "../components/top-bar.css" layer(components);
|
|
28
28
|
@import "../components/command-prompt.css" layer(components);
|
|
29
29
|
@import "../components/skill-file-viewer.css" layer(components);
|
|
30
|
+
@import "../components/file-card.css" layer(components);
|
|
30
31
|
|
|
31
32
|
/* Utilities */
|
|
32
33
|
@import "../components/utilities.css" layer(utilities);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Card
|
|
3
|
+
*
|
|
4
|
+
* Unified card surface for displaying files with collapsible panes.
|
|
5
|
+
* Single bordered surface — no nested borders from code-display or wrappers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
@layer components {
|
|
9
|
+
/* The card — single bordered surface */
|
|
10
|
+
.file-card {
|
|
11
|
+
border: 1px solid var(--color-border);
|
|
12
|
+
border-radius: var(--radius-md);
|
|
13
|
+
background: var(--color-surface);
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* Card header — always visible */
|
|
18
|
+
.file-card-header {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
gap: var(--space-sm);
|
|
23
|
+
padding: var(--space-sm) var(--space-md);
|
|
24
|
+
border-bottom: 1px solid var(--color-border);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.file-card-header h3 {
|
|
28
|
+
margin: 0;
|
|
29
|
+
font-size: var(--font-size-md);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* File panes — flush inside card, no chrome */
|
|
33
|
+
.file-card-pane + .file-card-pane {
|
|
34
|
+
border-top: 1px solid var(--color-border);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.file-card-pane > summary {
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
gap: var(--space-sm);
|
|
41
|
+
padding: var(--space-sm) var(--space-md);
|
|
42
|
+
cursor: pointer;
|
|
43
|
+
list-style: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.file-card-pane > summary::-webkit-details-marker {
|
|
47
|
+
display: none;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.file-card-pane > summary::before {
|
|
51
|
+
content: "▸";
|
|
52
|
+
font-size: var(--font-size-xs);
|
|
53
|
+
color: var(--color-text-muted);
|
|
54
|
+
flex-shrink: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.file-card-pane[open] > summary::before {
|
|
58
|
+
content: "▾";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.file-card-filename {
|
|
62
|
+
flex: 1;
|
|
63
|
+
min-width: 0;
|
|
64
|
+
overflow: hidden;
|
|
65
|
+
text-overflow: ellipsis;
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
font-family: var(--font-family-mono);
|
|
68
|
+
font-size: var(--font-size-xs);
|
|
69
|
+
color: var(--color-text-muted);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.file-card-pane > summary .button-group {
|
|
73
|
+
flex-shrink: 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Code block inside file card — no border, no radius, no bg */
|
|
77
|
+
.file-card-pane .code-display {
|
|
78
|
+
border: none;
|
|
79
|
+
border-radius: 0;
|
|
80
|
+
background: transparent;
|
|
81
|
+
margin: 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Header element helpers */
|
|
85
|
+
.file-card-emoji {
|
|
86
|
+
font-size: 1.5rem;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.file-card-title {
|
|
90
|
+
display: flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
gap: var(--space-sm);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.file-card-name {
|
|
96
|
+
font-weight: 600;
|
|
97
|
+
font-size: var(--font-size-sm);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.file-card-badge {
|
|
101
|
+
font-size: var(--font-size-xs);
|
|
102
|
+
color: var(--color-text-muted);
|
|
103
|
+
background: var(--color-bg);
|
|
104
|
+
border: 1px solid var(--color-border);
|
|
105
|
+
border-radius: var(--radius-sm);
|
|
106
|
+
padding: 0.1em 0.5em;
|
|
107
|
+
white-space: nowrap;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent Builder Page Styles
|
|
3
3
|
*
|
|
4
|
-
* Agent builder form, preview, and card
|
|
4
|
+
* Agent builder form, preview, and card grid layout.
|
|
5
|
+
* Card surfaces are in components/file-card.css.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
@layer pages {
|
|
@@ -32,11 +33,9 @@
|
|
|
32
33
|
gap: var(--space-xl);
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
/* Agent section — spacing container, no surface */
|
|
35
37
|
.agent-section {
|
|
36
|
-
|
|
37
|
-
border-radius: var(--radius-lg);
|
|
38
|
-
padding: var(--space-lg);
|
|
39
|
-
box-shadow: var(--shadow-md);
|
|
38
|
+
margin-bottom: var(--space-lg);
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
.agent-section .section-header {
|
|
@@ -50,13 +49,6 @@
|
|
|
50
49
|
margin: 0;
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
.agent-section .filename {
|
|
54
|
-
font-family: var(--font-family-mono);
|
|
55
|
-
font-size: var(--font-size-xs);
|
|
56
|
-
color: var(--color-text-muted);
|
|
57
|
-
margin-bottom: var(--space-sm);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
52
|
/* Agent cards grid */
|
|
61
53
|
.agent-cards-grid {
|
|
62
54
|
display: grid;
|
|
@@ -69,51 +61,6 @@
|
|
|
69
61
|
max-width: 800px;
|
|
70
62
|
}
|
|
71
63
|
|
|
72
|
-
.agent-card {
|
|
73
|
-
border: 1px solid var(--color-border);
|
|
74
|
-
border-radius: var(--radius-lg);
|
|
75
|
-
background: var(--color-bg);
|
|
76
|
-
overflow: hidden;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.agent-card-header {
|
|
80
|
-
display: flex;
|
|
81
|
-
justify-content: space-between;
|
|
82
|
-
align-items: flex-start;
|
|
83
|
-
padding: var(--space-md);
|
|
84
|
-
background: var(--color-surface);
|
|
85
|
-
border-bottom: 1px solid var(--color-border);
|
|
86
|
-
gap: var(--space-sm);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.agent-card-title {
|
|
90
|
-
display: flex;
|
|
91
|
-
align-items: center;
|
|
92
|
-
gap: var(--space-sm);
|
|
93
|
-
flex-wrap: wrap;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.agent-card-title h3 {
|
|
97
|
-
margin: 0;
|
|
98
|
-
font-size: var(--font-size-md);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.agent-card-emoji {
|
|
102
|
-
font-size: 1.5rem;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.agent-card-preview {
|
|
106
|
-
padding: var(--space-md);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.agent-card-preview .code-display-pane {
|
|
110
|
-
margin: 0;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.agent-card-preview .code-display {
|
|
114
|
-
max-height: 400px;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
64
|
/* Skill cards grid */
|
|
118
65
|
.skill-cards-grid {
|
|
119
66
|
display: grid;
|
|
@@ -121,50 +68,6 @@
|
|
|
121
68
|
gap: var(--space-md);
|
|
122
69
|
}
|
|
123
70
|
|
|
124
|
-
.skill-card {
|
|
125
|
-
border: 1px solid var(--color-border);
|
|
126
|
-
border-radius: var(--radius-md);
|
|
127
|
-
background: var(--color-bg);
|
|
128
|
-
overflow: hidden;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.skill-card-header {
|
|
132
|
-
display: flex;
|
|
133
|
-
justify-content: space-between;
|
|
134
|
-
align-items: center;
|
|
135
|
-
padding: var(--space-sm) var(--space-md);
|
|
136
|
-
background: var(--color-surface);
|
|
137
|
-
border-bottom: 1px solid var(--color-border);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.skill-card-name {
|
|
141
|
-
font-weight: 600;
|
|
142
|
-
font-size: var(--font-size-sm);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.skill-card-preview {
|
|
146
|
-
padding: var(--space-sm) var(--space-md) var(--space-md);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.skill-card-preview .code-display-pane {
|
|
150
|
-
margin: 0;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.skill-card-preview .code-display {
|
|
154
|
-
max-height: 300px;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/* Skill card file count badge */
|
|
158
|
-
.skill-card-badge {
|
|
159
|
-
font-size: var(--font-size-xs);
|
|
160
|
-
color: var(--color-text-muted);
|
|
161
|
-
background: var(--color-surface);
|
|
162
|
-
border: 1px solid var(--color-border);
|
|
163
|
-
border-radius: var(--radius-sm);
|
|
164
|
-
padding: 0.1em 0.5em;
|
|
165
|
-
white-space: nowrap;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
71
|
.skills-list {
|
|
169
72
|
display: flex;
|
|
170
73
|
flex-direction: column;
|
|
@@ -42,8 +42,7 @@ import {
|
|
|
42
42
|
formatInstallScript,
|
|
43
43
|
formatReference,
|
|
44
44
|
} from "../formatters/agent/skill.js";
|
|
45
|
-
import {
|
|
46
|
-
import { createSkillFileViewer } from "../components/skill-file-viewer.js";
|
|
45
|
+
import { createFileCard } from "../components/file-card.js";
|
|
47
46
|
import { createToolkitTable } from "../formatters/toolkit/dom.js";
|
|
48
47
|
import { createDetailSection } from "../components/detail.js";
|
|
49
48
|
|
|
@@ -537,9 +536,24 @@ function createAllStagesPreview(context) {
|
|
|
537
536
|
),
|
|
538
537
|
div(
|
|
539
538
|
{ className: "agent-cards-grid" },
|
|
540
|
-
...stageAgents.map(({ stage, profile }) =>
|
|
541
|
-
|
|
542
|
-
|
|
539
|
+
...stageAgents.map(({ stage, profile }) => {
|
|
540
|
+
const content = formatAgentProfile(profile, templates.agent);
|
|
541
|
+
const stageEmoji = getStageEmoji(stages, stage.id);
|
|
542
|
+
return createFileCard({
|
|
543
|
+
header: [
|
|
544
|
+
span({ className: "file-card-emoji" }, stageEmoji),
|
|
545
|
+
h3({}, `${stage.name} Agent`),
|
|
546
|
+
],
|
|
547
|
+
files: [
|
|
548
|
+
{
|
|
549
|
+
filename: profile.filename,
|
|
550
|
+
content,
|
|
551
|
+
language: "markdown",
|
|
552
|
+
},
|
|
553
|
+
],
|
|
554
|
+
maxHeight: 400,
|
|
555
|
+
});
|
|
556
|
+
}),
|
|
543
557
|
),
|
|
544
558
|
),
|
|
545
559
|
|
|
@@ -550,7 +564,7 @@ function createAllStagesPreview(context) {
|
|
|
550
564
|
skillFiles.length > 0
|
|
551
565
|
? div(
|
|
552
566
|
{ className: "skill-cards-grid" },
|
|
553
|
-
...skillFiles.map((skill) =>
|
|
567
|
+
...skillFiles.map((skill) => buildSkillFileCard(skill, templates)),
|
|
554
568
|
)
|
|
555
569
|
: p(
|
|
556
570
|
{ className: "text-muted" },
|
|
@@ -591,20 +605,6 @@ function createSingleStagePreview(context, stage) {
|
|
|
591
605
|
agentIndex,
|
|
592
606
|
} = context;
|
|
593
607
|
|
|
594
|
-
// Derive stage agent
|
|
595
|
-
const derived = deriveStageAgent({
|
|
596
|
-
discipline: humanDiscipline,
|
|
597
|
-
track: humanTrack,
|
|
598
|
-
stage,
|
|
599
|
-
grade,
|
|
600
|
-
skills,
|
|
601
|
-
behaviours,
|
|
602
|
-
agentBehaviours,
|
|
603
|
-
agentDiscipline,
|
|
604
|
-
agentTrack,
|
|
605
|
-
stages,
|
|
606
|
-
});
|
|
607
|
-
|
|
608
608
|
const profile = generateStageAgentProfile({
|
|
609
609
|
discipline: humanDiscipline,
|
|
610
610
|
track: humanTrack,
|
|
@@ -656,7 +656,24 @@ function createSingleStagePreview(context, stage) {
|
|
|
656
656
|
h2({}, "Agent"),
|
|
657
657
|
div(
|
|
658
658
|
{ className: "agent-cards-grid single" },
|
|
659
|
-
|
|
659
|
+
(() => {
|
|
660
|
+
const content = formatAgentProfile(profile, templates.agent);
|
|
661
|
+
const stageEmoji = getStageEmoji(stages, stage.id);
|
|
662
|
+
return createFileCard({
|
|
663
|
+
header: [
|
|
664
|
+
span({ className: "file-card-emoji" }, stageEmoji),
|
|
665
|
+
h3({}, `${stage.name} Agent`),
|
|
666
|
+
],
|
|
667
|
+
files: [
|
|
668
|
+
{
|
|
669
|
+
filename: profile.filename,
|
|
670
|
+
content,
|
|
671
|
+
language: "markdown",
|
|
672
|
+
},
|
|
673
|
+
],
|
|
674
|
+
maxHeight: 400,
|
|
675
|
+
});
|
|
676
|
+
})(),
|
|
660
677
|
),
|
|
661
678
|
),
|
|
662
679
|
|
|
@@ -667,7 +684,7 @@ function createSingleStagePreview(context, stage) {
|
|
|
667
684
|
skillFiles.length > 0
|
|
668
685
|
? div(
|
|
669
686
|
{ className: "skill-cards-grid" },
|
|
670
|
-
...skillFiles.map((skill) =>
|
|
687
|
+
...skillFiles.map((skill) => buildSkillFileCard(skill, templates)),
|
|
671
688
|
)
|
|
672
689
|
: p(
|
|
673
690
|
{ className: "text-muted" },
|
|
@@ -686,57 +703,18 @@ function createSingleStagePreview(context, stage) {
|
|
|
686
703
|
}
|
|
687
704
|
|
|
688
705
|
/**
|
|
689
|
-
*
|
|
690
|
-
* @param {Object} stage - Stage object
|
|
691
|
-
* @param {Object} profile - Generated profile
|
|
692
|
-
* @param {Array} stages - All stages for emoji lookup
|
|
693
|
-
* @param {string} agentTemplate - Mustache template for agent profile
|
|
694
|
-
* @param {Object} [_derived] - Optional derived agent data for extra info
|
|
695
|
-
* @returns {HTMLElement}
|
|
696
|
-
*/
|
|
697
|
-
function createAgentCard(stage, profile, stages, agentTemplate, _derived) {
|
|
698
|
-
const content = formatAgentProfile(profile, agentTemplate);
|
|
699
|
-
const stageEmoji = getStageEmoji(stages, stage.id);
|
|
700
|
-
|
|
701
|
-
const card = div(
|
|
702
|
-
{ className: "agent-card" },
|
|
703
|
-
div(
|
|
704
|
-
{ className: "agent-card-header" },
|
|
705
|
-
div(
|
|
706
|
-
{ className: "agent-card-title" },
|
|
707
|
-
span({ className: "agent-card-emoji" }, stageEmoji),
|
|
708
|
-
h3({}, `${stage.name} Agent`),
|
|
709
|
-
),
|
|
710
|
-
),
|
|
711
|
-
div(
|
|
712
|
-
{ className: "agent-card-preview" },
|
|
713
|
-
createCodeDisplay({
|
|
714
|
-
content,
|
|
715
|
-
filename: profile.filename,
|
|
716
|
-
maxHeight: 400,
|
|
717
|
-
open: true,
|
|
718
|
-
}),
|
|
719
|
-
),
|
|
720
|
-
);
|
|
721
|
-
|
|
722
|
-
return card;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
/**
|
|
726
|
-
* Create a skill card with tabbed file viewer
|
|
706
|
+
* Build a file card for a skill with 1–3 file panes (accordion).
|
|
727
707
|
* @param {Object} skill - Skill with frontmatter and body
|
|
728
708
|
* @param {{skill: string, install: string, reference: string}} templates - Mustache templates
|
|
729
709
|
* @returns {HTMLElement}
|
|
730
710
|
*/
|
|
731
|
-
function
|
|
711
|
+
function buildSkillFileCard(skill, templates) {
|
|
732
712
|
const content = formatAgentSkill(skill, templates.skill);
|
|
733
|
-
const filename = `${skill.dirname}/SKILL.md`;
|
|
734
713
|
|
|
735
|
-
|
|
736
|
-
/** @type {import('../components/skill-file-viewer.js').SkillFile[]} */
|
|
714
|
+
/** @type {import('../components/file-card.js').FileDescriptor[]} */
|
|
737
715
|
const files = [
|
|
738
716
|
{
|
|
739
|
-
filename
|
|
717
|
+
filename: `${skill.dirname}/SKILL.md`,
|
|
740
718
|
content,
|
|
741
719
|
language: "markdown",
|
|
742
720
|
},
|
|
@@ -758,25 +736,20 @@ function createSkillCard(skill, templates) {
|
|
|
758
736
|
});
|
|
759
737
|
}
|
|
760
738
|
|
|
761
|
-
// Count total files for badge
|
|
762
|
-
const fileCount = files.length;
|
|
763
739
|
const headerChildren = [
|
|
764
|
-
span({ className: "
|
|
740
|
+
span({ className: "file-card-name" }, skill.frontmatter.name),
|
|
765
741
|
];
|
|
766
|
-
if (
|
|
742
|
+
if (files.length > 1) {
|
|
767
743
|
headerChildren.push(
|
|
768
|
-
span({ className: "
|
|
744
|
+
span({ className: "file-card-badge" }, `${files.length} files`),
|
|
769
745
|
);
|
|
770
746
|
}
|
|
771
747
|
|
|
772
|
-
return
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
createSkillFileViewer({ files, maxHeight: 300 }),
|
|
778
|
-
),
|
|
779
|
-
);
|
|
748
|
+
return createFileCard({
|
|
749
|
+
header: headerChildren,
|
|
750
|
+
files,
|
|
751
|
+
maxHeight: 300,
|
|
752
|
+
});
|
|
780
753
|
}
|
|
781
754
|
|
|
782
755
|
/**
|