@forwardimpact/pathway 0.25.22 → 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 +13 -13
- package/src/commands/behaviour.js +7 -7
- package/src/commands/build-packs.js +208 -34
- package/src/commands/build.js +2 -2
- 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 +19 -17
- 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 +9 -9
- package/src/commands/stage.js +7 -7
- package/src/commands/tool.js +6 -6
- package/src/commands/track.js +7 -7
- package/src/formatters/questions/yaml.js +1 -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 +6 -5
- package/src/commands/init.js +0 -64
- 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
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
|
/**
|
|
@@ -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 = {};
|
package/src/index.html
CHANGED
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
<div class="top-bar__command">
|
|
84
84
|
<span class="top-bar__prompt">$</span>
|
|
85
85
|
<span class="top-bar__command-text" id="cli-command"
|
|
86
|
-
>
|
|
86
|
+
>npx fit-pathway</span
|
|
87
87
|
>
|
|
88
88
|
<button class="top-bar__copy" id="cli-copy" aria-label="Copy command">
|
|
89
89
|
<svg viewBox="0 0 24 24">
|
package/src/lib/cli-command.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CLI Command Mapping
|
|
3
3
|
*
|
|
4
|
-
* Maps hash routes to their equivalent `
|
|
4
|
+
* Maps hash routes to their equivalent `npx fit-pathway` CLI commands.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -11,122 +11,122 @@
|
|
|
11
11
|
*/
|
|
12
12
|
const ROUTE_COMMANDS = [
|
|
13
13
|
// Landing
|
|
14
|
-
{ pattern: /^\/$/, toCommand: () => "
|
|
14
|
+
{ pattern: /^\/$/, toCommand: () => "npx fit-pathway" },
|
|
15
15
|
|
|
16
16
|
// Entity lists
|
|
17
|
-
{ pattern: /^\/skill$/, toCommand: () => "
|
|
18
|
-
{ pattern: /^\/behaviour$/, toCommand: () => "
|
|
17
|
+
{ pattern: /^\/skill$/, toCommand: () => "npx fit-pathway skill" },
|
|
18
|
+
{ pattern: /^\/behaviour$/, toCommand: () => "npx fit-pathway behaviour" },
|
|
19
19
|
{
|
|
20
20
|
pattern: /^\/discipline$/,
|
|
21
|
-
toCommand: () => "
|
|
21
|
+
toCommand: () => "npx fit-pathway discipline",
|
|
22
22
|
},
|
|
23
|
-
{ pattern: /^\/track$/, toCommand: () => "
|
|
24
|
-
{ pattern: /^\/level$/, toCommand: () => "
|
|
25
|
-
{ pattern: /^\/driver$/, toCommand: () => "
|
|
26
|
-
{ pattern: /^\/stage$/, toCommand: () => "
|
|
27
|
-
{ pattern: /^\/tool$/, toCommand: () => "
|
|
23
|
+
{ pattern: /^\/track$/, toCommand: () => "npx fit-pathway track" },
|
|
24
|
+
{ pattern: /^\/level$/, toCommand: () => "npx fit-pathway level" },
|
|
25
|
+
{ pattern: /^\/driver$/, toCommand: () => "npx fit-pathway driver" },
|
|
26
|
+
{ pattern: /^\/stage$/, toCommand: () => "npx fit-pathway stage" },
|
|
27
|
+
{ pattern: /^\/tool$/, toCommand: () => "npx fit-pathway tool" },
|
|
28
28
|
|
|
29
29
|
// Entity details
|
|
30
30
|
{
|
|
31
31
|
pattern: /^\/skill\/(.+)$/,
|
|
32
|
-
toCommand: (m) => `
|
|
32
|
+
toCommand: (m) => `npx fit-pathway skill ${m[1]}`,
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
pattern: /^\/behaviour\/(.+)$/,
|
|
36
|
-
toCommand: (m) => `
|
|
36
|
+
toCommand: (m) => `npx fit-pathway behaviour ${m[1]}`,
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
pattern: /^\/discipline\/(.+)$/,
|
|
40
|
-
toCommand: (m) => `
|
|
40
|
+
toCommand: (m) => `npx fit-pathway discipline ${m[1]}`,
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
pattern: /^\/track\/(.+)$/,
|
|
44
|
-
toCommand: (m) => `
|
|
44
|
+
toCommand: (m) => `npx fit-pathway track ${m[1]}`,
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
pattern: /^\/level\/(.+)$/,
|
|
48
|
-
toCommand: (m) => `
|
|
48
|
+
toCommand: (m) => `npx fit-pathway level ${m[1]}`,
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
pattern: /^\/driver\/(.+)$/,
|
|
52
|
-
toCommand: (m) => `
|
|
52
|
+
toCommand: (m) => `npx fit-pathway driver ${m[1]}`,
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
pattern: /^\/stage\/(.+)$/,
|
|
56
|
-
toCommand: (m) => `
|
|
56
|
+
toCommand: (m) => `npx fit-pathway stage ${m[1]}`,
|
|
57
57
|
},
|
|
58
58
|
|
|
59
59
|
// Job builder + detail
|
|
60
60
|
{
|
|
61
61
|
pattern: /^\/job-builder$/,
|
|
62
|
-
toCommand: () => "
|
|
62
|
+
toCommand: () => "npx fit-pathway job --list",
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
pattern: /^\/job\/([^/]+)\/([^/]+)\/([^/]+)$/,
|
|
66
|
-
toCommand: (m) => `
|
|
66
|
+
toCommand: (m) => `npx fit-pathway job ${m[1]} ${m[2]} --track=${m[3]}`,
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
69
|
pattern: /^\/job\/([^/]+)\/([^/]+)$/,
|
|
70
|
-
toCommand: (m) => `
|
|
70
|
+
toCommand: (m) => `npx fit-pathway job ${m[1]} ${m[2]}`,
|
|
71
71
|
},
|
|
72
72
|
|
|
73
73
|
// Interview builder + detail
|
|
74
74
|
{
|
|
75
75
|
pattern: /^\/interview-prep$/,
|
|
76
|
-
toCommand: () => "
|
|
76
|
+
toCommand: () => "npx fit-pathway interview --list",
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
pattern: /^\/interview\/([^/]+)\/([^/]+)\/([^/]+)$/,
|
|
80
80
|
toCommand: (m) =>
|
|
81
|
-
`
|
|
81
|
+
`npx fit-pathway interview ${m[1]} ${m[2]} --track=${m[3]}`,
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
pattern: /^\/interview\/([^/]+)\/([^/]+)$/,
|
|
85
|
-
toCommand: (m) => `
|
|
85
|
+
toCommand: (m) => `npx fit-pathway interview ${m[1]} ${m[2]}`,
|
|
86
86
|
},
|
|
87
87
|
|
|
88
88
|
// Career progress builder + detail
|
|
89
89
|
{
|
|
90
90
|
pattern: /^\/career-progress$/,
|
|
91
|
-
toCommand: () => "
|
|
91
|
+
toCommand: () => "npx fit-pathway progress --list",
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
pattern: /^\/progress\/([^/]+)\/([^/]+)\/([^/]+)$/,
|
|
95
95
|
toCommand: (m) =>
|
|
96
|
-
`
|
|
96
|
+
`npx fit-pathway progress ${m[1]} ${m[2]} --track=${m[3]}`,
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
pattern: /^\/progress\/([^/]+)\/([^/]+)$/,
|
|
100
|
-
toCommand: (m) => `
|
|
100
|
+
toCommand: (m) => `npx fit-pathway progress ${m[1]} ${m[2]}`,
|
|
101
101
|
},
|
|
102
102
|
|
|
103
103
|
// Self-assessment
|
|
104
104
|
{
|
|
105
105
|
pattern: /^\/self-assessment$/,
|
|
106
|
-
toCommand: () => "
|
|
106
|
+
toCommand: () => "npx fit-pathway self-assessment",
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
pattern: /^\/self-assessment\/results$/,
|
|
110
|
-
toCommand: () => "
|
|
110
|
+
toCommand: () => "npx fit-pathway self-assessment",
|
|
111
111
|
},
|
|
112
112
|
|
|
113
113
|
// Agent builder + detail
|
|
114
114
|
{
|
|
115
115
|
pattern: /^\/agent-builder$/,
|
|
116
|
-
toCommand: () => "
|
|
116
|
+
toCommand: () => "npx fit-pathway agent --list",
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
119
|
pattern: /^\/agent\/([^/]+)\/([^/]+)\/([^/]+)$/,
|
|
120
120
|
toCommand: (m) =>
|
|
121
|
-
`
|
|
121
|
+
`npx fit-pathway agent ${m[1]} --track=${m[2]} --stage=${m[3]}`,
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
pattern: /^\/agent\/([^/]+)\/([^/]+)$/,
|
|
125
|
-
toCommand: (m) => `
|
|
125
|
+
toCommand: (m) => `npx fit-pathway agent ${m[1]} --track=${m[2]}`,
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
pattern: /^\/agent\/([^/]+)$/,
|
|
129
|
-
toCommand: (m) => `
|
|
129
|
+
toCommand: (m) => `npx fit-pathway agent ${m[1]}`,
|
|
130
130
|
},
|
|
131
131
|
];
|
|
132
132
|
|
|
@@ -141,5 +141,5 @@ export function getCliCommand(hashPath) {
|
|
|
141
141
|
const match = path.match(pattern);
|
|
142
142
|
if (match) return toCommand(match);
|
|
143
143
|
}
|
|
144
|
-
return "
|
|
144
|
+
return "npx fit-pathway";
|
|
145
145
|
}
|
package/src/lib/cli-output.js
CHANGED
|
@@ -1,129 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI Output
|
|
2
|
+
* Domain-specific CLI Output Formatters
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Pathway-specific formatting for skill proficiencies, behaviour maturities,
|
|
5
|
+
* modifiers, percentages, and change indicators. Generic formatters (colors,
|
|
6
|
+
* tables, headers, etc.) live in @forwardimpact/libcli.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
export const colors = {
|
|
10
|
-
reset: "\x1b[0m",
|
|
11
|
-
bold: "\x1b[1m",
|
|
12
|
-
dim: "\x1b[2m",
|
|
13
|
-
italic: "\x1b[3m",
|
|
14
|
-
underline: "\x1b[4m",
|
|
15
|
-
red: "\x1b[31m",
|
|
16
|
-
green: "\x1b[32m",
|
|
17
|
-
yellow: "\x1b[33m",
|
|
18
|
-
blue: "\x1b[34m",
|
|
19
|
-
magenta: "\x1b[35m",
|
|
20
|
-
cyan: "\x1b[36m",
|
|
21
|
-
white: "\x1b[37m",
|
|
22
|
-
gray: "\x1b[90m",
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Check if stdout supports colors
|
|
27
|
-
* @returns {boolean}
|
|
28
|
-
*/
|
|
29
|
-
export function supportsColor() {
|
|
30
|
-
if (process.env.NO_COLOR) return false;
|
|
31
|
-
if (process.env.FORCE_COLOR) return true;
|
|
32
|
-
return process.stdout.isTTY;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Wrap text with color if supported
|
|
37
|
-
* @param {string} text
|
|
38
|
-
* @param {string} color
|
|
39
|
-
* @returns {string}
|
|
40
|
-
*/
|
|
41
|
-
function colorize(text, color) {
|
|
42
|
-
if (!supportsColor()) return text;
|
|
43
|
-
return `${color}${text}${colors.reset}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Format a header
|
|
48
|
-
* @param {string} text
|
|
49
|
-
* @returns {string}
|
|
50
|
-
*/
|
|
51
|
-
export function formatHeader(text) {
|
|
52
|
-
return colorize(text, colors.bold + colors.cyan);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Format a subheader
|
|
57
|
-
* @param {string} text
|
|
58
|
-
* @returns {string}
|
|
59
|
-
*/
|
|
60
|
-
export function formatSubheader(text) {
|
|
61
|
-
return colorize(text, colors.bold);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Format a list item
|
|
66
|
-
* @param {string} label
|
|
67
|
-
* @param {string} value
|
|
68
|
-
* @param {number} [indent=0]
|
|
69
|
-
* @returns {string}
|
|
70
|
-
*/
|
|
71
|
-
export function formatListItem(label, value, indent = 0) {
|
|
72
|
-
const padding = " ".repeat(indent);
|
|
73
|
-
const bullet = colorize("•", colors.dim);
|
|
74
|
-
return `${padding}${bullet} ${label}: ${value}`;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Format a bullet item (no label)
|
|
79
|
-
* @param {string} text
|
|
80
|
-
* @param {number} [indent=0]
|
|
81
|
-
* @returns {string}
|
|
82
|
-
*/
|
|
83
|
-
export function formatBullet(text, indent = 0) {
|
|
84
|
-
const padding = " ".repeat(indent);
|
|
85
|
-
const bullet = colorize("•", colors.dim);
|
|
86
|
-
return `${padding}${bullet} ${text}`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Format a table
|
|
91
|
-
* @param {string[]} headers
|
|
92
|
-
* @param {Array<Array<string|number>>} rows
|
|
93
|
-
* @param {Object} [options]
|
|
94
|
-
* @param {boolean} [options.compact=false]
|
|
95
|
-
* @returns {string}
|
|
96
|
-
*/
|
|
97
|
-
export function formatTable(headers, rows, options = {}) {
|
|
98
|
-
const { compact = false } = options;
|
|
99
|
-
|
|
100
|
-
// Calculate column widths
|
|
101
|
-
const widths = headers.map((h, i) =>
|
|
102
|
-
Math.max(String(h).length, ...rows.map((r) => String(r[i] || "").length)),
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
const lines = [];
|
|
106
|
-
|
|
107
|
-
// Header
|
|
108
|
-
const headerLine = headers
|
|
109
|
-
.map((h, i) => String(h).padEnd(widths[i]))
|
|
110
|
-
.join(" ");
|
|
111
|
-
lines.push(colorize(headerLine, colors.bold));
|
|
112
|
-
|
|
113
|
-
// Separator
|
|
114
|
-
if (!compact) {
|
|
115
|
-
lines.push(widths.map((w) => "─".repeat(w)).join("──"));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Rows
|
|
119
|
-
for (const row of rows) {
|
|
120
|
-
lines.push(
|
|
121
|
-
row.map((cell, i) => String(cell || "").padEnd(widths[i])).join(" "),
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return lines.join("\n");
|
|
126
|
-
}
|
|
9
|
+
import { colorize, colors } from "@forwardimpact/libcli";
|
|
127
10
|
|
|
128
11
|
/**
|
|
129
12
|
* Format skill proficiency with color
|
|
@@ -193,78 +76,15 @@ export function formatPercent(value) {
|
|
|
193
76
|
}
|
|
194
77
|
|
|
195
78
|
/**
|
|
196
|
-
* Format a change indicator
|
|
79
|
+
* Format a change indicator
|
|
197
80
|
* @param {number} change
|
|
198
81
|
* @returns {string}
|
|
199
82
|
*/
|
|
200
83
|
export function formatChange(change) {
|
|
201
84
|
if (change > 0) {
|
|
202
|
-
return colorize(
|
|
85
|
+
return colorize(`\u2191${change}`, colors.green);
|
|
203
86
|
} else if (change < 0) {
|
|
204
|
-
return colorize(
|
|
87
|
+
return colorize(`\u2193${Math.abs(change)}`, colors.red);
|
|
205
88
|
}
|
|
206
|
-
return colorize("
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Format an error message
|
|
211
|
-
* @param {string} message
|
|
212
|
-
* @returns {string}
|
|
213
|
-
*/
|
|
214
|
-
export function formatError(message) {
|
|
215
|
-
return colorize(`Error: ${message}`, colors.red);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Format a success message
|
|
220
|
-
* @param {string} message
|
|
221
|
-
* @returns {string}
|
|
222
|
-
*/
|
|
223
|
-
export function formatSuccess(message) {
|
|
224
|
-
return colorize(message, colors.green);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Format a warning message
|
|
229
|
-
* @param {string} message
|
|
230
|
-
/**
|
|
231
|
-
* Format a warning message
|
|
232
|
-
* @param {string} message
|
|
233
|
-
* @returns {string}
|
|
234
|
-
*/
|
|
235
|
-
export function formatWarning(message) {
|
|
236
|
-
return colorize(`Warning: ${message}`, colors.yellow);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Create a horizontal rule
|
|
241
|
-
* @param {number} [width=60]
|
|
242
|
-
* @returns {string}
|
|
243
|
-
*/
|
|
244
|
-
export function horizontalRule(width = 60) {
|
|
245
|
-
return colorize("─".repeat(width), colors.dim);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Format a section with title and content
|
|
250
|
-
* @param {string} title
|
|
251
|
-
* @param {string} content
|
|
252
|
-
* @returns {string}
|
|
253
|
-
*/
|
|
254
|
-
export function formatSection(title, content) {
|
|
255
|
-
return `${formatHeader(title)}\n\n${content}`;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Indent all lines of text
|
|
260
|
-
* @param {string} text
|
|
261
|
-
* @param {number} [spaces=2]
|
|
262
|
-
* @returns {string}
|
|
263
|
-
*/
|
|
264
|
-
export function indent(text, spaces = 2) {
|
|
265
|
-
const padding = " ".repeat(spaces);
|
|
266
|
-
return text
|
|
267
|
-
.split("\n")
|
|
268
|
-
.map((line) => padding + line)
|
|
269
|
-
.join("\n");
|
|
89
|
+
return colorize("\u2192", colors.dim);
|
|
270
90
|
}
|
|
@@ -56,13 +56,14 @@ export function getApmInstallCommand(siteUrl, packName) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
* Build the `npx skills add` command that discovers the
|
|
60
|
-
*
|
|
59
|
+
* Build the `npx skills add` command that discovers the per-pack skill
|
|
60
|
+
* repository at `<siteUrl>/packs/<packName>/.well-known/skills/index.json`.
|
|
61
61
|
* @param {string} siteUrl
|
|
62
|
+
* @param {string} packName
|
|
62
63
|
* @returns {string}
|
|
63
64
|
*/
|
|
64
|
-
export function getSkillsAddCommand(siteUrl) {
|
|
65
|
-
return `npx skills add ${normalizeSiteUrl(siteUrl)}`;
|
|
65
|
+
export function getSkillsAddCommand(siteUrl, packName) {
|
|
66
|
+
return `npx skills add ${normalizeSiteUrl(siteUrl)}/packs/${packName}`;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
/**
|
|
@@ -80,7 +81,7 @@ export function createInstallSection({ discipline, track, siteUrl }) {
|
|
|
80
81
|
|
|
81
82
|
const packName = getPackName(discipline, track);
|
|
82
83
|
const apmCommand = getApmInstallCommand(siteUrl, packName);
|
|
83
|
-
const skillsCommand = getSkillsAddCommand(siteUrl);
|
|
84
|
+
const skillsCommand = getSkillsAddCommand(siteUrl, packName);
|
|
84
85
|
|
|
85
86
|
return section(
|
|
86
87
|
{
|
package/src/commands/init.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Init Command
|
|
3
|
-
*
|
|
4
|
-
* Initializes a new Engineering Pathway project by copying starter data.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { cp, access } from "fs/promises";
|
|
8
|
-
import { join, dirname } from "path";
|
|
9
|
-
import { fileURLToPath } from "url";
|
|
10
|
-
|
|
11
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const starterDir = join(__dirname, "..", "..", "starter");
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Run the init command
|
|
16
|
-
* @param {Object} params - Command parameters
|
|
17
|
-
* @param {Object} params.options - Command options
|
|
18
|
-
*/
|
|
19
|
-
export async function runInitCommand({ options }) {
|
|
20
|
-
const targetPath = options.path || process.cwd();
|
|
21
|
-
const dataDir = join(targetPath, "data", "pathway");
|
|
22
|
-
|
|
23
|
-
// Check if data/pathway/ already exists
|
|
24
|
-
try {
|
|
25
|
-
await access(dataDir);
|
|
26
|
-
console.error("Error: ./data/pathway/ already exists.");
|
|
27
|
-
console.error("Remove it first or use a different directory.");
|
|
28
|
-
process.exit(1);
|
|
29
|
-
} catch {
|
|
30
|
-
// Directory doesn't exist, proceed
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Verify starter data is available
|
|
34
|
-
try {
|
|
35
|
-
await access(starterDir);
|
|
36
|
-
} catch {
|
|
37
|
-
console.error("Error: Starter data not found in package.");
|
|
38
|
-
console.error("This may indicate a corrupted package installation.");
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Copy starter data
|
|
43
|
-
console.log("Creating ./data/pathway/ with starter data...\n");
|
|
44
|
-
await cp(starterDir, dataDir, { recursive: true });
|
|
45
|
-
|
|
46
|
-
console.log(`✅ Created ./data/pathway/ with starter data.
|
|
47
|
-
|
|
48
|
-
Next steps:
|
|
49
|
-
1. Edit data files to match your organization
|
|
50
|
-
2. npx fit-map validate
|
|
51
|
-
3. npx fit-pathway dev
|
|
52
|
-
|
|
53
|
-
Data structure:
|
|
54
|
-
data/pathway/
|
|
55
|
-
├── framework.yaml # Framework metadata
|
|
56
|
-
├── levels.yaml # Career levels
|
|
57
|
-
├── stages.yaml # Lifecycle stages
|
|
58
|
-
├── drivers.yaml # Business drivers
|
|
59
|
-
├── disciplines/ # Engineering disciplines
|
|
60
|
-
├── capabilities/ # Capability areas with skills
|
|
61
|
-
├── behaviours/ # Behavioural expectations
|
|
62
|
-
└── tracks/ # Track specializations
|
|
63
|
-
`);
|
|
64
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# yaml-language-server: $schema=https://www.forwardimpact.team/schema/json/behaviour.schema.json
|
|
2
|
-
|
|
3
|
-
name: Think in Systems
|
|
4
|
-
human:
|
|
5
|
-
description:
|
|
6
|
-
The ability to see beyond individual components to understand how the entire
|
|
7
|
-
system behaves. Engineers recognize that every service, API, and queue is
|
|
8
|
-
part of a larger whole—isolated changes ripple across the system.
|
|
9
|
-
maturityDescriptions:
|
|
10
|
-
emerging:
|
|
11
|
-
Recognizes that systems have interconnected parts; considers immediate
|
|
12
|
-
dependencies in code
|
|
13
|
-
developing:
|
|
14
|
-
Identifies upstream and downstream impacts; uses observability tools to
|
|
15
|
-
trace requests across services
|
|
16
|
-
practicing:
|
|
17
|
-
Maps complex system interactions across technical and business domains;
|
|
18
|
-
anticipates cascading effects
|
|
19
|
-
role_modeling:
|
|
20
|
-
Shapes systems design practices across their function; influences
|
|
21
|
-
cross-team architecture decisions
|
|
22
|
-
exemplifying:
|
|
23
|
-
Defines organizational systems architecture principles; recognized
|
|
24
|
-
authority on complex systems
|
|
25
|
-
|
|
26
|
-
agent:
|
|
27
|
-
title: Consider the whole system
|
|
28
|
-
workingStyle: |
|
|
29
|
-
For every change:
|
|
30
|
-
1. Identify upstream and downstream impacts
|
|
31
|
-
2. Consider non-functional requirements (performance, security)
|
|
32
|
-
3. Document assumptions and trade-offs
|