@forwardimpact/pathway 0.21.0 → 0.22.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.
Files changed (72) hide show
  1. package/README.md +3 -3
  2. package/bin/fit-pathway.js +22 -22
  3. package/package.json +3 -3
  4. package/src/commands/agent.js +7 -7
  5. package/src/commands/index.js +1 -1
  6. package/src/commands/init.js +1 -1
  7. package/src/commands/interview.js +8 -8
  8. package/src/commands/job.js +19 -19
  9. package/src/commands/level.js +60 -0
  10. package/src/commands/progress.js +20 -20
  11. package/src/commands/questions.js +3 -3
  12. package/src/components/action-buttons.js +3 -3
  13. package/src/components/builder.js +25 -25
  14. package/src/components/comparison-radar.js +3 -3
  15. package/src/components/detail.js +2 -2
  16. package/src/components/grid.js +1 -1
  17. package/src/components/radar-chart.js +3 -3
  18. package/src/components/skill-matrix.js +7 -7
  19. package/src/css/pages/landing.css +5 -5
  20. package/src/formatters/index.js +5 -5
  21. package/src/formatters/interview/shared.js +20 -20
  22. package/src/formatters/job/description.js +17 -17
  23. package/src/formatters/job/dom.js +12 -12
  24. package/src/formatters/job/markdown.js +7 -7
  25. package/src/formatters/json-ld.js +24 -24
  26. package/src/formatters/{grade → level}/dom.js +31 -27
  27. package/src/formatters/{grade → level}/markdown.js +19 -28
  28. package/src/formatters/{grade → level}/microdata.js +28 -38
  29. package/src/formatters/level/shared.js +86 -0
  30. package/src/formatters/progress/markdown.js +2 -2
  31. package/src/formatters/progress/shared.js +48 -48
  32. package/src/formatters/questions/markdown.js +8 -6
  33. package/src/formatters/questions/shared.js +7 -7
  34. package/src/formatters/skill/dom.js +4 -4
  35. package/src/formatters/skill/markdown.js +1 -1
  36. package/src/formatters/skill/microdata.js +3 -3
  37. package/src/formatters/skill/shared.js +2 -2
  38. package/src/handout-main.js +12 -12
  39. package/src/index.html +1 -1
  40. package/src/lib/card-mappers.js +16 -16
  41. package/src/lib/cli-command.js +3 -3
  42. package/src/lib/cli-output.js +2 -2
  43. package/src/lib/job-cache.js +11 -11
  44. package/src/lib/render.js +5 -5
  45. package/src/lib/state.js +2 -2
  46. package/src/lib/yaml-loader.js +9 -9
  47. package/src/main.js +10 -10
  48. package/src/pages/agent-builder.js +11 -11
  49. package/src/pages/assessment-results.js +27 -23
  50. package/src/pages/interview-builder.js +6 -6
  51. package/src/pages/interview.js +8 -8
  52. package/src/pages/job-builder.js +6 -6
  53. package/src/pages/job.js +7 -7
  54. package/src/pages/landing.js +8 -8
  55. package/src/pages/level.js +122 -0
  56. package/src/pages/progress-builder.js +8 -8
  57. package/src/pages/progress.js +74 -74
  58. package/src/pages/self-assessment.js +7 -7
  59. package/src/slide-main.js +22 -22
  60. package/src/slides/chapter.js +4 -4
  61. package/src/slides/index.js +10 -10
  62. package/src/slides/interview.js +2 -2
  63. package/src/slides/job.js +3 -3
  64. package/src/slides/level.js +32 -0
  65. package/src/slides/overview.js +9 -9
  66. package/src/slides/progress.js +13 -13
  67. package/src/types.js +1 -1
  68. package/templates/job.template.md +2 -2
  69. package/src/commands/grade.js +0 -60
  70. package/src/formatters/grade/shared.js +0 -86
  71. package/src/pages/grade.js +0 -122
  72. package/src/slides/grade.js +0 -32
