@forwardimpact/pathway 0.25.15 → 0.25.21
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 +62 -54
- package/package.json +1 -3
- package/src/commands/agent-io.js +120 -0
- package/src/commands/agent.js +266 -349
- package/src/commands/init.js +2 -2
- package/src/commands/job.js +237 -183
- package/src/components/comparison-radar.js +118 -103
- package/src/components/progression-table.js +244 -208
- package/src/formatters/index.js +0 -19
- package/src/formatters/interview/markdown.js +100 -88
- package/src/formatters/job/description.js +76 -75
- package/src/formatters/job/dom.js +113 -97
- package/src/formatters/level/dom.js +87 -102
- package/src/formatters/questions/markdown.js +37 -33
- package/src/formatters/questions/shared.js +142 -75
- package/src/formatters/skill/dom.js +102 -93
- package/src/lib/comparison-radar-chart.js +256 -0
- package/src/lib/radar-utils.js +199 -0
- package/src/lib/radar.js +25 -662
- package/src/pages/agent-builder-download.js +170 -0
- package/src/pages/agent-builder-preview.js +344 -0
- package/src/pages/agent-builder.js +6 -550
- package/src/pages/progress-comparison.js +110 -0
- package/src/pages/progress.js +11 -111
- package/src/pages/self-assessment-steps.js +494 -0
- package/src/pages/self-assessment.js +54 -504
- package/src/formatters/behaviour/microdata.js +0 -106
- package/src/formatters/discipline/microdata.js +0 -117
- package/src/formatters/driver/microdata.js +0 -91
- package/src/formatters/level/microdata.js +0 -141
- package/src/formatters/microdata-shared.js +0 -184
- package/src/formatters/skill/microdata.js +0 -151
- package/src/formatters/stage/microdata.js +0 -116
- package/src/formatters/track/microdata.js +0 -111
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Skill formatting for microdata HTML output
|
|
3
|
-
*
|
|
4
|
-
* Generates clean, class-less HTML with microdata aligned with capability.schema.json
|
|
5
|
-
* RDF vocab: https://www.forwardimpact.team/schema/rdf/
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
openTag,
|
|
10
|
-
prop,
|
|
11
|
-
propRaw,
|
|
12
|
-
metaTag,
|
|
13
|
-
section,
|
|
14
|
-
dl,
|
|
15
|
-
ul,
|
|
16
|
-
escapeHtml,
|
|
17
|
-
formatLevelName,
|
|
18
|
-
htmlDocument,
|
|
19
|
-
} from "../microdata-shared.js";
|
|
20
|
-
import { prepareSkillsList, prepareSkillDetail } from "./shared.js";
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Format skill list as microdata HTML
|
|
24
|
-
* @param {Array} skills - Raw skill entities
|
|
25
|
-
* @param {Array} capabilities - Capability entities
|
|
26
|
-
* @returns {string} HTML with microdata
|
|
27
|
-
*/
|
|
28
|
-
export function skillListToMicrodata(skills, capabilities) {
|
|
29
|
-
const { groups, groupOrder } = prepareSkillsList(skills, capabilities);
|
|
30
|
-
|
|
31
|
-
const content = groupOrder
|
|
32
|
-
.map((capability) => {
|
|
33
|
-
const capabilitySkills = groups[capability];
|
|
34
|
-
const skillItems = capabilitySkills
|
|
35
|
-
.map(
|
|
36
|
-
(
|
|
37
|
-
skill,
|
|
38
|
-
) => `${openTag("article", { itemtype: "Skill", itemid: `#${skill.id}` })}
|
|
39
|
-
${prop("h3", "name", skill.name)}
|
|
40
|
-
${prop("p", "description", skill.truncatedDescription)}
|
|
41
|
-
${metaTag("capability", capability)}
|
|
42
|
-
</article>`,
|
|
43
|
-
)
|
|
44
|
-
.join("\n");
|
|
45
|
-
|
|
46
|
-
return section(formatLevelName(capability), skillItems, 2);
|
|
47
|
-
})
|
|
48
|
-
.join("\n");
|
|
49
|
-
|
|
50
|
-
return htmlDocument(
|
|
51
|
-
"Skills",
|
|
52
|
-
`<main>
|
|
53
|
-
<h1>Skills</h1>
|
|
54
|
-
${content}
|
|
55
|
-
</main>`,
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Format skill detail as microdata HTML
|
|
61
|
-
* @param {Object} skill - Raw skill entity
|
|
62
|
-
* @param {Object} context - Additional context
|
|
63
|
-
* @param {Array} context.disciplines - All disciplines
|
|
64
|
-
* @param {Array} context.tracks - All tracks
|
|
65
|
-
* @param {Array} context.drivers - All drivers
|
|
66
|
-
* @param {Array} context.capabilities - Capability entities
|
|
67
|
-
* @returns {string} HTML with microdata
|
|
68
|
-
*/
|
|
69
|
-
export function skillToMicrodata(
|
|
70
|
-
skill,
|
|
71
|
-
{ disciplines, tracks, drivers, capabilities },
|
|
72
|
-
) {
|
|
73
|
-
const view = prepareSkillDetail(skill, {
|
|
74
|
-
disciplines,
|
|
75
|
-
tracks,
|
|
76
|
-
drivers,
|
|
77
|
-
capabilities,
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
if (!view) return "";
|
|
81
|
-
|
|
82
|
-
const sections = [];
|
|
83
|
-
|
|
84
|
-
// Human-only badge
|
|
85
|
-
if (view.isHumanOnly) {
|
|
86
|
-
sections.push(`<p><strong>Human-Only</strong> — Requires interpersonal skills; excluded from agents</p>
|
|
87
|
-
${metaTag("isHumanOnly", "true")}`);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Level descriptions - uses ProficiencyDescriptions itemtype
|
|
91
|
-
const levelPairs = Object.entries(view.proficiencyDescriptions).map(
|
|
92
|
-
([level, desc]) => ({
|
|
93
|
-
term: formatLevelName(level),
|
|
94
|
-
definition: desc,
|
|
95
|
-
itemprop: `${level}Description`,
|
|
96
|
-
}),
|
|
97
|
-
);
|
|
98
|
-
sections.push(
|
|
99
|
-
section(
|
|
100
|
-
"Level Descriptions",
|
|
101
|
-
`${openTag("div", { itemtype: "ProficiencyDescriptions", itemprop: "proficiencyDescriptions" })}
|
|
102
|
-
${dl(levelPairs)}
|
|
103
|
-
</div>`,
|
|
104
|
-
2,
|
|
105
|
-
),
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
// Related disciplines
|
|
109
|
-
if (view.relatedDisciplines.length > 0) {
|
|
110
|
-
const disciplineItems = view.relatedDisciplines.map(
|
|
111
|
-
(d) =>
|
|
112
|
-
`<a href="#${escapeHtml(d.id)}">${escapeHtml(d.name)}</a> (${escapeHtml(d.skillType)})`,
|
|
113
|
-
);
|
|
114
|
-
sections.push(section("Used in Disciplines", ul(disciplineItems), 2));
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Related tracks with modifiers
|
|
118
|
-
if (view.relatedTracks.length > 0) {
|
|
119
|
-
const trackItems = view.relatedTracks.map((t) => {
|
|
120
|
-
const modifierStr = t.modifier > 0 ? `+${t.modifier}` : `${t.modifier}`;
|
|
121
|
-
return `<a href="#${escapeHtml(t.id)}">${escapeHtml(t.name)}</a>: ${modifierStr}`;
|
|
122
|
-
});
|
|
123
|
-
sections.push(section("Modified by Tracks", ul(trackItems), 2));
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Related drivers
|
|
127
|
-
if (view.relatedDrivers.length > 0) {
|
|
128
|
-
const driverItems = view.relatedDrivers.map(
|
|
129
|
-
(d) => `<a href="#${escapeHtml(d.id)}">${escapeHtml(d.name)}</a>`,
|
|
130
|
-
);
|
|
131
|
-
sections.push(section("Linked to Drivers", ul(driverItems), 2));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const body = `<main>
|
|
135
|
-
${openTag("article", { itemtype: "Skill", itemid: `#${view.id}` })}
|
|
136
|
-
${prop("h1", "name", view.name)}
|
|
137
|
-
${metaTag("id", view.id)}
|
|
138
|
-
${metaTag("capability", view.capability)}
|
|
139
|
-
${propRaw(
|
|
140
|
-
"div",
|
|
141
|
-
"human",
|
|
142
|
-
`${openTag("div", { itemtype: "SkillHumanSection" })}
|
|
143
|
-
${prop("p", "description", view.description)}
|
|
144
|
-
${sections.join("\n")}
|
|
145
|
-
</div>`,
|
|
146
|
-
)}
|
|
147
|
-
</article>
|
|
148
|
-
</main>`;
|
|
149
|
-
|
|
150
|
-
return htmlDocument(view.name, body);
|
|
151
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stage formatting for microdata HTML output
|
|
3
|
-
*
|
|
4
|
-
* Generates clean, class-less HTML with microdata aligned with stages.schema.json
|
|
5
|
-
* RDF vocab: https://www.forwardimpact.team/schema/rdf/
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
openTag,
|
|
10
|
-
prop,
|
|
11
|
-
metaTag,
|
|
12
|
-
linkTag,
|
|
13
|
-
section,
|
|
14
|
-
ul,
|
|
15
|
-
escapeHtml,
|
|
16
|
-
htmlDocument,
|
|
17
|
-
} from "../microdata-shared.js";
|
|
18
|
-
import { prepareStagesList, prepareStageDetail } from "./shared.js";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Format stage list as microdata HTML
|
|
22
|
-
* @param {Array} stages - Raw stage entities
|
|
23
|
-
* @returns {string} HTML with microdata
|
|
24
|
-
*/
|
|
25
|
-
export function stageListToMicrodata(stages) {
|
|
26
|
-
const { items } = prepareStagesList(stages);
|
|
27
|
-
|
|
28
|
-
const content = items
|
|
29
|
-
.map((stage) => {
|
|
30
|
-
const handoffText =
|
|
31
|
-
stage.handoffs.length > 0
|
|
32
|
-
? `→ ${stage.handoffs.map((h) => h.target).join(", ")}`
|
|
33
|
-
: "";
|
|
34
|
-
return `${openTag("article", { itemtype: "Stage", itemid: `#${stage.id}` })}
|
|
35
|
-
${prop("h2", "name", `${stage.emojiIcon} ${stage.name}`)}
|
|
36
|
-
${prop("p", "description", stage.truncatedDescription)}
|
|
37
|
-
${handoffText ? `<p>Handoffs: ${handoffText}</p>` : ""}
|
|
38
|
-
</article>`;
|
|
39
|
-
})
|
|
40
|
-
.join("\n");
|
|
41
|
-
|
|
42
|
-
return htmlDocument(
|
|
43
|
-
"Stages",
|
|
44
|
-
`<main>
|
|
45
|
-
<h1>Stages</h1>
|
|
46
|
-
${content}
|
|
47
|
-
</main>`,
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Format stage detail as microdata HTML
|
|
53
|
-
* @param {Object} stage - Raw stage entity
|
|
54
|
-
* @returns {string} HTML with microdata
|
|
55
|
-
*/
|
|
56
|
-
export function stageToMicrodata(stage) {
|
|
57
|
-
const view = prepareStageDetail(stage);
|
|
58
|
-
|
|
59
|
-
if (!view) return "";
|
|
60
|
-
|
|
61
|
-
const sections = [];
|
|
62
|
-
|
|
63
|
-
// Read checklist
|
|
64
|
-
if (view.readChecklist.length > 0) {
|
|
65
|
-
const readItems = view.readChecklist.map((c) => escapeHtml(c));
|
|
66
|
-
sections.push(
|
|
67
|
-
section("Read-Then-Do Checklist", ul(readItems, "readChecklist"), 2),
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Constraints
|
|
72
|
-
if (view.constraints.length > 0) {
|
|
73
|
-
const constraintItems = view.constraints.map((c) => escapeHtml(c));
|
|
74
|
-
sections.push(
|
|
75
|
-
section("Constraints", ul(constraintItems, "constraints"), 2),
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Confirm checklist
|
|
80
|
-
if (view.confirmChecklist.length > 0) {
|
|
81
|
-
const confirmItems = view.confirmChecklist.map((c) => escapeHtml(c));
|
|
82
|
-
sections.push(
|
|
83
|
-
section(
|
|
84
|
-
"Do-Then-Confirm Checklist",
|
|
85
|
-
ul(confirmItems, "confirmChecklist"),
|
|
86
|
-
2,
|
|
87
|
-
),
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Handoffs - using Handoff itemtype
|
|
92
|
-
if (view.handoffs.length > 0) {
|
|
93
|
-
const handoffItems = view.handoffs.map(
|
|
94
|
-
(
|
|
95
|
-
h,
|
|
96
|
-
) => `${openTag("article", { itemtype: "Handoff", itemprop: "handoffs" })}
|
|
97
|
-
${linkTag("targetStage", `#${h.target}`)}
|
|
98
|
-
<p><strong>${prop("span", "label", h.label)}</strong> → ${escapeHtml(h.target)}</p>
|
|
99
|
-
${prop("p", "prompt", h.prompt)}
|
|
100
|
-
</article>`,
|
|
101
|
-
);
|
|
102
|
-
sections.push(section("Handoffs", handoffItems.join("\n"), 2));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const body = `<main>
|
|
106
|
-
${openTag("article", { itemtype: "Stage", itemid: `#${view.id}` })}
|
|
107
|
-
${prop("h1", "name", view.name)}
|
|
108
|
-
${metaTag("id", view.id)}
|
|
109
|
-
${stage.emojiIcon ? metaTag("emojiIcon", stage.emojiIcon) : ""}
|
|
110
|
-
${prop("p", "description", view.description)}
|
|
111
|
-
${sections.join("\n")}
|
|
112
|
-
</article>
|
|
113
|
-
</main>`;
|
|
114
|
-
|
|
115
|
-
return htmlDocument(view.name, body);
|
|
116
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Track formatting for microdata HTML output
|
|
3
|
-
*
|
|
4
|
-
* Generates clean, class-less HTML with microdata aligned with track.schema.json
|
|
5
|
-
* RDF vocab: https://www.forwardimpact.team/schema/rdf/
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
openTag,
|
|
10
|
-
prop,
|
|
11
|
-
metaTag,
|
|
12
|
-
linkTag,
|
|
13
|
-
section,
|
|
14
|
-
ul,
|
|
15
|
-
escapeHtml,
|
|
16
|
-
htmlDocument,
|
|
17
|
-
} from "../microdata-shared.js";
|
|
18
|
-
import { prepareTracksList, prepareTrackDetail } from "./shared.js";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Format track list as microdata HTML
|
|
22
|
-
* @param {Array} tracks - Raw track entities
|
|
23
|
-
* @returns {string} HTML with microdata
|
|
24
|
-
*/
|
|
25
|
-
export function trackListToMicrodata(tracks) {
|
|
26
|
-
const { items } = prepareTracksList(tracks);
|
|
27
|
-
|
|
28
|
-
const content = items
|
|
29
|
-
.map((track) => {
|
|
30
|
-
return `${openTag("article", { itemtype: "Track", itemid: `#${track.id}` })}
|
|
31
|
-
${prop("h2", "name", track.name)}
|
|
32
|
-
</article>`;
|
|
33
|
-
})
|
|
34
|
-
.join("\n");
|
|
35
|
-
|
|
36
|
-
return htmlDocument(
|
|
37
|
-
"Tracks",
|
|
38
|
-
`<main>
|
|
39
|
-
<h1>Tracks</h1>
|
|
40
|
-
${content}
|
|
41
|
-
</main>`,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Format track detail as microdata HTML
|
|
47
|
-
* @param {Object} track - Raw track entity
|
|
48
|
-
* @param {Object} context - Additional context
|
|
49
|
-
* @param {Array} context.skills - All skills
|
|
50
|
-
* @param {Array} context.behaviours - All behaviours
|
|
51
|
-
* @param {Array} context.disciplines - All disciplines
|
|
52
|
-
* @returns {string} HTML with microdata
|
|
53
|
-
*/
|
|
54
|
-
export function trackToMicrodata(track, { skills, behaviours, disciplines }) {
|
|
55
|
-
const view = prepareTrackDetail(track, { skills, behaviours, disciplines });
|
|
56
|
-
|
|
57
|
-
if (!view) return "";
|
|
58
|
-
|
|
59
|
-
const sections = [];
|
|
60
|
-
|
|
61
|
-
// Skill modifiers - using SkillModifier itemtype with targetCapability
|
|
62
|
-
if (view.skillModifiers.length > 0) {
|
|
63
|
-
const modifierItems = view.skillModifiers.map((m) => {
|
|
64
|
-
const modifierStr = m.modifier > 0 ? `+${m.modifier}` : `${m.modifier}`;
|
|
65
|
-
|
|
66
|
-
if (m.isCapability && m.skills && m.skills.length > 0) {
|
|
67
|
-
// Capability with expanded skills
|
|
68
|
-
const skillLinks = m.skills
|
|
69
|
-
.map(
|
|
70
|
-
(s) => `<a href="#${escapeHtml(s.id)}">${escapeHtml(s.name)}</a>`,
|
|
71
|
-
)
|
|
72
|
-
.join(", ");
|
|
73
|
-
return `${openTag("div", { itemtype: "SkillModifier", itemprop: "skillModifiers" })}
|
|
74
|
-
${linkTag("targetCapability", `#${m.id}`)}
|
|
75
|
-
<strong>${escapeHtml(m.name)} Capability</strong> (${openTag("span", { itemprop: "modifierValue" })}${modifierStr}</span>)
|
|
76
|
-
<p>${skillLinks}</p>
|
|
77
|
-
</div>`;
|
|
78
|
-
} else {
|
|
79
|
-
// Individual skill or capability without skills
|
|
80
|
-
return `${openTag("span", { itemtype: "SkillModifier", itemprop: "skillModifiers" })}
|
|
81
|
-
${linkTag("targetCapability", `#${m.id}`)}
|
|
82
|
-
<strong>${escapeHtml(m.name)}</strong>: ${openTag("span", { itemprop: "modifierValue" })}${modifierStr}</span>
|
|
83
|
-
</span>`;
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
sections.push(section("Skill Modifiers", modifierItems.join("\n"), 2));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Behaviour modifiers - using BehaviourModifier itemtype
|
|
90
|
-
if (view.behaviourModifiers.length > 0) {
|
|
91
|
-
const modifierItems = view.behaviourModifiers.map((b) => {
|
|
92
|
-
const modifierStr = b.modifier > 0 ? `+${b.modifier}` : `${b.modifier}`;
|
|
93
|
-
return `${openTag("span", { itemtype: "BehaviourModifier", itemprop: "behaviourModifiers" })}
|
|
94
|
-
${linkTag("targetBehaviour", `#${b.id}`)}
|
|
95
|
-
<a href="#${escapeHtml(b.id)}">${escapeHtml(b.name)}</a>: ${openTag("span", { itemprop: "modifierValue" })}${modifierStr}</span>
|
|
96
|
-
</span>`;
|
|
97
|
-
});
|
|
98
|
-
sections.push(section("Behaviour Modifiers", ul(modifierItems), 2));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const body = `<main>
|
|
102
|
-
${openTag("article", { itemtype: "Track", itemid: `#${view.id}` })}
|
|
103
|
-
${prop("h1", "name", view.name)}
|
|
104
|
-
${metaTag("id", view.id)}
|
|
105
|
-
${prop("p", "description", view.description)}
|
|
106
|
-
${sections.join("\n")}
|
|
107
|
-
</article>
|
|
108
|
-
</main>`;
|
|
109
|
-
|
|
110
|
-
return htmlDocument(view.name, body);
|
|
111
|
-
}
|