@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.
Files changed (34) hide show
  1. package/bin/fit-pathway.js +62 -54
  2. package/package.json +1 -3
  3. package/src/commands/agent-io.js +120 -0
  4. package/src/commands/agent.js +266 -349
  5. package/src/commands/init.js +2 -2
  6. package/src/commands/job.js +237 -183
  7. package/src/components/comparison-radar.js +118 -103
  8. package/src/components/progression-table.js +244 -208
  9. package/src/formatters/index.js +0 -19
  10. package/src/formatters/interview/markdown.js +100 -88
  11. package/src/formatters/job/description.js +76 -75
  12. package/src/formatters/job/dom.js +113 -97
  13. package/src/formatters/level/dom.js +87 -102
  14. package/src/formatters/questions/markdown.js +37 -33
  15. package/src/formatters/questions/shared.js +142 -75
  16. package/src/formatters/skill/dom.js +102 -93
  17. package/src/lib/comparison-radar-chart.js +256 -0
  18. package/src/lib/radar-utils.js +199 -0
  19. package/src/lib/radar.js +25 -662
  20. package/src/pages/agent-builder-download.js +170 -0
  21. package/src/pages/agent-builder-preview.js +344 -0
  22. package/src/pages/agent-builder.js +6 -550
  23. package/src/pages/progress-comparison.js +110 -0
  24. package/src/pages/progress.js +11 -111
  25. package/src/pages/self-assessment-steps.js +494 -0
  26. package/src/pages/self-assessment.js +54 -504
  27. package/src/formatters/behaviour/microdata.js +0 -106
  28. package/src/formatters/discipline/microdata.js +0 -117
  29. package/src/formatters/driver/microdata.js +0 -91
  30. package/src/formatters/level/microdata.js +0 -141
  31. package/src/formatters/microdata-shared.js +0 -184
  32. package/src/formatters/skill/microdata.js +0 -151
  33. package/src/formatters/stage/microdata.js +0 -116
  34. 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
- }