@forwardimpact/pathway 0.16.1 → 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 +3 -3
- package/src/commands/agent.js +47 -15
- package/src/components/code-display.js +108 -48
- package/src/components/file-card.js +106 -0
- package/src/components/skill-file-viewer.js +61 -0
- package/src/css/bundles/app.css +2 -0
- package/src/css/components/file-card.css +109 -0
- package/src/css/components/forms.css +47 -16
- package/src/css/components/skill-file-viewer.css +18 -0
- package/src/css/pages/agent-builder.css +4 -143
- package/src/formatters/agent/dom.js +7 -37
- package/src/formatters/agent/profile.js +0 -29
- package/src/formatters/agent/skill.js +69 -11
- package/src/formatters/job/dom.js +6 -4
- package/src/formatters/skill/dom.js +47 -9
- package/src/formatters/skill/shared.js +2 -0
- package/src/lib/template-loader.js +18 -0
- package/src/lib/yaml-loader.js +5 -0
- package/src/pages/agent-builder.js +127 -91
- package/src/pages/skill.js +27 -1
- package/templates/agent.template.md +15 -45
- package/templates/skill-install.template.sh +4 -0
- package/templates/skill-reference.template.md +3 -0
- package/templates/skill.template.md +37 -34
- package/src/components/markdown-textarea.js +0 -153
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code Display Component
|
|
3
|
-
*
|
|
4
|
-
* Reusable read-only code block with copy buttons and syntax highlighting.
|
|
5
|
-
* Used for markdown content, agent profiles, skills, and code snippets.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/* global Prism */
|
|
9
|
-
import { div, p, span, button } from "../lib/render.js";
|
|
10
|
-
|
|
11
|
-
const COPY_LABEL = "📋 Copy";
|
|
12
|
-
const COPY_HTML_LABEL = "Copy as HTML";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Create a copy button that copies content to clipboard
|
|
16
|
-
* @param {string} content - The text content to copy
|
|
17
|
-
* @returns {HTMLElement}
|
|
18
|
-
*/
|
|
19
|
-
export function createCopyButton(content) {
|
|
20
|
-
const btn = button(
|
|
21
|
-
{
|
|
22
|
-
className: "btn btn-sm copy-btn",
|
|
23
|
-
onClick: async () => {
|
|
24
|
-
try {
|
|
25
|
-
await navigator.clipboard.writeText(content);
|
|
26
|
-
btn.textContent = "✓ Copied!";
|
|
27
|
-
btn.classList.add("copied");
|
|
28
|
-
setTimeout(() => {
|
|
29
|
-
btn.textContent = COPY_LABEL;
|
|
30
|
-
btn.classList.remove("copied");
|
|
31
|
-
}, 2000);
|
|
32
|
-
} catch (err) {
|
|
33
|
-
console.error("Failed to copy:", err);
|
|
34
|
-
btn.textContent = "Copy failed";
|
|
35
|
-
setTimeout(() => {
|
|
36
|
-
btn.textContent = COPY_LABEL;
|
|
37
|
-
}, 2000);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
COPY_LABEL,
|
|
42
|
-
);
|
|
43
|
-
return btn;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Create a copy button that copies HTML to clipboard (for rich text pasting)
|
|
48
|
-
* @param {string} html - The HTML content to copy
|
|
49
|
-
* @returns {HTMLElement}
|
|
50
|
-
*/
|
|
51
|
-
function createCopyHtmlButton(html) {
|
|
52
|
-
const btn = button(
|
|
53
|
-
{
|
|
54
|
-
className: "btn btn-sm btn-secondary copy-btn",
|
|
55
|
-
onClick: async () => {
|
|
56
|
-
try {
|
|
57
|
-
const blob = new Blob([html], { type: "text/html" });
|
|
58
|
-
const clipboardItem = new ClipboardItem({ "text/html": blob });
|
|
59
|
-
await navigator.clipboard.write([clipboardItem]);
|
|
60
|
-
btn.textContent = "✓ Copied!";
|
|
61
|
-
btn.classList.add("copied");
|
|
62
|
-
setTimeout(() => {
|
|
63
|
-
btn.textContent = COPY_HTML_LABEL;
|
|
64
|
-
btn.classList.remove("copied");
|
|
65
|
-
}, 2000);
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.error("Failed to copy:", err);
|
|
68
|
-
btn.textContent = "Copy failed";
|
|
69
|
-
setTimeout(() => {
|
|
70
|
-
btn.textContent = COPY_HTML_LABEL;
|
|
71
|
-
}, 2000);
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
COPY_HTML_LABEL,
|
|
76
|
-
);
|
|
77
|
-
return btn;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Create a code display component with syntax highlighting and copy button
|
|
82
|
-
* @param {Object} options
|
|
83
|
-
* @param {string} options.content - The code content to display
|
|
84
|
-
* @param {string} [options.language="markdown"] - Language for syntax highlighting
|
|
85
|
-
* @param {string} [options.filename] - Optional filename to display in header
|
|
86
|
-
* @param {string} [options.description] - Optional description text
|
|
87
|
-
* @param {Function} [options.toHtml] - Function to convert content to HTML (enables "Copy as HTML" button)
|
|
88
|
-
* @param {number} [options.minHeight] - Optional minimum height in pixels
|
|
89
|
-
* @param {number} [options.maxHeight] - Optional maximum height in pixels
|
|
90
|
-
* @returns {HTMLElement}
|
|
91
|
-
*/
|
|
92
|
-
export function createCodeDisplay({
|
|
93
|
-
content,
|
|
94
|
-
language = "markdown",
|
|
95
|
-
filename,
|
|
96
|
-
description,
|
|
97
|
-
toHtml,
|
|
98
|
-
minHeight,
|
|
99
|
-
maxHeight,
|
|
100
|
-
}) {
|
|
101
|
-
// Create highlighted code block
|
|
102
|
-
const pre = document.createElement("pre");
|
|
103
|
-
pre.className = "code-display";
|
|
104
|
-
if (minHeight) pre.style.minHeight = `${minHeight}px`;
|
|
105
|
-
if (maxHeight) {
|
|
106
|
-
pre.style.maxHeight = `${maxHeight}px`;
|
|
107
|
-
pre.style.overflowY = "auto";
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const code = document.createElement("code");
|
|
111
|
-
if (language) {
|
|
112
|
-
code.className = `language-${language}`;
|
|
113
|
-
}
|
|
114
|
-
code.textContent = content;
|
|
115
|
-
pre.appendChild(code);
|
|
116
|
-
|
|
117
|
-
// Apply Prism highlighting if available and language specified
|
|
118
|
-
if (language && typeof Prism !== "undefined") {
|
|
119
|
-
Prism.highlightElement(code);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Build header content
|
|
123
|
-
const headerLeft = [];
|
|
124
|
-
if (filename) {
|
|
125
|
-
headerLeft.push(span({ className: "code-display-filename" }, filename));
|
|
126
|
-
}
|
|
127
|
-
if (description) {
|
|
128
|
-
headerLeft.push(p({ className: "text-muted" }, description));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Build buttons
|
|
132
|
-
const buttons = [createCopyButton(content)];
|
|
133
|
-
if (toHtml) {
|
|
134
|
-
buttons.push(createCopyHtmlButton(toHtml(content)));
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Only show header if there's content for it
|
|
138
|
-
const hasHeader = headerLeft.length > 0 || buttons.length > 0;
|
|
139
|
-
|
|
140
|
-
return div(
|
|
141
|
-
{ className: "code-display-container" },
|
|
142
|
-
hasHeader
|
|
143
|
-
? div(
|
|
144
|
-
{ className: "code-display-header" },
|
|
145
|
-
headerLeft.length > 0
|
|
146
|
-
? div({ className: "code-display-info" }, ...headerLeft)
|
|
147
|
-
: null,
|
|
148
|
-
div({ className: "button-group" }, ...buttons),
|
|
149
|
-
)
|
|
150
|
-
: null,
|
|
151
|
-
pre,
|
|
152
|
-
);
|
|
153
|
-
}
|