@forwardimpact/pathway 0.25.21 → 0.25.24
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 +117 -325
- package/package.json +2 -2
- package/src/commands/agent-io.js +1 -1
- package/src/commands/agent.js +25 -23
- package/src/commands/behaviour.js +7 -7
- package/src/commands/build-bundle.js +88 -0
- package/src/commands/build-packs.js +566 -0
- package/src/commands/build.js +27 -84
- package/src/commands/command-factory.js +2 -2
- package/src/commands/discipline.js +7 -7
- package/src/commands/driver.js +8 -8
- package/src/commands/index.js +0 -1
- package/src/commands/interview.js +4 -4
- package/src/commands/job.js +24 -18
- package/src/commands/level.js +7 -7
- package/src/commands/progress.js +4 -4
- package/src/commands/questions.js +10 -8
- package/src/commands/skill.js +10 -10
- package/src/commands/stage.js +7 -7
- package/src/commands/tool.js +6 -6
- package/src/commands/track.js +7 -7
- package/src/css/pages/agent-builder.css +48 -0
- package/src/formatters/interview/shared.js +6 -4
- package/src/formatters/progress/shared.js +9 -20
- package/src/formatters/questions/yaml.js +1 -1
- package/src/formatters/skill/shared.js +9 -2
- package/src/formatters/track/shared.js +4 -1
- package/src/index.html +1 -1
- package/src/lib/cli-command.js +33 -33
- package/src/lib/cli-output.js +9 -189
- package/src/pages/agent-builder-install.js +118 -0
- package/src/pages/agent-builder-preview.js +3 -3
- package/src/pages/agent-builder.js +23 -1
- package/src/pages/progress.js +3 -3
- package/src/pages/skill.js +5 -2
- package/src/commands/init.js +0 -64
- package/src/lib/job-cache.js +0 -89
- package/starter/behaviours/systems_thinking.yaml +0 -32
- package/starter/capabilities/delivery.yaml +0 -105
- package/starter/capabilities/reliability.yaml +0 -72
- package/starter/disciplines/software_engineering.yaml +0 -46
- package/starter/drivers.yaml +0 -10
- package/starter/framework.yaml +0 -49
- package/starter/levels.yaml +0 -39
- package/starter/questions/behaviours/.gitkeep +0 -0
- package/starter/questions/capabilities/.gitkeep +0 -0
- package/starter/questions/skills/.gitkeep +0 -0
- package/starter/stages.yaml +0 -21
- package/starter/tracks/forward_deployed.yaml +0 -33
- package/starter/tracks/platform.yaml +0 -33
|
@@ -89,7 +89,7 @@ export function createEntityCommand({
|
|
|
89
89
|
function handleValidate({ data, _entityName, pluralName, validate }) {
|
|
90
90
|
if (!validate) {
|
|
91
91
|
console.log(`No specific validation for ${pluralName}.`);
|
|
92
|
-
console.log(`Run '
|
|
92
|
+
console.log(`Run 'npx fit-pathway --validate' for full data validation.`);
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -178,7 +178,7 @@ export function createCompositeCommand({
|
|
|
178
178
|
return async function runCommand({ data, args, options }) {
|
|
179
179
|
if (args.length < requiredArgs.length) {
|
|
180
180
|
const argsList = requiredArgs.map((arg) => `<${arg}>`).join(" ");
|
|
181
|
-
console.error(`Usage:
|
|
181
|
+
console.error(`Usage: npx fit-pathway ${commandName} ${argsList}`);
|
|
182
182
|
if (usageExample) {
|
|
183
183
|
console.error(`Example: ${usageExample}`);
|
|
184
184
|
}
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
* Handles discipline summary, listing, and detail display in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* npx fit-pathway discipline # Summary with stats
|
|
8
|
+
* npx fit-pathway discipline --list # IDs only (for piping)
|
|
9
|
+
* npx fit-pathway discipline <id> # Detail view
|
|
10
|
+
* npx fit-pathway discipline --validate # Validation checks
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { createEntityCommand } from "./command-factory.js";
|
|
14
14
|
import { disciplineToMarkdown } from "../formatters/discipline/markdown.js";
|
|
15
|
-
import { formatTable } from "
|
|
15
|
+
import { formatTable } from "@forwardimpact/libcli";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Format discipline list item for --list output
|
|
@@ -43,8 +43,8 @@ function formatSummary(disciplines) {
|
|
|
43
43
|
|
|
44
44
|
console.log(formatTable(["ID", "Specialization", "Type", "Tracks"], rows));
|
|
45
45
|
console.log(`\nTotal: ${disciplines.length} disciplines`);
|
|
46
|
-
console.log(`\nRun '
|
|
47
|
-
console.log(`Run '
|
|
46
|
+
console.log(`\nRun 'npx fit-pathway discipline --list' for IDs and names`);
|
|
47
|
+
console.log(`Run 'npx fit-pathway discipline <id>' for details\n`);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
package/src/commands/driver.js
CHANGED
|
@@ -4,20 +4,20 @@
|
|
|
4
4
|
* Handles driver summary, listing, and detail display in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* npx fit-pathway driver # Summary with stats
|
|
8
|
+
* npx fit-pathway driver --list # IDs only (for piping)
|
|
9
|
+
* npx fit-pathway driver <id> # Detail view
|
|
10
|
+
* npx fit-pathway driver --validate # Validation checks
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { createEntityCommand } from "./command-factory.js";
|
|
14
14
|
import { prepareDriverDetail } from "../formatters/driver/shared.js";
|
|
15
|
-
import { formatTable } from "../lib/cli-output.js";
|
|
16
15
|
import {
|
|
16
|
+
formatTable,
|
|
17
17
|
formatHeader,
|
|
18
18
|
formatSubheader,
|
|
19
19
|
formatBullet,
|
|
20
|
-
} from "
|
|
20
|
+
} from "@forwardimpact/libcli";
|
|
21
21
|
import { getConceptEmoji } from "@forwardimpact/map/levels";
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -52,8 +52,8 @@ function formatSummary(drivers, data) {
|
|
|
52
52
|
|
|
53
53
|
console.log(formatTable(["ID", "Name", "Skills", "Behaviours"], rows));
|
|
54
54
|
console.log(`\nTotal: ${drivers.length} drivers`);
|
|
55
|
-
console.log(`\nRun '
|
|
56
|
-
console.log(`Run '
|
|
55
|
+
console.log(`\nRun 'npx fit-pathway driver --list' for IDs and names`);
|
|
56
|
+
console.log(`Run 'npx fit-pathway driver <id>' for details\n`);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
package/src/commands/index.js
CHANGED
|
@@ -17,6 +17,5 @@ export { runInterviewCommand } from "./interview.js";
|
|
|
17
17
|
export { runProgressCommand } from "./progress.js";
|
|
18
18
|
export { runQuestionsCommand } from "./questions.js";
|
|
19
19
|
export { runServeCommand } from "./serve.js";
|
|
20
|
-
export { runInitCommand } from "./init.js";
|
|
21
20
|
export { runSiteCommand } from "./site.js";
|
|
22
21
|
export { runUpdateCommand } from "./update.js";
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Generates and displays interview questions in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* npx fit-pathway interview <discipline> <level> # All interview types
|
|
8
|
+
* npx fit-pathway interview <discipline> <level> --track=<track> # With track
|
|
9
|
+
* npx fit-pathway interview <discipline> <level> --track=<track> --type=mission # Single type
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { createCompositeCommand } from "./command-factory.js";
|
|
@@ -109,5 +109,5 @@ export const runInterviewCommand = createCompositeCommand({
|
|
|
109
109
|
}
|
|
110
110
|
},
|
|
111
111
|
usageExample:
|
|
112
|
-
"
|
|
112
|
+
"npx fit-pathway interview software_engineering J090 --track=platform --type=mission",
|
|
113
113
|
});
|
package/src/commands/job.js
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Generates and displays job definitions in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
7
|
+
* npx fit-pathway job # Summary with stats
|
|
8
|
+
* npx fit-pathway job --list # All valid combinations (for piping)
|
|
9
|
+
* npx fit-pathway job <discipline> <level> # Detail view (trackless)
|
|
10
|
+
* npx fit-pathway job <discipline> <level> --track=<track> # Detail view (with track)
|
|
11
|
+
* npx fit-pathway job <d> <l> [--track=<t>] --skills # Plain list of skill IDs
|
|
12
|
+
* npx fit-pathway job <d> <l> [--track=<t>] --tools # Plain list of tool names
|
|
13
|
+
* npx fit-pathway job se L3 --track=platform --checklist=code # Show checklist for handoff
|
|
14
|
+
* npx fit-pathway job --validate # Validation checks
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { prepareJobDetail } from "@forwardimpact/libskill/job";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
generateJobTitle,
|
|
21
21
|
generateAllJobs,
|
|
22
22
|
} from "@forwardimpact/libskill/derivation";
|
|
23
|
-
import { formatTable } from "
|
|
23
|
+
import { formatTable } from "@forwardimpact/libcli";
|
|
24
24
|
import {
|
|
25
25
|
deriveChecklist,
|
|
26
26
|
formatChecklistMarkdown,
|
|
@@ -44,7 +44,11 @@ function formatJob(view, _options, entities, jobTemplate) {
|
|
|
44
44
|
*/
|
|
45
45
|
function printJobList(filteredJobs) {
|
|
46
46
|
for (const job of filteredJobs) {
|
|
47
|
-
const title = generateJobTitle(
|
|
47
|
+
const title = generateJobTitle({
|
|
48
|
+
discipline: job.discipline,
|
|
49
|
+
level: job.level,
|
|
50
|
+
track: job.track,
|
|
51
|
+
});
|
|
48
52
|
if (job.track) {
|
|
49
53
|
console.log(
|
|
50
54
|
`${job.discipline.id} ${job.level.id} ${job.track.id}, ${title}`,
|
|
@@ -92,10 +96,10 @@ function printJobSummary(filteredJobs, options) {
|
|
|
92
96
|
);
|
|
93
97
|
console.log(`\nTotal: ${filteredJobs.length} valid job combinations`);
|
|
94
98
|
console.log(
|
|
95
|
-
`\nRun '
|
|
99
|
+
`\nRun 'npx fit-pathway job --list' for all combinations with titles`,
|
|
96
100
|
);
|
|
97
101
|
console.log(
|
|
98
|
-
`Run '
|
|
102
|
+
`Run 'npx fit-pathway job <discipline> <level> [--track=<track>]' for details\n`,
|
|
99
103
|
);
|
|
100
104
|
}
|
|
101
105
|
|
|
@@ -109,7 +113,7 @@ function handleSingleArg(arg, data) {
|
|
|
109
113
|
const isTrack = data.tracks.some((t) => t.id === arg);
|
|
110
114
|
if (isLevel) {
|
|
111
115
|
console.error(
|
|
112
|
-
`Missing discipline. Usage:
|
|
116
|
+
`Missing discipline. Usage: npx fit-pathway job <discipline> ${arg} [--track=<track>]`,
|
|
113
117
|
);
|
|
114
118
|
console.error(
|
|
115
119
|
`Disciplines: ${data.disciplines.map((d) => d.id).join(", ")}`,
|
|
@@ -117,13 +121,13 @@ function handleSingleArg(arg, data) {
|
|
|
117
121
|
} else if (isTrack) {
|
|
118
122
|
console.error(`Track must be passed as a flag: --track=${arg}`);
|
|
119
123
|
console.error(
|
|
120
|
-
`Usage:
|
|
124
|
+
`Usage: npx fit-pathway job <discipline> <level> --track=${arg}`,
|
|
121
125
|
);
|
|
122
126
|
} else {
|
|
123
127
|
console.error(
|
|
124
|
-
"Usage:
|
|
128
|
+
"Usage: npx fit-pathway job <discipline> <level> [--track=<track>]",
|
|
125
129
|
);
|
|
126
|
-
console.error("
|
|
130
|
+
console.error(" npx fit-pathway job --list");
|
|
127
131
|
}
|
|
128
132
|
process.exit(1);
|
|
129
133
|
}
|
|
@@ -148,7 +152,7 @@ function resolveJobEntities(data, args, options) {
|
|
|
148
152
|
if (maybeLevel && maybeDiscipline) {
|
|
149
153
|
console.error(`Arguments are in the wrong order. Try:`);
|
|
150
154
|
console.error(
|
|
151
|
-
`
|
|
155
|
+
` npx fit-pathway job ${args[1]} ${args[0]}${options.track ? ` --track=${options.track}` : ""}`,
|
|
152
156
|
);
|
|
153
157
|
} else {
|
|
154
158
|
console.error(`Discipline not found: ${args[0]}`);
|
|
@@ -165,7 +169,9 @@ function resolveJobEntities(data, args, options) {
|
|
|
165
169
|
console.error(
|
|
166
170
|
`Track must be passed as a flag, not a positional argument:`,
|
|
167
171
|
);
|
|
168
|
-
console.error(
|
|
172
|
+
console.error(
|
|
173
|
+
` npx fit-pathway job ${args[0]} <level> --track=${args[1]}`,
|
|
174
|
+
);
|
|
169
175
|
console.error(`Levels: ${data.levels.map((g) => g.id).join(", ")}`);
|
|
170
176
|
} else {
|
|
171
177
|
console.error(`Level not found: ${args[1]}`);
|
package/src/commands/level.js
CHANGED
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
* Handles level summary, listing, and detail display in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* npx fit-pathway level # Summary with stats
|
|
8
|
+
* npx fit-pathway level --list # IDs only (for piping)
|
|
9
|
+
* npx fit-pathway level <id> # Detail view
|
|
10
|
+
* npx fit-pathway level --validate # Validation checks
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { createEntityCommand } from "./command-factory.js";
|
|
14
14
|
import { levelToMarkdown } from "../formatters/level/markdown.js";
|
|
15
|
-
import { formatTable } from "
|
|
15
|
+
import { formatTable } from "@forwardimpact/libcli";
|
|
16
16
|
import { getConceptEmoji } from "@forwardimpact/map/levels";
|
|
17
17
|
import { capitalize } from "../formatters/shared.js";
|
|
18
18
|
|
|
@@ -57,8 +57,8 @@ function formatSummary(levels, data) {
|
|
|
57
57
|
),
|
|
58
58
|
);
|
|
59
59
|
console.log(`\nTotal: ${levels.length} levels`);
|
|
60
|
-
console.log(`\nRun '
|
|
61
|
-
console.log(`Run '
|
|
60
|
+
console.log(`\nRun 'npx fit-pathway level --list' for IDs and titles`);
|
|
61
|
+
console.log(`Run 'npx fit-pathway level <id>' for details\n`);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/**
|
package/src/commands/progress.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Shows career progression analysis in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* npx fit-pathway progress <discipline> <level> # Progress for trackless job
|
|
8
|
+
* npx fit-pathway progress <discipline> <level> --track=<track> # Progress with track
|
|
9
|
+
* npx fit-pathway progress <discipline> <from_level> --compare=<to_level> # Compare levels
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { createCompositeCommand } from "./command-factory.js";
|
|
@@ -80,5 +80,5 @@ export const runProgressCommand = createCompositeCommand({
|
|
|
80
80
|
}),
|
|
81
81
|
formatter: formatProgress,
|
|
82
82
|
usageExample:
|
|
83
|
-
"
|
|
83
|
+
"npx fit-pathway progress software_engineering L3 --track=platform --compare=L4",
|
|
84
84
|
});
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* Browse and compare interview questions across skills and behaviours.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* npx fit-pathway questions # Summary with stats
|
|
8
|
+
* npx fit-pathway questions --list # Question IDs (for piping)
|
|
9
|
+
* npx fit-pathway questions --level=practitioner # Filter by level
|
|
10
|
+
* npx fit-pathway questions --stats # Detailed statistics
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { questionsToMarkdown } from "../formatters/questions/markdown.js";
|
|
18
18
|
import { questionsToYaml } from "../formatters/questions/yaml.js";
|
|
19
19
|
import { questionsToJson } from "../formatters/questions/json.js";
|
|
20
|
-
import { formatTable } from "
|
|
20
|
+
import { formatTable } from "@forwardimpact/libcli";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Parse questions command options
|
|
@@ -97,9 +97,11 @@ function showQuestionsSummary(data) {
|
|
|
97
97
|
console.log("\nBehaviour Questions:");
|
|
98
98
|
console.log(formatTable(["Maturity", "Count"], behaviourRows));
|
|
99
99
|
|
|
100
|
-
console.log(`\nRun '
|
|
101
|
-
console.log(`Run '
|
|
102
|
-
console.log(
|
|
100
|
+
console.log(`\nRun 'npx fit-pathway questions --list' for question IDs`);
|
|
101
|
+
console.log(`Run 'npx fit-pathway questions --stats' for detailed stats`);
|
|
102
|
+
console.log(
|
|
103
|
+
`Run 'npx fit-pathway questions --level=practitioner' to filter\n`,
|
|
104
|
+
);
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
/**
|
package/src/commands/skill.js
CHANGED
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
* Handles skill summary, listing, and detail display in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* npx fit-pathway skill # Summary with stats
|
|
8
|
+
* npx fit-pathway skill --list # IDs only (for piping)
|
|
9
|
+
* npx fit-pathway skill <id> # Detail view
|
|
10
|
+
* npx fit-pathway skill <id> --agent # Agent SKILL.md output
|
|
11
|
+
* npx fit-pathway skill --validate # Validation checks
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { createEntityCommand } from "./command-factory.js";
|
|
15
15
|
import { skillToMarkdown } from "../formatters/skill/markdown.js";
|
|
16
16
|
import { prepareSkillsList } from "../formatters/skill/shared.js";
|
|
17
17
|
import { getConceptEmoji } from "@forwardimpact/map/levels";
|
|
18
|
-
import { formatTable, formatError } from "
|
|
18
|
+
import { formatTable, formatError } from "@forwardimpact/libcli";
|
|
19
19
|
import { generateSkillMarkdown } from "@forwardimpact/libskill/agent";
|
|
20
20
|
import { formatAgentSkill } from "../formatters/agent/skill.js";
|
|
21
21
|
|
|
@@ -40,8 +40,8 @@ function formatSummary(skills, data) {
|
|
|
40
40
|
|
|
41
41
|
console.log(formatTable(["Capability", "Count", "Agent"], rows));
|
|
42
42
|
console.log(`\nTotal: ${skills.length} skills`);
|
|
43
|
-
console.log(`\nRun '
|
|
44
|
-
console.log(`Run '
|
|
43
|
+
console.log(`\nRun 'npx fit-pathway skill --list' for IDs`);
|
|
44
|
+
console.log(`Run 'npx fit-pathway skill <id>' for details\n`);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -73,13 +73,13 @@ async function formatAgentDetail(skill, stages, templateLoader, dataDir) {
|
|
|
73
73
|
console.error(formatError(`Skill '${skill.id}' has no agent section`));
|
|
74
74
|
console.error(`\nSkills with agent support:`);
|
|
75
75
|
console.error(
|
|
76
|
-
`
|
|
76
|
+
` npx fit-pathway skill --list | xargs -I{} sh -c 'npx fit-pathway skill {} --json | jq -e .skill.agent > /dev/null && echo {}'`,
|
|
77
77
|
);
|
|
78
78
|
process.exit(1);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const template = templateLoader.load("skill.template.md", dataDir);
|
|
82
|
-
const skillMd = generateSkillMarkdown(skill, stages);
|
|
82
|
+
const skillMd = generateSkillMarkdown({ skillData: skill, stages });
|
|
83
83
|
const output = formatAgentSkill(skillMd, template);
|
|
84
84
|
console.log(output);
|
|
85
85
|
}
|
package/src/commands/stage.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Handles stage summary, listing, and detail display in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* npx fit-pathway stage # Summary with lifecycle flow
|
|
8
|
+
* npx fit-pathway stage --list # IDs only (for piping)
|
|
9
|
+
* npx fit-pathway stage <id> # Detail view
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { createEntityCommand } from "./command-factory.js";
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
prepareStageDetail,
|
|
15
15
|
getStageEmoji,
|
|
16
16
|
} from "../formatters/stage/shared.js";
|
|
17
|
-
import { formatTable } from "../lib/cli-output.js";
|
|
18
17
|
import {
|
|
18
|
+
formatTable,
|
|
19
19
|
formatHeader,
|
|
20
20
|
formatSubheader,
|
|
21
21
|
formatBullet,
|
|
22
|
-
} from "
|
|
22
|
+
} from "@forwardimpact/libcli";
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Format stage list item for --list output
|
|
@@ -52,8 +52,8 @@ function formatSummary(stages, _data) {
|
|
|
52
52
|
|
|
53
53
|
console.log(formatTable(["ID", "Name", "Mode", "Tools", "Handoffs"], rows));
|
|
54
54
|
console.log(`\nTotal: ${stages.length} stages`);
|
|
55
|
-
console.log(`\nRun '
|
|
56
|
-
console.log(`Run '
|
|
55
|
+
console.log(`\nRun 'npx fit-pathway stage --list' for IDs and names`);
|
|
56
|
+
console.log(`Run 'npx fit-pathway stage <id>' for details\n`);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
package/src/commands/tool.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Handles tool summary, listing, and detail display in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* npx fit-pathway tool # Summary with stats
|
|
8
|
+
* npx fit-pathway tool --list # Tool names only (for piping)
|
|
9
|
+
* npx fit-pathway tool <name> # Detail view for specific tool
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { truncate } from "../formatters/shared.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
formatTable,
|
|
16
16
|
formatHeader,
|
|
17
17
|
formatSubheader,
|
|
18
|
-
} from "
|
|
18
|
+
} from "@forwardimpact/libcli";
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Run tool command
|
|
@@ -89,9 +89,9 @@ function formatSummary(tools, totalCount) {
|
|
|
89
89
|
console.log(`(showing top 15 by usage)`);
|
|
90
90
|
}
|
|
91
91
|
console.log(
|
|
92
|
-
`\nRun '
|
|
92
|
+
`\nRun 'npx fit-pathway tool --list' for all tool names and descriptions`,
|
|
93
93
|
);
|
|
94
|
-
console.log(`Run '
|
|
94
|
+
console.log(`Run 'npx fit-pathway tool <name>' for details\n`);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/**
|
package/src/commands/track.js
CHANGED
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
* Handles track summary, listing, and detail display in the terminal.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* npx fit-pathway track # Summary with stats
|
|
8
|
+
* npx fit-pathway track --list # IDs only (for piping)
|
|
9
|
+
* npx fit-pathway track <id> # Detail view
|
|
10
|
+
* npx fit-pathway track --validate # Validation checks
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { createEntityCommand } from "./command-factory.js";
|
|
14
14
|
import { trackToMarkdown } from "../formatters/track/markdown.js";
|
|
15
15
|
import { sortTracksByName } from "../formatters/track/shared.js";
|
|
16
|
-
import { formatTable } from "
|
|
16
|
+
import { formatTable } from "@forwardimpact/libcli";
|
|
17
17
|
import { getConceptEmoji } from "@forwardimpact/map/levels";
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -49,8 +49,8 @@ function formatSummary(tracks, data) {
|
|
|
49
49
|
|
|
50
50
|
console.log(formatTable(["ID", "Name", "Modifiers", "Disciplines"], rows));
|
|
51
51
|
console.log(`\nTotal: ${tracks.length} tracks`);
|
|
52
|
-
console.log(`\nRun '
|
|
53
|
-
console.log(`Run '
|
|
52
|
+
console.log(`\nRun 'npx fit-pathway track --list' for IDs and names`);
|
|
53
|
+
console.log(`Run 'npx fit-pathway track <id>' for details\n`);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
@@ -33,6 +33,54 @@
|
|
|
33
33
|
gap: var(--space-xl);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/* Install section — ecosystem-tool install commands shown between the
|
|
37
|
+
dropdowns and the preview cards. Uses the same surface treatment as
|
|
38
|
+
the form so the two blocks read as a matched pair. */
|
|
39
|
+
.agent-install-section {
|
|
40
|
+
background: var(--color-surface);
|
|
41
|
+
border-radius: var(--radius-lg);
|
|
42
|
+
padding: var(--space-xl);
|
|
43
|
+
box-shadow: var(--shadow-md);
|
|
44
|
+
margin-bottom: var(--space-xl);
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
gap: var(--space-lg);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.agent-install-header h2 {
|
|
51
|
+
margin: 0 0 var(--space-sm) 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.agent-install-description {
|
|
55
|
+
margin: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.agent-install-commands {
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
gap: var(--space-md);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.agent-install-command {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: column;
|
|
67
|
+
gap: var(--space-xs);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.agent-install-command-label {
|
|
71
|
+
margin: 0;
|
|
72
|
+
font-size: var(--font-size-sm);
|
|
73
|
+
font-weight: 600;
|
|
74
|
+
color: var(--color-text-secondary);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Allow the command prompts inside the install section to grow beyond the
|
|
78
|
+
600px center-aligned default used on the landing hero. */
|
|
79
|
+
.agent-install-command .command-prompt {
|
|
80
|
+
max-width: none;
|
|
81
|
+
margin: 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
36
84
|
/* Agent section — spacing container, no surface */
|
|
37
85
|
.agent-section {
|
|
38
86
|
margin-bottom: var(--space-lg);
|
|
@@ -14,7 +14,9 @@ import {
|
|
|
14
14
|
deriveDecompositionInterview,
|
|
15
15
|
deriveStakeholderInterview,
|
|
16
16
|
} from "@forwardimpact/libskill/interview";
|
|
17
|
-
import {
|
|
17
|
+
import { createJobCache } from "@forwardimpact/libskill/job-cache";
|
|
18
|
+
|
|
19
|
+
const jobCache = createJobCache();
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* Interview type configurations
|
|
@@ -140,7 +142,7 @@ export function prepareInterviewDetail({
|
|
|
140
142
|
}) {
|
|
141
143
|
if (!discipline || !level) return null;
|
|
142
144
|
|
|
143
|
-
const job =
|
|
145
|
+
const job = jobCache.getOrCreate({
|
|
144
146
|
discipline,
|
|
145
147
|
level,
|
|
146
148
|
track,
|
|
@@ -275,7 +277,7 @@ export function prepareInterviewBuilderPreview({
|
|
|
275
277
|
};
|
|
276
278
|
}
|
|
277
279
|
|
|
278
|
-
const title = generateJobTitle(discipline, level, track);
|
|
280
|
+
const title = generateJobTitle({ discipline, level, track });
|
|
279
281
|
const totalSkills = getDisciplineSkillIds(discipline).length;
|
|
280
282
|
|
|
281
283
|
return {
|
|
@@ -320,7 +322,7 @@ export function prepareAllInterviews({
|
|
|
320
322
|
// Track is optional (null = generalist)
|
|
321
323
|
if (!discipline || !level) return null;
|
|
322
324
|
|
|
323
|
-
const job =
|
|
325
|
+
const job = jobCache.getOrCreate({
|
|
324
326
|
discipline,
|
|
325
327
|
level,
|
|
326
328
|
track,
|
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
analyzeCustomProgression,
|
|
14
14
|
getNextLevel,
|
|
15
15
|
} from "@forwardimpact/libskill/progression";
|
|
16
|
-
import {
|
|
16
|
+
import { createJobCache } from "@forwardimpact/libskill/job-cache";
|
|
17
|
+
|
|
18
|
+
const jobCache = createJobCache();
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Get the next level for progression
|
|
@@ -22,20 +24,7 @@ import { getOrCreateJob } from "@forwardimpact/libskill/job-cache";
|
|
|
22
24
|
* @returns {Object|null}
|
|
23
25
|
*/
|
|
24
26
|
export function getDefaultTargetLevel(currentLevel, levels) {
|
|
25
|
-
return getNextLevel(currentLevel, levels);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Check if a job combination is valid
|
|
30
|
-
* @param {Object} params
|
|
31
|
-
* @param {Object} params.discipline
|
|
32
|
-
* @param {Object} params.level
|
|
33
|
-
* @param {Object} params.track
|
|
34
|
-
* @param {Array} [params.levels] - All levels for validation
|
|
35
|
-
* @returns {boolean}
|
|
36
|
-
*/
|
|
37
|
-
export function isValidCombination({ discipline, level, track, levels }) {
|
|
38
|
-
return isValidJobCombination({ discipline, level, track, levels });
|
|
27
|
+
return getNextLevel({ level: currentLevel, levels });
|
|
39
28
|
}
|
|
40
29
|
|
|
41
30
|
/**
|
|
@@ -69,7 +58,7 @@ export function prepareCurrentJob({
|
|
|
69
58
|
}) {
|
|
70
59
|
if (!discipline || !level) return null;
|
|
71
60
|
|
|
72
|
-
const job =
|
|
61
|
+
const job = jobCache.getOrCreate({
|
|
73
62
|
discipline,
|
|
74
63
|
level,
|
|
75
64
|
track,
|
|
@@ -148,8 +137,8 @@ export function prepareCareerProgressPreview({
|
|
|
148
137
|
};
|
|
149
138
|
}
|
|
150
139
|
|
|
151
|
-
const title = generateJobTitle(discipline, level, track);
|
|
152
|
-
const nextLevel = getNextLevel(level, levels);
|
|
140
|
+
const title = generateJobTitle({ discipline, level, track });
|
|
141
|
+
const nextLevel = getNextLevel({ level, levels });
|
|
153
142
|
|
|
154
143
|
// Find other valid tracks for comparison (exclude current track if any)
|
|
155
144
|
const validTracks = tracks.filter(
|
|
@@ -209,7 +198,7 @@ export function prepareProgressDetail({
|
|
|
209
198
|
if (!fromDiscipline || !fromLevel) return null;
|
|
210
199
|
if (!toDiscipline || !toLevel) return null;
|
|
211
200
|
|
|
212
|
-
const fromJob =
|
|
201
|
+
const fromJob = jobCache.getOrCreate({
|
|
213
202
|
discipline: fromDiscipline,
|
|
214
203
|
level: fromLevel,
|
|
215
204
|
track: fromTrack,
|
|
@@ -218,7 +207,7 @@ export function prepareProgressDetail({
|
|
|
218
207
|
capabilities,
|
|
219
208
|
});
|
|
220
209
|
|
|
221
|
-
const toJob =
|
|
210
|
+
const toJob = jobCache.getOrCreate({
|
|
222
211
|
discipline: toDiscipline,
|
|
223
212
|
level: toLevel,
|
|
224
213
|
track: toTrack,
|
|
@@ -26,7 +26,7 @@ export function questionsToYaml(view, _options = {}) {
|
|
|
26
26
|
|
|
27
27
|
const filterStr =
|
|
28
28
|
filterParts.length > 0 ? filterParts.join(" ") : "(no filters)";
|
|
29
|
-
const header = `# Generated by:
|
|
29
|
+
const header = `# Generated by: npx fit-pathway questions ${filterStr}\n# Questions: ${questions.length}\n\n`;
|
|
30
30
|
|
|
31
31
|
// Group questions by source
|
|
32
32
|
const bySource = {};
|