@@ -11,31 +11,31 @@ import {
11
11
  import {
12
12
  analyzeProgression,
13
13
  analyzeCustomProgression,
14
- getNextGrade,
14
+ getNextLevel,
15
15
  } from "@forwardimpact/libpathway/progression";
16
16
  import { getOrCreateJob } from "@forwardimpact/libpathway/job-cache";
17
17
 
18
18
  /**
19
- * Get the next grade for progression
20
- * @param {Object} currentGrade
21
- * @param {Array} grades
19
+ * Get the next level for progression
20
+ * @param {Object} currentLevel
21
+ * @param {Array} levels
22
22
  * @returns {Object|null}
23
23
  */
24
- export function getDefaultTargetGrade(currentGrade, grades) {
25
- return getNextGrade(currentGrade, grades);
24
+ export function getDefaultTargetLevel(currentLevel, levels) {
25
+ return getNextLevel(currentLevel, levels);
26
26
  }
27
27
 
28
28
  /**
29
29
  * Check if a job combination is valid
30
30
  * @param {Object} params
31
31
  * @param {Object} params.discipline
32
- * @param {Object} params.grade
32
+ * @param {Object} params.level
33
33
  * @param {Object} params.track
34
- * @param {Array} [params.grades] - All grades for validation
34
+ * @param {Array} [params.levels] - All levels for validation
35
35
  * @returns {boolean}
36
36
  */
37
- export function isValidCombination({ discipline, grade, track, grades }) {
38
- return isValidJobCombination({ discipline, grade, track, grades });
37
+ export function isValidCombination({ discipline, level, track, levels }) {
38
+ return isValidJobCombination({ discipline, level, track, levels });
39
39
  }
40
40
 
41
41
  /**
@@ -52,7 +52,7 @@ export function isValidCombination({ discipline, grade, track, grades }) {
52
52
  * Prepare current job summary for progress detail page
53
53
  * @param {Object} params
54
54
  * @param {Object} params.discipline
55
- * @param {Object} params.grade
55
+ * @param {Object} params.level
56
56
  * @param {Object} params.track
57
57
  * @param {Array} params.skills
58
58
  * @param {Array} params.behaviours
@@ -61,17 +61,17 @@ export function isValidCombination({ discipline, grade, track, grades }) {
61
61
  */
62
62
  export function prepareCurrentJob({
63
63
  discipline,
64
- grade,
64
+ level,
65
65
  track,
66
66
  skills,
67
67
  behaviours,
68
68
  capabilities,
69
69
  }) {
70
- if (!discipline || !grade) return null;
70
+ if (!discipline || !level) return null;
71
71
 
72
72
  const job = getOrCreateJob({
73
73
  discipline,
74
- grade,
74
+ level,
75
75
  track,
76
76
  skills,
77
77
  behaviours,
@@ -96,7 +96,7 @@ export function prepareCurrentJob({
96
96
  * @property {boolean} isValid
97
97
  * @property {string|null} title
98
98
  * @property {string|null} invalidReason
99
- * @property {Object|null} nextGrade
99
+ * @property {Object|null} nextLevel
100
100
  * @property {Array} validTracks - Other valid tracks for comparison
101
101
  */
102
102
 
@@ -104,35 +104,35 @@ export function prepareCurrentJob({
104
104
  * Prepare career progress builder preview for form validation
105
105
  * @param {Object} params
106
106
  * @param {Object|null} params.discipline
107
- * @param {Object|null} params.grade
107
+ * @param {Object|null} params.level
108
108
  * @param {Object|null} params.track
109
- * @param {Array} params.grades - All grades
109
+ * @param {Array} params.levels - All levels
110
110
  * @param {Array} params.tracks - All tracks
111
111
  * @returns {CareerProgressPreview}
112
112
  */
113
113
  export function prepareCareerProgressPreview({
114
114
  discipline,
115
- grade,
115
+ level,
116
116
  track,
117
- grades,
117
+ levels,
118
118
  tracks,
119
119
  }) {
120
120
  // Track is optional (null = generalist)
121
- if (!discipline || !grade) {
121
+ if (!discipline || !level) {
122
122
  return {
123
123
  isValid: false,
124
124
  title: null,
125
125
  invalidReason: null,
126
- nextGrade: null,
126
+ nextLevel: null,
127
127
  validTracks: [],
128
128
  };
129
129
  }
130
130
 
131
131
  const validCombination = isValidJobCombination({
132
132
  discipline,
133
- grade,
133
+ level,
134
134
  track,
135
- grades,
135
+ levels,
136
136
  });
137
137
 
138
138
  if (!validCombination) {
@@ -143,27 +143,27 @@ export function prepareCareerProgressPreview({
143
143
  isValid: false,
144
144
  title: null,
145
145
  invalidReason: reason,
146
- nextGrade: null,
146
+ nextLevel: null,
147
147
  validTracks: [],
148
148
  };
149
149
  }
150
150
 
151
- const title = generateJobTitle(discipline, grade, track);
152
- const nextGrade = getNextGrade(grade, grades);
151
+ const title = generateJobTitle(discipline, level, track);
152
+ const nextLevel = getNextLevel(level, levels);
153
153
 
154
154
  // Find other valid tracks for comparison (exclude current track if any)
155
155
  const validTracks = tracks.filter(
156
156
  (t) =>
157
157
  (!track || t.id !== track.id) &&
158
- isValidJobCombination({ discipline, grade, track: t, grades }),
158
+ isValidJobCombination({ discipline, level, track: t, levels }),
159
159
  );
160
160
 
161
161
  return {
162
162
  isValid: true,
163
163
  title,
164
164
  invalidReason: null,
165
- nextGrade: nextGrade
166
- ? { id: nextGrade.id, name: nextGrade.managementTitle }
165
+ nextLevel: nextLevel
166
+ ? { id: nextLevel.id, name: nextLevel.managementTitle }
167
167
  : null,
168
168
  validTracks: validTracks.map((t) => ({ id: t.id, name: t.name })),
169
169
  };
@@ -184,10 +184,10 @@ export function prepareCareerProgressPreview({
184
184
  * Prepare career progression between two roles
185
185
  * @param {Object} params
186
186
  * @param {Object} params.fromDiscipline
187
- * @param {Object} params.fromGrade
187
+ * @param {Object} params.fromLevel
188
188
  * @param {Object} params.fromTrack
189
189
  * @param {Object} params.toDiscipline
190
- * @param {Object} params.toGrade
190
+ * @param {Object} params.toLevel
191
191
  * @param {Object} params.toTrack
192
192
  * @param {Array} params.skills
193
193
  * @param {Array} params.behaviours
@@ -196,22 +196,22 @@ export function prepareCareerProgressPreview({
196
196
  */
197
197
  export function prepareProgressDetail({
198
198
  fromDiscipline,
199
- fromGrade,
199
+ fromLevel,
200
200
  fromTrack,
201
201
  toDiscipline,
202
- toGrade,
202
+ toLevel,
203
203
  toTrack,
204
204
  skills,
205
205
  behaviours,
206
206
  capabilities,
207
207
  }) {
208
208
  // Track is optional (null = generalist)
209
- if (!fromDiscipline || !fromGrade) return null;
210
- if (!toDiscipline || !toGrade) return null;
209
+ if (!fromDiscipline || !fromLevel) return null;
210
+ if (!toDiscipline || !toLevel) return null;
211
211
 
212
212
  const fromJob = getOrCreateJob({
213
213
  discipline: fromDiscipline,
214
- grade: fromGrade,
214
+ level: fromLevel,
215
215
  track: fromTrack,
216
216
  skills,
217
217
  behaviours,
@@ -220,7 +220,7 @@ export function prepareProgressDetail({
220
220
 
221
221
  const toJob = getOrCreateJob({
222
222
  discipline: toDiscipline,
223
- grade: toGrade,
223
+ level: toLevel,
224
224
  track: toTrack,
225
225
  skills,
226
226
  behaviours,
@@ -238,7 +238,7 @@ export function prepareProgressDetail({
238
238
  type: s.type,
239
239
  fromLevel: s.currentLevel,
240
240
  toLevel: s.targetLevel,
241
- levelChange: s.change,
241
+ proficiencyChange: s.change,
242
242
  }));
243
243
 
244
244
  // Transform behaviour changes
@@ -251,12 +251,12 @@ export function prepareProgressDetail({
251
251
  }));
252
252
 
253
253
  const summary = {
254
- skillsToImprove: skillChanges.filter((s) => s.levelChange > 0).length,
254
+ skillsToImprove: skillChanges.filter((s) => s.proficiencyChange > 0).length,
255
255
  behavioursToImprove: behaviourChanges.filter((b) => b.maturityChange > 0)
256
256
  .length,
257
257
  newSkills: skillChanges.filter((s) => !s.fromLevel && s.toLevel).length,
258
258
  totalChanges:
259
- skillChanges.filter((s) => s.levelChange !== 0).length +
259
+ skillChanges.filter((s) => s.proficiencyChange !== 0).length +
260
260
  behaviourChanges.filter((b) => b.maturityChange !== 0).length,
261
261
  };
262
262
 
@@ -265,12 +265,12 @@ export function prepareProgressDetail({
265
265
  toTitle: toJob.title,
266
266
  fromJob: {
267
267
  disciplineId: fromDiscipline.id,
268
- gradeId: fromGrade.id,
268
+ levelId: fromLevel.id,
269
269
  trackId: fromTrack?.id || null,
270
270
  },
271
271
  toJob: {
272
272
  disciplineId: toDiscipline.id,
273
- gradeId: toGrade.id,
273
+ levelId: toLevel.id,
274
274
  trackId: toTrack?.id || null,
275
275
  },
276
276
  skillChanges,
@@ -292,10 +292,10 @@ export function prepareProgressDetail({
292
292
  * Prepare custom progression analysis between any two roles
293
293
  * @param {Object} params
294
294
  * @param {Object} params.discipline - Current discipline
295
- * @param {Object} params.currentGrade
295
+ * @param {Object} params.currentLevel
296
296
  * @param {Object} params.currentTrack
297
297
  * @param {Object} params.targetDiscipline
298
- * @param {Object} params.targetGrade
298
+ * @param {Object} params.targetLevel
299
299
  * @param {Object} params.targetTrack
300
300
  * @param {Array} params.skills
301
301
  * @param {Array} params.behaviours
@@ -303,20 +303,20 @@ export function prepareProgressDetail({
303
303
  */
304
304
  export function prepareCustomProgression({
305
305
  discipline,
306
- currentGrade,
306
+ currentLevel,
307
307
  currentTrack,
308
308
  targetDiscipline,
309
- targetGrade,
309
+ targetLevel,
310
310
  targetTrack,
311
311
  skills,
312
312
  behaviours,
313
313
  }) {
314
314
  const analysis = analyzeCustomProgression({
315
315
  discipline,
316
- currentGrade,
316
+ currentLevel,
317
317
  currentTrack,
318
318
  targetDiscipline,
319
- targetGrade,
319
+ targetLevel,
320
320
  targetTrack,
321
321
  skills,
322
322
  behaviours,
@@ -4,7 +4,7 @@
4
4
  * Formats questions for terminal output as tables and lists.
5
5
  */
6
6
 
7
- import { SKILL_LEVELS, BEHAVIOUR_MATURITIES } from "./shared.js";
7
+ import { SKILL_PROFICIENCIES, BEHAVIOUR_MATURITIES } from "./shared.js";
8
8
 
9
9
  /**
10
10
  * Level abbreviations for compact display
@@ -67,7 +67,7 @@ function formatStats(view, skills) {
67
67
  // Header
68
68
  const skillHeader =
69
69
  pad("Skill", 30) +
70
- SKILL_LEVELS.map((l) => pad(LEVEL_ABBREVS[l], 7)).join("") +
70
+ SKILL_PROFICIENCIES.map((l) => pad(LEVEL_ABBREVS[l], 7)).join("") +
71
71
  "TOTAL";
72
72
  lines.push(skillHeader);
73
73
  lines.push("─".repeat(75));
@@ -84,7 +84,7 @@ function formatStats(view, skills) {
84
84
 
85
85
  const row =
86
86
  pad(name, 30) +
87
- SKILL_LEVELS.map((l) => {
87
+ SKILL_PROFICIENCIES.map((l) => {
88
88
  const count = skillData[l] || 0;
89
89
  levelTotals[l] = (levelTotals[l] || 0) + count;
90
90
  return pad(String(count), 7);
@@ -98,7 +98,9 @@ function formatStats(view, skills) {
98
98
  lines.push("─".repeat(75));
99
99
  const totalsRow =
100
100
  pad("TOTAL", 30) +
101
- SKILL_LEVELS.map((l) => pad(String(levelTotals[l] || 0), 7)).join("") +
101
+ SKILL_PROFICIENCIES.map((l) => pad(String(levelTotals[l] || 0), 7)).join(
102
+ "",
103
+ ) +
102
104
  String(skillTotal);
103
105
  lines.push(totalsRow);
104
106
  lines.push("");
@@ -150,7 +152,7 @@ function formatStats(view, skills) {
150
152
  const gaps = [];
151
153
  for (const skillId of sortedSkillIds) {
152
154
  const skillData = stats.skillStats[skillId];
153
- for (const level of SKILL_LEVELS) {
155
+ for (const level of SKILL_PROFICIENCIES) {
154
156
  if ((skillData[level] || 0) < 1) {
155
157
  gaps.push(`${skillId}: missing ${level} questions`);
156
158
  }
@@ -250,7 +252,7 @@ function formatSingleSource(view) {
250
252
  }
251
253
 
252
254
  const orderedLevels =
253
- sourceType === "skill" ? SKILL_LEVELS : BEHAVIOUR_MATURITIES;
255
+ sourceType === "skill" ? SKILL_PROFICIENCIES : BEHAVIOUR_MATURITIES;
254
256
 
255
257
  for (const level of orderedLevels) {
256
258
  if (!byLevel[level]) continue;
@@ -5,9 +5,9 @@
5
5
  */
6
6
 
7
7
  /**
8
- * Skill levels in order
8
+ * Skill proficiencies in order
9
9
  */
10
- export const SKILL_LEVELS = [
10
+ export const SKILL_PROFICIENCIES = [
11
11
  "awareness",
12
12
  "foundational",
13
13
  "working",
@@ -28,7 +28,7 @@ export const BEHAVIOUR_MATURITIES = [
28
28
 
29
29
  /**
30
30
  * @typedef {Object} QuestionsFilter
31
- * @property {string|null} level - Skill level filter
31
+ * @property {string|null} level - Skill proficiency filter
32
32
  * @property {string|null} maturity - Behaviour maturity filter
33
33
  * @property {string[]|null} skills - Skill IDs to include
34
34
  * @property {string[]|null} behaviours - Behaviour IDs to include
@@ -40,7 +40,7 @@ export const BEHAVIOUR_MATURITIES = [
40
40
  * @property {string} source - Source skill/behaviour ID
41
41
  * @property {string} sourceName - Source skill/behaviour name
42
42
  * @property {string} sourceType - 'skill' or 'behaviour'
43
- * @property {string} level - Skill level or behaviour maturity
43
+ * @property {string} level - Skill proficiency or behaviour maturity
44
44
  * @property {string} id - Question ID
45
45
  * @property {string} text - Question text
46
46
  * @property {string[]} lookingFor - Expected answer indicators
@@ -124,7 +124,7 @@ export function flattenQuestions(questionBank, skills, behaviours, filter) {
124
124
 
125
125
  // Process skill questions
126
126
  for (const [skillId, roleTypes] of Object.entries(
127
- questionBank.skillLevels || {},
127
+ questionBank.skillProficiencies || {},
128
128
  )) {
129
129
  const skillName = getSkillName(skillId, skills);
130
130
  const capability = getSkillCapability(skillId, skills);
@@ -218,10 +218,10 @@ export function calculateStats(questions, questionBank) {
218
218
  // Calculate full stats for skills and behaviours
219
219
  const skillStats = {};
220
220
  for (const [skillId, roleTypes] of Object.entries(
221
- questionBank.skillLevels || {},
221
+ questionBank.skillProficiencies || {},
222
222
  )) {
223
223
  skillStats[skillId] = {};
224
- for (const level of SKILL_LEVELS) {
224
+ for (const level of SKILL_PROFICIENCIES) {
225
225
  let count = 0;
226
226
  for (const roleType of ROLE_TYPES) {
227
227
  count += (roleTypes[roleType]?.[level] || []).length;
@@ -20,7 +20,7 @@ import { createBackLink } from "../../components/nav.js";
20
20
  import { createLevelCell } from "../../components/detail.js";
21
21
  import { createSkillFileViewer } from "../../components/skill-file-viewer.js";
22
22
  import { createToolIcon } from "../../lib/card-mappers.js";
23
- import { SKILL_LEVEL_ORDER } from "@forwardimpact/map/levels";
23
+ import { SKILL_PROFICIENCY_ORDER } from "@forwardimpact/map/levels";
24
24
  import { prepareSkillDetail } from "./shared.js";
25
25
  import { createJsonLdScript, skillToJsonLd } from "../json-ld.js";
26
26
 
@@ -97,11 +97,11 @@ export function skillToDOM(
97
97
  thead({}, tr({}, th({}, "Level"), th({}, "Description"))),
98
98
  tbody(
99
99
  {},
100
- ...SKILL_LEVEL_ORDER.map((level, index) => {
101
- const description = view.levelDescriptions[level] || "—";
100
+ ...SKILL_PROFICIENCY_ORDER.map((level, index) => {
101
+ const description = view.proficiencyDescriptions[level] || "—";
102
102
  return tr(
103
103
  {},
104
- createLevelCell(index + 1, SKILL_LEVEL_ORDER.length, level),
104
+ createLevelCell(index + 1, SKILL_PROFICIENCY_ORDER.length, level),
105
105
  td({}, description),
106
106
  );
107
107
  }),
@@ -71,7 +71,7 @@ export function skillToMarkdown(
71
71
 
72
72
  // Level descriptions table
73
73
  lines.push("## Level Descriptions", "");
74
- const levelRows = Object.entries(view.levelDescriptions).map(
74
+ const levelRows = Object.entries(view.proficiencyDescriptions).map(
75
75
  ([level, desc]) => [capitalize(level), desc],
76
76
  );
77
77
  lines.push(tableToMarkdown(["Level", "Description"], levelRows));
@@ -87,8 +87,8 @@ export function skillToMicrodata(
87
87
  ${metaTag("isHumanOnly", "true")}`);
88
88
  }
89
89
 
90
- // Level descriptions - uses LevelDescriptions itemtype
91
- const levelPairs = Object.entries(view.levelDescriptions).map(
90
+ // Level descriptions - uses ProficiencyDescriptions itemtype
91
+ const levelPairs = Object.entries(view.proficiencyDescriptions).map(
92
92
  ([level, desc]) => ({
93
93
  term: formatLevelName(level),
94
94
  definition: desc,
@@ -98,7 +98,7 @@ ${metaTag("isHumanOnly", "true")}`);
98
98
  sections.push(
99
99
  section(
100
100
  "Level Descriptions",
101
- `${openTag("div", { itemtype: "LevelDescriptions", itemprop: "levelDescriptions" })}
101
+ `${openTag("div", { itemtype: "ProficiencyDescriptions", itemprop: "proficiencyDescriptions" })}
102
102
  ${dl(levelPairs)}
103
103
  </div>`,
104
104
  2,
@@ -69,7 +69,7 @@ export function prepareSkillsList(
69
69
  * @property {string} capabilityName
70
70
  * @property {boolean} isHumanOnly
71
71
  * @property {string} capabilityEmoji
72
- * @property {Object<string, string>} levelDescriptions
72
+ * @property {Object<string, string>} proficiencyDescriptions
73
73
  * @property {Array<{id: string, name: string, skillType: string}>} relatedDisciplines
74
74
  * @property {Array<{id: string, name: string, modifier: number}>} relatedTracks
75
75
  * @property {Array<{id: string, name: string}>} relatedDrivers
@@ -124,7 +124,7 @@ export function prepareSkillDetail(
124
124
  capabilityName: capabilityEntity?.name || skill.capability,
125
125
  isHumanOnly: skill.isHumanOnly || false,
126
126
  capabilityEmoji: getCapabilityEmoji(capabilities, skill.capability),
127
- levelDescriptions: skill.levelDescriptions,
127
+ proficiencyDescriptions: skill.proficiencyDescriptions,
128
128
  relatedDisciplines,
129
129
  relatedTracks,
130
130
  relatedDrivers,
@@ -7,7 +7,7 @@
7
7
  * /driver - All driver slides
8
8
  * /skill - All skill slides
9
9
  * /behaviour - All behaviour slides
10
- * /job - All discipline, track, and grade slides
10
+ * /job - All discipline, track, and level slides
11
11
  */
12
12
 
13
13
  import { setData, getState } from "./lib/state.js";
@@ -33,7 +33,7 @@ import {
33
33
  skillToDOM,
34
34
  behaviourToDOM,
35
35
  disciplineToDOM,
36
- gradeToDOM,
36
+ levelToDOM,
37
37
  trackToDOM,
38
38
  } from "./formatters/index.js";
39
39
  import { sortTracksByName } from "./formatters/track/shared.js";
@@ -135,7 +135,7 @@ function renderIndex(data) {
135
135
  `${getConceptEmoji(framework, "job")} ${framework.entityDefinitions.job.title}`,
136
136
  ),
137
137
  " - ",
138
- `${data.disciplines.length} disciplines, ${data.grades.length} grades, ${data.tracks.length} tracks`,
138
+ `${data.disciplines.length} disciplines, ${data.levels.length} levels, ${data.tracks.length} tracks`,
139
139
  ),
140
140
  li(
141
141
  {},
@@ -284,7 +284,7 @@ function sortDisciplinesByType(disciplines) {
284
284
  }
285
285
 
286
286
  /**
287
- * Render all job component slides (disciplines, grades, tracks)
287
+ * Render all job component slides (disciplines, levels, tracks)
288
288
  * @param {Object} data
289
289
  */
290
290
  function renderJobHandout(data) {
@@ -303,8 +303,8 @@ function renderJobHandout(data) {
303
303
  });
304
304
  });
305
305
 
306
- const gradeSlides = data.grades.map((grade) => {
307
- return gradeToDOM(grade, {
306
+ const levelSlides = data.levels.map((level) => {
307
+ return levelToDOM(level, {
308
308
  framework: data.framework,
309
309
  showBackLink: false,
310
310
  });
@@ -329,15 +329,15 @@ function renderJobHandout(data) {
329
329
  }),
330
330
  ...disciplineSlides,
331
331
 
332
- // Grades chapter (moved before Tracks)
332
+ // Levels chapter (moved before Tracks)
333
333
  createChapterCover({
334
- emojiIcon: getConceptEmoji(framework, "grade"),
335
- title: framework.entityDefinitions.grade.title,
336
- description: framework.entityDefinitions.grade.description,
334
+ emojiIcon: getConceptEmoji(framework, "level"),
335
+ title: framework.entityDefinitions.level.title,
336
+ description: framework.entityDefinitions.level.description,
337
337
  }),
338
- ...gradeSlides,
338
+ ...levelSlides,
339
339
 
340
- // Tracks chapter (moved after Grades)
340
+ // Tracks chapter (moved after Levels)
341
341
  createChapterCover({
342
342
  emojiIcon: getConceptEmoji(framework, "track"),
343
343
  title: framework.entityDefinitions.track.title,
package/src/index.html CHANGED
@@ -83,7 +83,7 @@
83
83
  <div class="drawer-section">
84
84
  <span class="drawer-section-label">Browse</span>
85
85
  <a href="#/discipline">Disciplines</a>
86
- <a href="#/grade">Grades</a>
86
+ <a href="#/level">Levels</a>
87
87
  <a href="#/track">Tracks</a>
88
88
  <a href="#/behaviour">Behaviours</a>
89
89
  <a href="#/skill">Skills</a>
@@ -109,31 +109,31 @@ export function driverToCardConfig(driver) {
109
109
  }
110
110
 
111
111
  /**
112
- * Map grade to card config (for timeline)
113
- * @param {Object} grade
112
+ * Map level to card config (for timeline)
113
+ * @param {Object} level
114
114
  * @returns {Object}
115
115
  */
116
- export function gradeToCardConfig(grade) {
116
+ export function levelToCardConfig(level) {
117
117
  return {
118
- title: grade.displayName,
119
- description: grade.scope || grade.truncatedDescription,
120
- href: `/grade/${grade.id}`,
121
- badges: [createBadge(grade.id, "default")],
118
+ title: level.displayName,
119
+ description: level.scope || level.truncatedDescription,
120
+ href: `/level/${level.id}`,
121
+ badges: [createBadge(level.id, "default")],
122
122
  meta: [
123
123
  createBadge(
124
- `Primary: ${formatLevel(grade.baseSkillLevels?.primary)}`,
124
+ `Primary: ${formatLevel(level.baseSkillProficiencies?.primary)}`,
125
125
  "primary",
126
126
  ),
127
127
  createBadge(
128
- `Secondary: ${formatLevel(grade.baseSkillLevels?.secondary)}`,
128
+ `Secondary: ${formatLevel(level.baseSkillProficiencies?.secondary)}`,
129
129
  "secondary",
130
130
  ),
131
131
  createBadge(
132
- `Broad: ${formatLevel(grade.baseSkillLevels?.broad)}`,
132
+ `Broad: ${formatLevel(level.baseSkillProficiencies?.broad)}`,
133
133
  "broad",
134
134
  ),
135
135
  ],
136
- yearsExperience: grade.yearsExperience,
136
+ yearsExperience: level.yearsExperience,
137
137
  };
138
138
  }
139
139
 
@@ -158,15 +158,15 @@ export function trackToCardConfig(track) {
158
158
  */
159
159
  export function jobToCardConfig(job) {
160
160
  const href = job.track
161
- ? `/job/${job.discipline.id}/${job.grade.id}/${job.track.id}`
162
- : `/job/${job.discipline.id}/${job.grade.id}`;
161
+ ? `/job/${job.discipline.id}/${job.level.id}/${job.track.id}`
162
+ : `/job/${job.discipline.id}/${job.level.id}`;
163
163
  return {
164
164
  title: job.title,
165
165
  description: job.track
166
- ? `${job.discipline.specialization || job.discipline.name} at ${job.grade.professionalTitle} level on ${job.track.name} track`
167
- : `${job.discipline.specialization || job.discipline.name} at ${job.grade.professionalTitle} level`,
166
+ ? `${job.discipline.specialization || job.discipline.name} at ${job.level.professionalTitle} level on ${job.track.name} track`
167
+ : `${job.discipline.specialization || job.discipline.name} at ${job.level.professionalTitle} level`,
168
168
  href,
169
- badges: [createBadge(job.grade.id, "default")],
169
+ badges: [createBadge(job.level.id, "default")],
170
170
  meta: job.track ? [createBadge(job.track.name, "secondary")] : [],
171
171
  };
172
172
  }
@@ -21,7 +21,7 @@ const ROUTE_COMMANDS = [
21
21
  toCommand: () => "npx fit-pathway discipline",
22
22
  },
23
23
  { pattern: /^\/track$/, toCommand: () => "npx fit-pathway track" },
24
- { pattern: /^\/grade$/, toCommand: () => "npx fit-pathway grade" },
24
+ { pattern: /^\/level$/, toCommand: () => "npx fit-pathway level" },
25
25
  { pattern: /^\/driver$/, toCommand: () => "npx fit-pathway driver" },
26
26
  { pattern: /^\/stage$/, toCommand: () => "npx fit-pathway stage" },
27
27
  { pattern: /^\/tool$/, toCommand: () => "npx fit-pathway tool" },
@@ -44,8 +44,8 @@ const ROUTE_COMMANDS = [
44
44
  toCommand: (m) => `npx fit-pathway track ${m[1]}`,
45
45
  },
46
46
  {
47
- pattern: /^\/grade\/(.+)$/,
48
- toCommand: (m) => `npx fit-pathway grade ${m[1]}`,
47
+ pattern: /^\/level\/(.+)$/,
48
+ toCommand: (m) => `npx fit-pathway level ${m[1]}`,
49
49
  },
50
50
  {
51
51
  pattern: /^\/driver\/(.+)$/,
@@ -126,11 +126,11 @@ export function formatTable(headers, rows, options = {}) {
126
126
  }
127
127
 
128
128
  /**
129
- * Format skill level with color
129
+ * Format skill proficiency with color
130
130
  * @param {string} level
131
131
  * @returns {string}
132
132
  */
133
- export function formatSkillLevel(level) {
133
+ export function formatSkillProficiency(level) {
134
134
  const levelColors = {
135
135
  awareness: colors.gray,
136
136
  foundational: colors.blue,