@forwardimpact/pathway 0.12.0 → 0.14.0
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/bin/fit-pathway.js +32 -12
- package/package.json +3 -3
- package/src/commands/build.js +98 -2
- package/src/commands/index.js +1 -0
- package/src/commands/interview.js +52 -14
- package/src/commands/job.js +1 -0
- package/src/commands/questions.js +13 -10
- package/src/commands/stage.js +8 -8
- package/src/commands/update.js +133 -0
- package/src/components/command-prompt.js +85 -0
- package/src/components/nav.js +2 -2
- package/src/components/top-bar.js +97 -0
- package/src/css/bundles/app.css +2 -0
- package/src/css/components/badges.css +41 -11
- package/src/css/components/command-prompt.css +98 -0
- package/src/css/components/layout.css +0 -3
- package/src/css/components/nav.css +121 -81
- package/src/css/components/surfaces.css +1 -1
- package/src/css/components/top-bar.css +180 -0
- package/src/css/pages/agent-builder.css +0 -9
- package/src/css/pages/landing.css +4 -0
- package/src/css/pages/lifecycle.css +5 -2
- package/src/css/reset.css +1 -1
- package/src/css/tokens.css +25 -11
- package/src/css/views/slide-base.css +2 -1
- package/src/formatters/agent/dom.js +0 -26
- package/src/formatters/agent/profile.js +13 -7
- package/src/formatters/agent/skill.js +4 -4
- package/src/formatters/interview/markdown.js +62 -3
- package/src/formatters/interview/shared.js +89 -52
- package/src/formatters/questions/markdown.js +15 -0
- package/src/formatters/questions/shared.js +70 -58
- package/src/formatters/stage/dom.js +13 -10
- package/src/formatters/stage/microdata.js +14 -8
- package/src/formatters/stage/shared.js +4 -4
- package/src/index.html +69 -44
- package/src/lib/cli-command.js +145 -0
- package/src/lib/state.js +2 -0
- package/src/lib/yaml-loader.js +39 -21
- package/src/main.js +47 -26
- package/src/pages/agent-builder.js +0 -28
- package/src/pages/behaviour.js +3 -1
- package/src/pages/discipline.js +3 -1
- package/src/pages/driver.js +6 -1
- package/src/pages/grade.js +6 -1
- package/src/pages/interview.js +61 -5
- package/src/pages/job.js +1 -0
- package/src/pages/landing.js +7 -0
- package/src/pages/skill.js +9 -2
- package/src/pages/track.js +6 -1
- package/src/slides/job.js +1 -0
- package/templates/agent.template.md +17 -10
- package/templates/install.template.sh +33 -0
- package/templates/skill.template.md +15 -7
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Top Bar
|
|
3
|
+
*
|
|
4
|
+
* Fixed bar across the top of the viewport with sidebar toggle and
|
|
5
|
+
* CLI command display. Inspired by Safari's URL bar + sidebar layout.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
@layer components {
|
|
9
|
+
/* --------------------------------------------------------------------------
|
|
10
|
+
Bar container - fixed across top
|
|
11
|
+
-------------------------------------------------------------------------- */
|
|
12
|
+
.top-bar {
|
|
13
|
+
position: fixed;
|
|
14
|
+
top: 0;
|
|
15
|
+
left: 0;
|
|
16
|
+
right: 0;
|
|
17
|
+
height: var(--top-bar-height);
|
|
18
|
+
z-index: 200;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: var(--space-sm);
|
|
22
|
+
padding: 0 var(--space-sm);
|
|
23
|
+
background: var(--color-surface);
|
|
24
|
+
border-bottom: 1px solid var(--color-border);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* --------------------------------------------------------------------------
|
|
28
|
+
Sidebar toggle button
|
|
29
|
+
-------------------------------------------------------------------------- */
|
|
30
|
+
.top-bar__toggle {
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
width: 36px;
|
|
36
|
+
height: 36px;
|
|
37
|
+
border: none;
|
|
38
|
+
border-radius: var(--radius-md);
|
|
39
|
+
background: transparent;
|
|
40
|
+
color: var(--color-text-muted);
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
transition:
|
|
43
|
+
background 0.15s,
|
|
44
|
+
color 0.15s;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.top-bar__toggle:hover {
|
|
48
|
+
background: var(--color-bg-secondary);
|
|
49
|
+
color: var(--color-text);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.top-bar__toggle:active {
|
|
53
|
+
background: var(--color-border);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Sidebar icon: simple sidebar SVG */
|
|
57
|
+
.top-bar__toggle svg {
|
|
58
|
+
width: 18px;
|
|
59
|
+
height: 18px;
|
|
60
|
+
fill: none;
|
|
61
|
+
stroke: currentColor;
|
|
62
|
+
stroke-width: 1.5;
|
|
63
|
+
stroke-linecap: round;
|
|
64
|
+
stroke-linejoin: round;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Highlight toggle when drawer is open */
|
|
68
|
+
.drawer-open .top-bar__toggle {
|
|
69
|
+
color: var(--color-primary);
|
|
70
|
+
background: rgba(59, 130, 246, 0.08);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* --------------------------------------------------------------------------
|
|
74
|
+
Command bar (mimics Safari-style URL bar)
|
|
75
|
+
-------------------------------------------------------------------------- */
|
|
76
|
+
.top-bar__command {
|
|
77
|
+
width: 100%;
|
|
78
|
+
max-width: 800px;
|
|
79
|
+
margin: 0 auto;
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
height: 36px;
|
|
83
|
+
padding: 0 var(--space-sm) 0 var(--space-md);
|
|
84
|
+
border: 1px solid var(--color-border);
|
|
85
|
+
border-radius: var(--radius-lg);
|
|
86
|
+
transition:
|
|
87
|
+
border-color 0.15s,
|
|
88
|
+
box-shadow 0.15s;
|
|
89
|
+
gap: var(--space-xs);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.top-bar__command:hover {
|
|
93
|
+
border-color: var(--color-text-light);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.top-bar__command:focus-within {
|
|
97
|
+
border-color: var(--color-primary);
|
|
98
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* Terminal prompt icon */
|
|
102
|
+
.top-bar__prompt {
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
font-size: var(--font-size-sm);
|
|
105
|
+
color: var(--color-text-light);
|
|
106
|
+
user-select: none;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* CLI command text */
|
|
110
|
+
.top-bar__command-text {
|
|
111
|
+
flex: 1;
|
|
112
|
+
min-width: 0;
|
|
113
|
+
font-family: var(--font-family-mono);
|
|
114
|
+
font-size: var(--font-size-xs);
|
|
115
|
+
color: var(--color-text-secondary);
|
|
116
|
+
white-space: nowrap;
|
|
117
|
+
overflow: hidden;
|
|
118
|
+
text-overflow: ellipsis;
|
|
119
|
+
user-select: all;
|
|
120
|
+
line-height: 36px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Copy button inside the command bar */
|
|
124
|
+
.top-bar__copy {
|
|
125
|
+
flex-shrink: 0;
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
width: 28px;
|
|
130
|
+
height: 28px;
|
|
131
|
+
border: none;
|
|
132
|
+
border-radius: var(--radius-sm);
|
|
133
|
+
background: transparent;
|
|
134
|
+
color: var(--color-text-light);
|
|
135
|
+
cursor: pointer;
|
|
136
|
+
transition:
|
|
137
|
+
background 0.15s,
|
|
138
|
+
color 0.15s;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.top-bar__copy:hover {
|
|
142
|
+
background: var(--color-border);
|
|
143
|
+
color: var(--color-text);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.top-bar__copy svg {
|
|
147
|
+
width: 14px;
|
|
148
|
+
height: 14px;
|
|
149
|
+
fill: none;
|
|
150
|
+
stroke: currentColor;
|
|
151
|
+
stroke-width: 2;
|
|
152
|
+
stroke-linecap: round;
|
|
153
|
+
stroke-linejoin: round;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* Copied state */
|
|
157
|
+
.top-bar__copy.copied {
|
|
158
|
+
color: var(--color-success);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.top-bar__copy.copied svg {
|
|
162
|
+
/* Swap from copy icon to checkmark via CSS — JS swaps the class */
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* --------------------------------------------------------------------------
|
|
166
|
+
Layout adjustments - push content below the top bar
|
|
167
|
+
-------------------------------------------------------------------------- */
|
|
168
|
+
.app-body {
|
|
169
|
+
padding-top: var(--top-bar-height);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* --------------------------------------------------------------------------
|
|
173
|
+
Mobile tweaks
|
|
174
|
+
-------------------------------------------------------------------------- */
|
|
175
|
+
@media (max-width: 768px) {
|
|
176
|
+
.top-bar__prompt {
|
|
177
|
+
display: none;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -160,15 +160,6 @@
|
|
|
160
160
|
gap: var(--space-md);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
/* CLI hint */
|
|
164
|
-
.cli-hint {
|
|
165
|
-
background: var(--color-bg);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
.cli-hint h2 {
|
|
169
|
-
margin-bottom: var(--space-sm);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
163
|
/* Role agents list */
|
|
173
164
|
.role-agents-list {
|
|
174
165
|
display: flex;
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
display: flex;
|
|
22
22
|
align-items: center;
|
|
23
23
|
gap: var(--space-md);
|
|
24
|
+
flex: 1;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
.lifecycle-stage {
|
|
28
|
+
flex: 1;
|
|
27
29
|
display: flex;
|
|
28
30
|
flex-direction: column;
|
|
29
31
|
align-items: center;
|
|
@@ -67,8 +69,9 @@
|
|
|
67
69
|
flex-wrap: wrap;
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
.page-title-row .page-title
|
|
71
|
-
|
|
72
|
+
.page-title-row .page-title,
|
|
73
|
+
.page-title-row .page-title-badges {
|
|
74
|
+
margin: 0 0 var(--space-md);
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
/* Criteria and constraints */
|
package/src/css/reset.css
CHANGED
package/src/css/tokens.css
CHANGED
|
@@ -43,22 +43,34 @@
|
|
|
43
43
|
--color-maturity-5: #c4b5fd;
|
|
44
44
|
|
|
45
45
|
/* --------------------------------------------------------------------------
|
|
46
|
-
Colors - Capabilities (text)
|
|
46
|
+
Colors - Capabilities (text) - matches data/capabilities/*.yaml IDs
|
|
47
47
|
-------------------------------------------------------------------------- */
|
|
48
|
-
--color-cap-
|
|
49
|
-
--color-cap-
|
|
50
|
-
--color-cap-
|
|
51
|
-
--color-cap-
|
|
52
|
-
--color-cap-
|
|
48
|
+
--color-cap-ai: #7c3aed; /* violet */
|
|
49
|
+
--color-cap-business: #b45309; /* amber */
|
|
50
|
+
--color-cap-data: #0f766e; /* teal */
|
|
51
|
+
--color-cap-delivery: #dc2626; /* red */
|
|
52
|
+
--color-cap-documentation: #15803d; /* green */
|
|
53
|
+
--color-cap-ml: #9333ea; /* purple */
|
|
54
|
+
--color-cap-people: #be185d; /* pink */
|
|
55
|
+
--color-cap-process: #c2410c; /* orange */
|
|
56
|
+
--color-cap-product: #4f46e5; /* indigo */
|
|
57
|
+
--color-cap-reliability: #0891b2; /* cyan */
|
|
58
|
+
--color-cap-scale: #1d4ed8; /* blue */
|
|
53
59
|
|
|
54
60
|
/* --------------------------------------------------------------------------
|
|
55
61
|
Colors - Capabilities (backgrounds)
|
|
56
62
|
-------------------------------------------------------------------------- */
|
|
57
|
-
--color-cap-
|
|
58
|
-
--color-cap-scale-light: #dbeafe; /* blue */
|
|
59
|
-
--color-cap-reliability-light: #cffafe; /* cyan */
|
|
63
|
+
--color-cap-ai-light: #ede9fe; /* violet */
|
|
60
64
|
--color-cap-business-light: #fef3c7; /* amber */
|
|
65
|
+
--color-cap-data-light: #ccfbf1; /* teal */
|
|
66
|
+
--color-cap-delivery-light: #fecaca; /* red */
|
|
67
|
+
--color-cap-documentation-light: #dcfce7; /* green */
|
|
68
|
+
--color-cap-ml-light: #f3e8ff; /* purple */
|
|
61
69
|
--color-cap-people-light: #fce7f3; /* pink */
|
|
70
|
+
--color-cap-process-light: #ffedd5; /* orange */
|
|
71
|
+
--color-cap-product-light: #e0e7ff; /* indigo */
|
|
72
|
+
--color-cap-reliability-light: #cffafe; /* cyan */
|
|
73
|
+
--color-cap-scale-light: #dbeafe; /* blue */
|
|
62
74
|
|
|
63
75
|
/* --------------------------------------------------------------------------
|
|
64
76
|
Colors - Neutrals
|
|
@@ -137,11 +149,13 @@
|
|
|
137
149
|
Layout
|
|
138
150
|
-------------------------------------------------------------------------- */
|
|
139
151
|
--max-width: 1400px;
|
|
140
|
-
--
|
|
152
|
+
--drawer-width: 240px;
|
|
153
|
+
--top-bar-height: 48px;
|
|
141
154
|
|
|
142
155
|
/*
|
|
143
156
|
* Responsive breakpoints (used in @media queries):
|
|
144
|
-
* - 1280px: Tablet/laptop -
|
|
157
|
+
* - 1280px: Tablet/laptop - layout stacking
|
|
158
|
+
* - 768px: Mobile - drawer overlays instead of pushing content
|
|
145
159
|
* - 640px: Mobile - full-width buttons, simplified layouts
|
|
146
160
|
*/
|
|
147
161
|
}
|
|
@@ -92,14 +92,6 @@ export function agentDeploymentToDOM({
|
|
|
92
92
|
"No skills with agent sections found for this discipline.",
|
|
93
93
|
),
|
|
94
94
|
),
|
|
95
|
-
|
|
96
|
-
// CLI hint section
|
|
97
|
-
section(
|
|
98
|
-
{ className: "agent-section cli-hint" },
|
|
99
|
-
h2({}, "CLI Alternative"),
|
|
100
|
-
p({}, "Generate this agent from the command line:"),
|
|
101
|
-
createCliCommand(agentName),
|
|
102
|
-
),
|
|
103
95
|
);
|
|
104
96
|
}
|
|
105
97
|
|
|
@@ -200,24 +192,6 @@ function createRoleAgentCard(agent) {
|
|
|
200
192
|
);
|
|
201
193
|
}
|
|
202
194
|
|
|
203
|
-
/**
|
|
204
|
-
* Create CLI command display
|
|
205
|
-
* @param {string} agentName - Agent name (kebab-case)
|
|
206
|
-
* @returns {HTMLElement}
|
|
207
|
-
*/
|
|
208
|
-
function createCliCommand(agentName) {
|
|
209
|
-
// Convert kebab-case name to discipline and track
|
|
210
|
-
const parts = agentName.split("-");
|
|
211
|
-
const track = parts.pop();
|
|
212
|
-
const discipline = parts.join("_");
|
|
213
|
-
|
|
214
|
-
const command = `npx pathway agent ${discipline} ${track} --output=.github --all-roles`;
|
|
215
|
-
|
|
216
|
-
return createCodeDisplay({
|
|
217
|
-
content: command,
|
|
218
|
-
language: "bash",
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
195
|
|
|
222
196
|
/**
|
|
223
197
|
* Download all agent files as a ZIP
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* @typedef {Object}
|
|
26
|
+
* @typedef {Object} ConfirmChecklistEntry
|
|
27
27
|
* @property {{id: string, name: string}} skill - Skill info
|
|
28
28
|
* @property {{id: string, name: string, emojiIcon: string}} capability - Capability info
|
|
29
29
|
* @property {string[]} items - Checklist items
|
|
@@ -41,12 +41,15 @@ import {
|
|
|
41
41
|
* @param {Object} params.bodyData - Structured body data
|
|
42
42
|
* @param {string} params.bodyData.title - Agent title
|
|
43
43
|
* @param {string} params.bodyData.stageDescription - Stage description text
|
|
44
|
+
* @param {string} params.bodyData.stageId - Stage identifier (e.g. "plan", "code", "onboard")
|
|
45
|
+
* @param {string} params.bodyData.stageName - Human-readable stage name (e.g. "Plan", "Code", "Onboard")
|
|
46
|
+
* @param {boolean} params.bodyData.isOnboard - Whether this is the onboard stage
|
|
44
47
|
* @param {string} params.bodyData.identity - Core identity text
|
|
45
48
|
* @param {string} [params.bodyData.priority] - Priority/philosophy statement
|
|
46
49
|
* @param {Array<{name: string, dirname: string, useWhen: string}>} params.bodyData.skillIndex - Skill index entries
|
|
47
50
|
* @param {string} params.bodyData.roleContext - Role context text
|
|
48
51
|
* @param {WorkingStyleEntry[]} params.bodyData.workingStyles - Working style entries
|
|
49
|
-
* @param {
|
|
52
|
+
* @param {ConfirmChecklistEntry[]} [params.bodyData.confirmChecklist] - Confirm Checklist entries
|
|
50
53
|
* @param {string[]} params.bodyData.constraints - List of constraints
|
|
51
54
|
* @param {Array<{id: string, name: string, description: string}>} [params.bodyData.agentIndex] - List of all available agents
|
|
52
55
|
* @param {boolean} [params.bodyData.hasAgentIndex] - Whether agent index is available
|
|
@@ -77,8 +80,8 @@ function prepareAgentProfileData({ frontmatter, bodyData }) {
|
|
|
77
80
|
content: "required",
|
|
78
81
|
});
|
|
79
82
|
|
|
80
|
-
// Process
|
|
81
|
-
const
|
|
83
|
+
// Process confirmChecklist: trim items in each entry
|
|
84
|
+
const confirmChecklist = (bodyData.confirmChecklist || []).map((entry) => ({
|
|
82
85
|
skill: entry.skill,
|
|
83
86
|
capability: entry.capability,
|
|
84
87
|
items: (entry.items || []).map((item) => trimRequired(item)),
|
|
@@ -94,6 +97,9 @@ function prepareAgentProfileData({ frontmatter, bodyData }) {
|
|
|
94
97
|
// Body data - trim all string fields
|
|
95
98
|
title: bodyData.title,
|
|
96
99
|
stageDescription: trimValue(bodyData.stageDescription),
|
|
100
|
+
stageId: bodyData.stageId,
|
|
101
|
+
stageName: bodyData.stageName,
|
|
102
|
+
isOnboard: bodyData.isOnboard,
|
|
97
103
|
identity: trimValue(bodyData.identity),
|
|
98
104
|
priority: trimValue(bodyData.priority),
|
|
99
105
|
skillIndex,
|
|
@@ -101,8 +107,8 @@ function prepareAgentProfileData({ frontmatter, bodyData }) {
|
|
|
101
107
|
roleContext: trimValue(bodyData.roleContext),
|
|
102
108
|
workingStyles,
|
|
103
109
|
hasWorkingStyles: workingStyles.length > 0,
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
confirmChecklist,
|
|
111
|
+
hasConfirmChecklist: confirmChecklist.length > 0,
|
|
106
112
|
constraints,
|
|
107
113
|
hasConstraints: constraints.length > 0,
|
|
108
114
|
agentIndex,
|
|
@@ -127,7 +133,7 @@ function prepareAgentProfileData({ frontmatter, bodyData }) {
|
|
|
127
133
|
* @param {Array<{name: string, dirname: string, useWhen: string}>} profile.bodyData.skillIndex - Skill index entries
|
|
128
134
|
* @param {string} profile.bodyData.roleContext - Role context text
|
|
129
135
|
* @param {WorkingStyleEntry[]} profile.bodyData.workingStyles - Working style entries
|
|
130
|
-
* @param {
|
|
136
|
+
* @param {ConfirmChecklistEntry[]} [profile.bodyData.confirmChecklist] - Confirm Checklist entries (optional)
|
|
131
137
|
* @param {string[]} profile.bodyData.constraints - List of constraints
|
|
132
138
|
* @param {string} template - Mustache template string
|
|
133
139
|
* @returns {string} Complete .agent.md file content
|
|
@@ -22,7 +22,7 @@ import { flattenToLine } from "../template-preprocess.js";
|
|
|
22
22
|
* @param {string} params.frontmatter.description - Skill description (required)
|
|
23
23
|
* @param {string} [params.frontmatter.useWhen] - When to use this skill
|
|
24
24
|
* @param {string} params.title - Human-readable skill title for heading
|
|
25
|
-
* @param {Array} params.stages - Array of stage objects with stageName, focus,
|
|
25
|
+
* @param {Array} params.stages - Array of stage objects with stageName, focus, readChecklist, confirmChecklist
|
|
26
26
|
* @param {string} params.reference - Reference content (markdown)
|
|
27
27
|
* @param {Array} [params.toolReferences] - Array of tool reference objects
|
|
28
28
|
* @returns {Object} Data object ready for Mustache template
|
|
@@ -37,8 +37,8 @@ function prepareAgentSkillData({
|
|
|
37
37
|
// Process stages - trim focus and array values
|
|
38
38
|
const processedStages = trimFields(stages, {
|
|
39
39
|
focus: "required",
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
readChecklist: "array",
|
|
41
|
+
confirmChecklist: "array",
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
// Flatten multi-line strings to single line for front matter compatibility
|
|
@@ -77,7 +77,7 @@ function prepareAgentSkillData({
|
|
|
77
77
|
* @param {string} skill.frontmatter.name - Skill name (required)
|
|
78
78
|
* @param {string} skill.frontmatter.description - Skill description (required)
|
|
79
79
|
* @param {string} skill.title - Human-readable skill title for heading
|
|
80
|
-
* @param {Array} skill.stages - Array of stage objects with stageName, focus,
|
|
80
|
+
* @param {Array} skill.stages - Array of stage objects with stageName, focus, readChecklist, confirmChecklist
|
|
81
81
|
* @param {string} skill.reference - Reference content (markdown)
|
|
82
82
|
* @param {Array} [skill.toolReferences] - Array of tool reference objects
|
|
83
83
|
* @param {string} template - Mustache template string
|
|
@@ -27,6 +27,9 @@ export function interviewToMarkdown(view, { framework } = {}) {
|
|
|
27
27
|
// Group sections by type
|
|
28
28
|
const skillSections = view.sections.filter((s) => s.type === "skill");
|
|
29
29
|
const behaviourSections = view.sections.filter((s) => s.type === "behaviour");
|
|
30
|
+
const capabilitySections = view.sections.filter(
|
|
31
|
+
(s) => s.type === "capability",
|
|
32
|
+
);
|
|
30
33
|
|
|
31
34
|
// Skill questions
|
|
32
35
|
if (skillSections.length > 0) {
|
|
@@ -36,27 +39,83 @@ export function interviewToMarkdown(view, { framework } = {}) {
|
|
|
36
39
|
for (const q of section.questions) {
|
|
37
40
|
lines.push(`**Q**: ${q.question}`);
|
|
38
41
|
if (q.followUps.length > 0) {
|
|
42
|
+
lines.push("", "**Follow-ups:**");
|
|
39
43
|
for (const followUp of q.followUps) {
|
|
40
44
|
lines.push(` → ${followUp}`);
|
|
41
45
|
}
|
|
42
46
|
}
|
|
47
|
+
if (q.lookingFor && q.lookingFor.length > 0) {
|
|
48
|
+
lines.push("", "**What to look for:**");
|
|
49
|
+
for (const item of q.lookingFor) {
|
|
50
|
+
lines.push(`- ${item}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
43
53
|
lines.push("");
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
56
|
}
|
|
47
57
|
|
|
48
|
-
//
|
|
58
|
+
// Capability decomposition questions
|
|
59
|
+
if (capabilitySections.length > 0) {
|
|
60
|
+
lines.push(`## 🧩 Decomposition Questions`, "");
|
|
61
|
+
for (const section of capabilitySections) {
|
|
62
|
+
lines.push(`### ${section.name} (${formatLevel(section.level)})`, "");
|
|
63
|
+
for (const q of section.questions) {
|
|
64
|
+
lines.push(`**Scenario**: ${q.question}`);
|
|
65
|
+
if (q.context) {
|
|
66
|
+
lines.push(`> ${q.context}`);
|
|
67
|
+
}
|
|
68
|
+
if (q.decompositionPrompts && q.decompositionPrompts.length > 0) {
|
|
69
|
+
lines.push("", "**Guide the candidate through:**");
|
|
70
|
+
for (const prompt of q.decompositionPrompts) {
|
|
71
|
+
lines.push(`- ${prompt}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (q.followUps.length > 0) {
|
|
75
|
+
lines.push("", "**Follow-ups:**");
|
|
76
|
+
for (const followUp of q.followUps) {
|
|
77
|
+
lines.push(` → ${followUp}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (q.lookingFor && q.lookingFor.length > 0) {
|
|
81
|
+
lines.push("", "**What to look for:**");
|
|
82
|
+
for (const item of q.lookingFor) {
|
|
83
|
+
lines.push(`- ${item}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
lines.push("");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Behaviour stakeholder simulation questions
|
|
49
92
|
if (behaviourSections.length > 0) {
|
|
50
|
-
lines.push(`## ${behaviourEmoji}
|
|
93
|
+
lines.push(`## ${behaviourEmoji} Stakeholder Simulation`, "");
|
|
51
94
|
for (const section of behaviourSections) {
|
|
52
95
|
lines.push(`### ${section.name} (${formatLevel(section.level)})`, "");
|
|
53
96
|
for (const q of section.questions) {
|
|
54
|
-
lines.push(`**
|
|
97
|
+
lines.push(`**Scenario**: ${q.question}`);
|
|
98
|
+
if (q.context) {
|
|
99
|
+
lines.push(`> ${q.context}`);
|
|
100
|
+
}
|
|
101
|
+
if (q.simulationPrompts && q.simulationPrompts.length > 0) {
|
|
102
|
+
lines.push("", "**Steer the simulation:**");
|
|
103
|
+
for (const prompt of q.simulationPrompts) {
|
|
104
|
+
lines.push(`- ${prompt}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
55
107
|
if (q.followUps.length > 0) {
|
|
108
|
+
lines.push("", "**Follow-ups:**");
|
|
56
109
|
for (const followUp of q.followUps) {
|
|
57
110
|
lines.push(` → ${followUp}`);
|
|
58
111
|
}
|
|
59
112
|
}
|
|
113
|
+
if (q.lookingFor && q.lookingFor.length > 0) {
|
|
114
|
+
lines.push("", "**What to look for:**");
|
|
115
|
+
for (const item of q.lookingFor) {
|
|
116
|
+
lines.push(`- ${item}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
60
119
|
lines.push("");
|
|
61
120
|
}
|
|
62
121
|
}
|