@forwardimpact/model 0.1.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.
- package/lib/agent.js +754 -0
- package/lib/checklist.js +103 -0
- package/lib/derivation.js +766 -0
- package/lib/index.js +121 -0
- package/lib/interview.js +539 -0
- package/lib/job-cache.js +89 -0
- package/lib/job.js +228 -0
- package/lib/matching.js +891 -0
- package/lib/modifiers.js +158 -0
- package/lib/profile.js +262 -0
- package/lib/progression.js +510 -0
- package/package.json +35 -0
package/lib/checklist.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checklist Derivation
|
|
3
|
+
*
|
|
4
|
+
* Checklists are derived from skills with agent.stages.{stage}.ready criteria.
|
|
5
|
+
* Each skill defines its own readiness criteria for stage transitions.
|
|
6
|
+
*
|
|
7
|
+
* Checklist = Stage × Skill Matrix × Skill Ready Criteria
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Map from stage ID to the stage whose ready criteria should be shown
|
|
12
|
+
* (i.e., what must be ready before leaving this stage)
|
|
13
|
+
*/
|
|
14
|
+
const STAGE_TO_HANDOFF = {
|
|
15
|
+
plan: "plan", // Show plan.ready before leaving plan
|
|
16
|
+
code: "code", // Show code.ready before leaving code
|
|
17
|
+
review: "review", // Show review.ready (completion criteria)
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Derive checklist items for a specific stage
|
|
22
|
+
* Returns skills grouped by capability with their ready criteria
|
|
23
|
+
*
|
|
24
|
+
* @param {Object} params
|
|
25
|
+
* @param {string} params.stageId - Current stage (plan, code, review)
|
|
26
|
+
* @param {Array} params.skillMatrix - Derived skill matrix with skill details
|
|
27
|
+
* @param {Array} params.skills - All skills (to look up agent.stages)
|
|
28
|
+
* @param {Array} params.capabilities - All capabilities (for emoji lookup)
|
|
29
|
+
* @returns {Array<{skill: Object, capability: Object, items: string[]}>} Checklist items grouped by skill
|
|
30
|
+
*/
|
|
31
|
+
export function deriveChecklist({
|
|
32
|
+
stageId,
|
|
33
|
+
skillMatrix,
|
|
34
|
+
skills,
|
|
35
|
+
capabilities,
|
|
36
|
+
}) {
|
|
37
|
+
const targetStage = STAGE_TO_HANDOFF[stageId];
|
|
38
|
+
if (!targetStage) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Build skill lookup
|
|
43
|
+
const skillById = new Map(skills.map((s) => [s.id, s]));
|
|
44
|
+
|
|
45
|
+
// Build capability lookup
|
|
46
|
+
const capabilityById = new Map(capabilities.map((c) => [c.id, c]));
|
|
47
|
+
|
|
48
|
+
const result = [];
|
|
49
|
+
|
|
50
|
+
for (const entry of skillMatrix) {
|
|
51
|
+
const skill = skillById.get(entry.skillId);
|
|
52
|
+
if (!skill || !skill.agent || !skill.agent.stages) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const stageData = skill.agent.stages[targetStage];
|
|
57
|
+
if (!stageData || !stageData.ready || stageData.ready.length === 0) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Get capability for this skill
|
|
62
|
+
const capability = capabilityById.get(entry.capability);
|
|
63
|
+
if (!capability) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
result.push({
|
|
68
|
+
skill: {
|
|
69
|
+
id: skill.id,
|
|
70
|
+
name: skill.name,
|
|
71
|
+
},
|
|
72
|
+
capability: {
|
|
73
|
+
id: capability.id,
|
|
74
|
+
name: capability.name,
|
|
75
|
+
emojiIcon: capability.emojiIcon,
|
|
76
|
+
},
|
|
77
|
+
items: stageData.ready,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Format a checklist for display (markdown format)
|
|
86
|
+
* Groups items by skill with capability emoji
|
|
87
|
+
*
|
|
88
|
+
* @param {Array<{skill: Object, capability: Object, items: string[]}>} checklist - Derived checklist
|
|
89
|
+
* @returns {string} Markdown-formatted checklist
|
|
90
|
+
*/
|
|
91
|
+
export function formatChecklistMarkdown(checklist) {
|
|
92
|
+
if (!checklist || checklist.length === 0) {
|
|
93
|
+
return "";
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const sections = checklist.map(({ skill, capability, items }) => {
|
|
97
|
+
const header = `**${capability.emojiIcon} ${skill.name}**`;
|
|
98
|
+
const itemList = items.map((item) => `- [ ] ${item}`).join("\n");
|
|
99
|
+
return `${header}\n\n${itemList}`;
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return sections.join("\n\n");
|
|
103
|
+
}
|