@forwardimpact/pathway 0.16.1 → 0.17.1

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.
@@ -65,6 +65,24 @@ export async function loadSkillTemplate(dataDir) {
65
65
  return loadTemplate("skill.template.md", dataDir);
66
66
  }
67
67
 
68
+ /**
69
+ * Load skill install script template
70
+ * @param {string} dataDir - Path to data directory
71
+ * @returns {Promise<string>} Install script template content
72
+ */
73
+ export async function loadSkillInstallTemplate(dataDir) {
74
+ return loadTemplate("skill-install.template.sh", dataDir);
75
+ }
76
+
77
+ /**
78
+ * Load skill reference template
79
+ * @param {string} dataDir - Path to data directory
80
+ * @returns {Promise<string>} Reference template content
81
+ */
82
+ export async function loadSkillReferenceTemplate(dataDir) {
83
+ return loadTemplate("skill-reference.template.md", dataDir);
84
+ }
85
+
68
86
  /**
69
87
  * Load job description template
70
88
  * @param {string} dataDir - Path to data directory
@@ -76,6 +76,8 @@ async function loadSkillsFromCapabilities(capabilitiesDir) {
76
76
  isHumanOnly,
77
77
  human,
78
78
  agent,
79
+ instructions,
80
+ installScript,
79
81
  implementationReference,
80
82
  toolReferences,
81
83
  } = skill;
@@ -88,6 +90,9 @@ async function loadSkillsFromCapabilities(capabilitiesDir) {
88
90
  // Include isHumanOnly flag for agent filtering (defaults to false)
89
91
  ...(isHumanOnly && { isHumanOnly }),
90
92
  ...(agent && { agent }),
93
+ // Include agent skill content fields
94
+ ...(instructions && { instructions }),
95
+ ...(installScript && { installScript }),
91
96
  // Include implementation reference and tool references (shared by human and agent)
92
97
  ...(implementationReference && { implementationReference }),
93
98
  ...(toolReferences && { toolReferences }),
@@ -37,8 +37,12 @@ import {
37
37
  import { createReactive } from "../lib/reactive.js";
38
38
  import { getStageEmoji } from "../formatters/stage/shared.js";
39
39
  import { formatAgentProfile } from "../formatters/agent/profile.js";
40
- import { formatAgentSkill } from "../formatters/agent/skill.js";
41
- import { createCodeDisplay } from "../components/code-display.js";
40
+ import {
41
+ formatAgentSkill,
42
+ formatInstallScript,
43
+ formatReference,
44
+ } from "../formatters/agent/skill.js";
45
+ import { createFileCard } from "../components/file-card.js";
42
46
  import { createToolkitTable } from "../formatters/toolkit/dom.js";
43
47
  import { createDetailSection } from "../components/detail.js";
44
48
 
@@ -65,17 +69,21 @@ async function getAgentData(dataDir = "./data") {
65
69
 
66
70
  /**
67
71
  * Load templates with caching
68
- * @returns {Promise<{agent: string, skill: string}>}
72
+ * @returns {Promise<{agent: string, skill: string, install: string, reference: string}>}
69
73
  */
70
74
  async function getTemplates() {
71
75
  if (!templateCache) {
72
- const [agentRes, skillRes] = await Promise.all([
76
+ const [agentRes, skillRes, installRes, referenceRes] = await Promise.all([
73
77
  fetch("./templates/agent.template.md"),
74
78
  fetch("./templates/skill.template.md"),
79
+ fetch("./templates/skill-install.template.sh"),
80
+ fetch("./templates/skill-reference.template.md"),
75
81
  ]);
76
82
  templateCache = {
77
83
  agent: await agentRes.text(),
78
84
  skill: await skillRes.text(),
85
+ install: await installRes.text(),
86
+ reference: await referenceRes.text(),
79
87
  };
80
88
  }
81
89
  return templateCache;
@@ -271,7 +279,6 @@ export async function renderAgentBuilder() {
271
279
  skills: data.skills,
272
280
  behaviours: data.behaviours,
273
281
  agentBehaviours: agentData.behaviours,
274
- capabilities: data.capabilities,
275
282
  vscodeSettings: agentData.vscodeSettings,
276
283
  devcontainer: agentData.devcontainer,
277
284
  templates,
@@ -449,7 +456,6 @@ function createAllStagesPreview(context) {
449
456
  skills,
450
457
  behaviours,
451
458
  agentBehaviours,
452
- capabilities,
453
459
  vscodeSettings,
454
460
  devcontainer,
455
461
  templates,
@@ -468,7 +474,6 @@ function createAllStagesPreview(context) {
468
474
  agentBehaviours,
469
475
  agentDiscipline,
470
476
  agentTrack,
471
- capabilities,
472
477
  stages,
473
478
  });
474
479
 
@@ -482,7 +487,6 @@ function createAllStagesPreview(context) {
482
487
  agentBehaviours,
483
488
  agentDiscipline,
484
489
  agentTrack,
485
- capabilities,
486
490
  stages,
487
491
  agentIndex,
488
492
  });
@@ -532,9 +536,24 @@ function createAllStagesPreview(context) {
532
536
  ),
533
537
  div(
534
538
  { className: "agent-cards-grid" },
535
- ...stageAgents.map(({ stage, profile }) =>
536
- createAgentCard(stage, profile, stages, templates.agent),
537
- ),
539
+ ...stageAgents.map(({ stage, profile }) => {
540
+ const content = formatAgentProfile(profile, templates.agent);
541
+ const stageEmoji = getStageEmoji(stages, stage.id);
542
+ return createFileCard({
543
+ header: [
544
+ span({ className: "file-card-emoji" }, stageEmoji),
545
+ h3({}, `${stage.name} Agent`),
546
+ ],
547
+ files: [
548
+ {
549
+ filename: profile.filename,
550
+ content,
551
+ language: "markdown",
552
+ },
553
+ ],
554
+ maxHeight: 400,
555
+ });
556
+ }),
538
557
  ),
539
558
  ),
540
559
 
@@ -545,9 +564,7 @@ function createAllStagesPreview(context) {
545
564
  skillFiles.length > 0
546
565
  ? div(
547
566
  { className: "skill-cards-grid" },
548
- ...skillFiles.map((skill) =>
549
- createSkillCard(skill, templates.skill),
550
- ),
567
+ ...skillFiles.map((skill) => buildSkillFileCard(skill, templates)),
551
568
  )
552
569
  : p(
553
570
  { className: "text-muted" },
@@ -581,7 +598,6 @@ function createSingleStagePreview(context, stage) {
581
598
  skills,
582
599
  behaviours,
583
600
  agentBehaviours,
584
- capabilities,
585
601
  vscodeSettings,
586
602
  devcontainer,
587
603
  stages,
@@ -589,21 +605,6 @@ function createSingleStagePreview(context, stage) {
589
605
  agentIndex,
590
606
  } = context;
591
607
 
592
- // Derive stage agent
593
- const derived = deriveStageAgent({
594
- discipline: humanDiscipline,
595
- track: humanTrack,
596
- stage,
597
- grade,
598
- skills,
599
- behaviours,
600
- agentBehaviours,
601
- agentDiscipline,
602
- agentTrack,
603
- capabilities,
604
- stages,
605
- });
606
-
607
608
  const profile = generateStageAgentProfile({
608
609
  discipline: humanDiscipline,
609
610
  track: humanTrack,
@@ -614,7 +615,6 @@ function createSingleStagePreview(context, stage) {
614
615
  agentBehaviours,
615
616
  agentDiscipline,
616
617
  agentTrack,
617
- capabilities,
618
618
  stages,
619
619
  agentIndex,
620
620
  });
@@ -656,7 +656,24 @@ function createSingleStagePreview(context, stage) {
656
656
  h2({}, "Agent"),
657
657
  div(
658
658
  { className: "agent-cards-grid single" },
659
- createAgentCard(stage, profile, stages, templates.agent, derived),
659
+ (() => {
660
+ const content = formatAgentProfile(profile, templates.agent);
661
+ const stageEmoji = getStageEmoji(stages, stage.id);
662
+ return createFileCard({
663
+ header: [
664
+ span({ className: "file-card-emoji" }, stageEmoji),
665
+ h3({}, `${stage.name} Agent`),
666
+ ],
667
+ files: [
668
+ {
669
+ filename: profile.filename,
670
+ content,
671
+ language: "markdown",
672
+ },
673
+ ],
674
+ maxHeight: 400,
675
+ });
676
+ })(),
660
677
  ),
661
678
  ),
662
679
 
@@ -667,9 +684,7 @@ function createSingleStagePreview(context, stage) {
667
684
  skillFiles.length > 0
668
685
  ? div(
669
686
  { className: "skill-cards-grid" },
670
- ...skillFiles.map((skill) =>
671
- createSkillCard(skill, templates.skill),
672
- ),
687
+ ...skillFiles.map((skill) => buildSkillFileCard(skill, templates)),
673
688
  )
674
689
  : p(
675
690
  { className: "text-muted" },
@@ -688,66 +703,53 @@ function createSingleStagePreview(context, stage) {
688
703
  }
689
704
 
690
705
  /**
691
- * Create an agent card for a stage
692
- * @param {Object} stage - Stage object
693
- * @param {Object} profile - Generated profile
694
- * @param {Array} stages - All stages for emoji lookup
695
- * @param {string} agentTemplate - Mustache template for agent profile
696
- * @param {Object} [_derived] - Optional derived agent data for extra info
706
+ * Build a file card for a skill with 1–3 file panes (accordion).
707
+ * @param {Object} skill - Skill with frontmatter and body
708
+ * @param {{skill: string, install: string, reference: string}} templates - Mustache templates
697
709
  * @returns {HTMLElement}
698
710
  */
699
- function createAgentCard(stage, profile, stages, agentTemplate, _derived) {
700
- const content = formatAgentProfile(profile, agentTemplate);
701
- const stageEmoji = getStageEmoji(stages, stage.id);
711
+ function buildSkillFileCard(skill, templates) {
712
+ const content = formatAgentSkill(skill, templates.skill);
713
+
714
+ /** @type {import('../components/file-card.js').FileDescriptor[]} */
715
+ const files = [
716
+ {
717
+ filename: `${skill.dirname}/SKILL.md`,
718
+ content,
719
+ language: "markdown",
720
+ },
721
+ ];
702
722
 
703
- const card = div(
704
- { className: "agent-card" },
705
- div(
706
- { className: "agent-card-header" },
707
- div(
708
- { className: "agent-card-title" },
709
- span({ className: "agent-card-emoji" }, stageEmoji),
710
- h3({}, `${stage.name} Agent`),
711
- ),
712
- ),
713
- div(
714
- { className: "agent-card-preview" },
715
- createCodeDisplay({
716
- content,
717
- filename: profile.filename,
718
- maxHeight: 400,
719
- }),
720
- ),
721
- );
723
+ if (skill.installScript) {
724
+ files.push({
725
+ filename: `${skill.dirname}/scripts/install.sh`,
726
+ content: formatInstallScript(skill, templates.install),
727
+ language: "bash",
728
+ });
729
+ }
722
730
 
723
- return card;
724
- }
731
+ if (skill.implementationReference) {
732
+ files.push({
733
+ filename: `${skill.dirname}/references/REFERENCE.md`,
734
+ content: formatReference(skill, templates.reference),
735
+ language: "markdown",
736
+ });
737
+ }
725
738
 
726
- /**
727
- * Create a skill card
728
- * @param {Object} skill - Skill with frontmatter and body
729
- * @param {string} skillTemplate - Mustache template for skill
730
- * @returns {HTMLElement}
731
- */
732
- function createSkillCard(skill, skillTemplate) {
733
- const content = formatAgentSkill(skill, skillTemplate);
734
- const filename = `${skill.dirname}/SKILL.md`;
739
+ const headerChildren = [
740
+ span({ className: "file-card-name" }, skill.frontmatter.name),
741
+ ];
742
+ if (files.length > 1) {
743
+ headerChildren.push(
744
+ span({ className: "file-card-badge" }, `${files.length} files`),
745
+ );
746
+ }
735
747
 
736
- return div(
737
- { className: "skill-card" },
738
- div(
739
- { className: "skill-card-header" },
740
- span({ className: "skill-card-name" }, skill.frontmatter.name),
741
- ),
742
- div(
743
- { className: "skill-card-preview" },
744
- createCodeDisplay({
745
- content,
746
- filename,
747
- maxHeight: 300,
748
- }),
749
- ),
750
- );
748
+ return createFileCard({
749
+ header: headerChildren,
750
+ files,
751
+ maxHeight: 300,
752
+ });
751
753
  }
752
754
 
753
755
  /**
@@ -787,10 +789,27 @@ function createDownloadAllButton(
787
789
  zip.file(`.github/agents/${profile.filename}`, content);
788
790
  }
789
791
 
790
- // Add skills
792
+ // Add skills (SKILL.md + optional install script + optional reference)
791
793
  for (const skill of skillFiles) {
792
794
  const content = formatAgentSkill(skill, templates.skill);
793
795
  zip.file(`.claude/skills/${skill.dirname}/SKILL.md`, content);
796
+
797
+ if (skill.installScript) {
798
+ const installContent = formatInstallScript(skill, templates.install);
799
+ zip.file(
800
+ `.claude/skills/${skill.dirname}/scripts/install.sh`,
801
+ installContent,
802
+ { unixPermissions: "755" },
803
+ );
804
+ }
805
+
806
+ if (skill.implementationReference) {
807
+ const refContent = formatReference(skill, templates.reference);
808
+ zip.file(
809
+ `.claude/skills/${skill.dirname}/references/REFERENCE.md`,
810
+ refContent,
811
+ );
812
+ }
794
813
  }
795
814
 
796
815
  // Add VS Code settings
@@ -870,10 +889,27 @@ function createDownloadSingleButton(
870
889
  const content = formatAgentProfile(profile, templates.agent);
871
890
  zip.file(`.github/agents/${profile.filename}`, content);
872
891
 
873
- // Add skills
892
+ // Add skills (SKILL.md + optional install script + optional reference)
874
893
  for (const skill of skillFiles) {
875
894
  const skillContent = formatAgentSkill(skill, templates.skill);
876
895
  zip.file(`.claude/skills/${skill.dirname}/SKILL.md`, skillContent);
896
+
897
+ if (skill.installScript) {
898
+ const installContent = formatInstallScript(skill, templates.install);
899
+ zip.file(
900
+ `.claude/skills/${skill.dirname}/scripts/install.sh`,
901
+ installContent,
902
+ { unixPermissions: "755" },
903
+ );
904
+ }
905
+
906
+ if (skill.implementationReference) {
907
+ const refContent = formatReference(skill, templates.reference);
908
+ zip.file(
909
+ `.claude/skills/${skill.dirname}/references/REFERENCE.md`,
910
+ refContent,
911
+ );
912
+ }
877
913
  }
878
914
 
879
915
  // Add VS Code settings
@@ -14,6 +14,23 @@ import {
14
14
  getCapabilityEmoji,
15
15
  getConceptEmoji,
16
16
  } from "@forwardimpact/schema/levels";
17
+ import { generateSkillMarkdown } from "@forwardimpact/model";
18
+ import { formatAgentSkill } from "../formatters/agent/skill.js";
19
+
20
+ /** @type {string|null} Cached skill template */
21
+ let skillTemplateCache = null;
22
+
23
+ /**
24
+ * Load skill Mustache template with caching
25
+ * @returns {Promise<string>}
26
+ */
27
+ async function getSkillTemplate() {
28
+ if (!skillTemplateCache) {
29
+ const res = await fetch("./templates/skill.template.md");
30
+ skillTemplateCache = await res.text();
31
+ }
32
+ return skillTemplateCache;
33
+ }
17
34
 
18
35
  /**
19
36
  * Render skills list page
@@ -69,7 +86,7 @@ export function renderSkillsList() {
69
86
  * Render skill detail page
70
87
  * @param {Object} params - Route params
71
88
  */
72
- export function renderSkillDetail(params) {
89
+ export async function renderSkillDetail(params) {
73
90
  const { data } = getState();
74
91
  const skill = data.skills.find((s) => s.id === params.id);
75
92
 
@@ -83,6 +100,14 @@ export function renderSkillDetail(params) {
83
100
  return;
84
101
  }
85
102
 
103
+ // Generate SKILL.md content if skill has an agent section
104
+ let agentSkillContent;
105
+ if (skill.agent) {
106
+ const template = await getSkillTemplate();
107
+ const skillData = generateSkillMarkdown(skill, data.stages);
108
+ agentSkillContent = formatAgentSkill(skillData, template);
109
+ }
110
+
86
111
  // Use DOM formatter - it handles transformation internally
87
112
  render(
88
113
  skillToDOM(skill, {
@@ -90,6 +115,7 @@ export function renderSkillDetail(params) {
90
115
  tracks: data.tracks,
91
116
  drivers: data.drivers,
92
117
  capabilities: data.capabilities,
118
+ agentSkillContent,
93
119
  }),
94
120
  );
95
121
  }
@@ -25,7 +25,7 @@ handoffs:
25
25
 
26
26
  {{{stageDescription}}}
27
27
 
28
- ## Core Identity
28
+ ## Core identity
29
29
 
30
30
  {{{identity}}}
31
31
  {{#priority}}
@@ -34,13 +34,13 @@ handoffs:
34
34
  {{/priority}}
35
35
  {{#roleContext}}
36
36
 
37
- ## Role Context
37
+ ## Role context
38
38
 
39
39
  {{{roleContext}}}
40
40
  {{/roleContext}}
41
41
  {{#hasWorkingStyles}}
42
42
 
43
- ## Working Style
43
+ ## Working style
44
44
  {{#workingStyles}}
45
45
 
46
46
  ### {{title}}
@@ -50,14 +50,14 @@ handoffs:
50
50
  {{/hasWorkingStyles}}
51
51
  {{#hasSkills}}
52
52
 
53
- ## Required Skills
53
+ ## Required skills
54
54
 
55
55
  **MANDATORY:** Before starting work, you MUST read the relevant skill files for
56
56
  project-specific guidance, required tools, and technology standards. Pre-training
57
57
  knowledge alone is insufficient—skills contain organizational standards that
58
58
  override general knowledge.
59
59
 
60
- Each skill file contains XML-tagged sections for precise navigation:
60
+ Each skill contains marked-up sections and references for precise navigation:
61
61
 
62
62
  - `<read_then_do_{{stageId}}>` — Read-Then-Do checklist for the
63
63
  {{stageName}} stage. Read and understand these items BEFORE starting work.
@@ -69,12 +69,15 @@ Each skill file contains XML-tagged sections for precise navigation:
69
69
  organizational standards that override general knowledge or personal
70
70
  preferences.
71
71
  {{#isOnboard}}
72
- - `<onboarding_steps>`Step-by-step environment setup instructions.
73
- Follow these to install prerequisites and configure the development
72
+ - `scripts/install.sh`Self-contained install script for environment setup.
73
+ Run this script to install prerequisites and configure the development
74
74
  environment. Focus on setup only — do not begin feature implementation.
75
+ - `references/REFERENCE.md` — Detailed code examples and reference material.
76
+ Consult this for implementation patterns, common pitfalls, and verification
77
+ steps.
75
78
  {{/isOnboard}}
76
79
 
77
- | Skill | Location | Use When |
80
+ | Skill | Location | Use when |
78
81
  | ----- | -------- | -------- |
79
82
  {{#skillIndex}}
80
83
  | {{{name}}} | `.claude/skills/{{dirname}}/SKILL.md` | {{{useWhen}}} |
@@ -82,7 +85,7 @@ Each skill file contains XML-tagged sections for precise navigation:
82
85
  {{/hasSkills}}
83
86
  {{#hasAgentIndex}}
84
87
 
85
- ## Required Sub-Agent Delegations
88
+ ## Required subagent delegations
86
89
 
87
90
  **MANDATORY:** You MUST delegate work outside your speciality using the
88
91
  `runSubagent` tool. Do not attempt work that another agent is better suited for.
@@ -93,52 +96,19 @@ cannot delegate due to a blocking constraint, document in your output: (1) the
93
96
  specialized work required, (2) the specific constraint preventing delegation,
94
97
  and (3) the compromised approach with acknowledged limitations.
95
98
 
96
- | Agent Name | Speciality | Description |
99
+ | Agent name | Speciality | Description |
97
100
  | ---------- | ---------- | ----------- |
98
101
  {{#agentIndex}}
99
102
  | `{{id}}` | {{{name}}} | {{{description}}} |
100
103
  {{/agentIndex}}
101
104
  {{/hasAgentIndex}}
102
- {{#hasReadChecklist}}
103
105
 
104
- ## Read-Then-Do Checklist
105
-
106
- Before starting work, read and understand these items. They are prerequisites
107
- and context that must be absorbed before implementation begins:
108
-
109
- {{#readChecklist}}
110
- ### {{{capability.emojiIcon}}} {{{skill.name}}}
111
-
112
- {{#items}}
113
- - [ ] {{{.}}}
114
- {{/items}}
115
-
116
- {{/readChecklist}}
117
- {{/hasReadChecklist}}
118
- {{#hasConfirmChecklist}}
119
-
120
- ## Do-Then-Confirm Checklist
121
-
122
- Before offering a handoff, verify and summarize completion of these items:
123
-
124
- {{#confirmChecklist}}
125
- ### {{{capability.emojiIcon}}} {{{skill.name}}}
126
-
127
- {{#items}}
128
- - [ ] {{{.}}}
129
- {{/items}}
130
-
131
- {{/confirmChecklist}}
132
- When verified, summarize what was accomplished then offer the handoff. If items
133
- are incomplete, explain what remains.
134
- {{/hasConfirmChecklist}}
135
-
136
- ## Return Format
106
+ ## Return format
137
107
 
138
108
  When completing work (for handoff or as a subagent), provide:
139
109
 
140
110
  1. **Work completed**: What was accomplished
141
- 2. **Checklist status**: Items verified from Before Handoff section
111
+ 2. **Checklist status**: Items verified from skill Do-Then-Confirm checklists
142
112
  3. **Recommendation**: Ready for next stage, or needs more work
143
113
 
144
114
  {{#hasConstraints}}
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+ # Install script for {{name}}
3
+ # Generated by @forwardimpact/pathway
4
+ {{{installScript}}}
@@ -0,0 +1,3 @@
1
+ # {{{title}}} — Reference
2
+
3
+ {{{implementationReference}}}
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: {{name}}
3
- description: {{{description}}}{{#hasUseWhen}} Use When: {{{useWhen}}}{{/hasUseWhen}}
3
+ description: {{{description}}}{{#hasUseWhen}} Use when {{{useWhen}}}{{/hasUseWhen}}
4
4
  ---
5
5
 
6
6
  # {{{title}}}
@@ -8,40 +8,28 @@ description: {{{description}}}{{#hasUseWhen}} Use When: {{{useWhen}}}{{/hasUseWh
8
8
  {{#descriptionLines}}
9
9
  {{{.}}}
10
10
  {{/descriptionLines}}
11
- {{#hasStages}}
12
-
13
- ## Stage Guidance
14
- {{#stages}}
15
-
16
- ### {{stageName}} Stage
17
-
18
- **Focus:** {{{focus}}}
19
-
20
- <read_then_do_{{stageId}}>
21
-
22
- **Read-Then-Do Checklist:**
23
- {{#readChecklist}}
24
- - [ ] {{{.}}}
25
- {{/readChecklist}}
26
11
 
27
- </read_then_do_{{stageId}}>
12
+ {{#hasInstallScript}}
13
+ Run this to install prerequisites: `scripts/install.sh`
14
+ {{/hasInstallScript}}
15
+ {{#hasReference}}
16
+ See [implementation reference](references/REFERENCE.md) for code examples.
17
+ {{/hasReference}}
18
+ {{#hasUseWhen}}
28
19
 
29
- <do_then_confirm_{{stageId}}>
20
+ ## When to use this skill
30
21
 
31
- **Do-Then-Confirm Checklist:**
32
- {{#confirmChecklist}}
33
- - [ ] {{{.}}}
34
- {{/confirmChecklist}}
22
+ Use this skill when {{{useWhen}}}
23
+ {{/hasUseWhen}}
24
+ {{#hasInstructions}}
35
25
 
36
- </do_then_confirm_{{stageId}}>
37
- {{/stages}}
38
- {{/hasStages}}
26
+ {{{instructions}}}
27
+ {{/hasInstructions}}
39
28
  {{#hasToolReferences}}
40
29
 
41
- <required_tools>
42
-
43
- ## Required Tools
30
+ # Required tools
44
31
 
32
+ <required_tools>
45
33
  **MANDATORY:** You MUST use these tools when applying this skill. These are
46
34
  organizational standards that override general knowledge or personal preferences.
47
35
 
@@ -50,17 +38,32 @@ output: (1) which tool requirement you cannot meet, (2) the specific constraint
50
38
  preventing compliance, and (3) the alternative approach with acknowledged
51
39
  trade-offs.
52
40
 
53
- | Tool | Use When |
41
+ | Tool | Use when |
54
42
  | ---- | -------- |
55
43
  {{#toolReferences}}
56
44
  | {{#url}}[{{{name}}}]({{{url}}}){{/url}}{{^url}}{{{name}}}{{/url}} | {{{useWhen}}} |
57
45
  {{/toolReferences}}
58
-
59
46
  </required_tools>
60
47
  {{/hasToolReferences}}
61
- {{#hasReference}}
48
+ {{#hasStages}}
49
+
50
+ # Stage checklists
51
+ {{#stages}}
62
52
 
63
- # Reference
53
+ ## {{stageName}} stage
64
54
 
65
- {{{reference}}}
66
- {{/hasReference}}
55
+ **Focus:** {{{focus}}}
56
+
57
+ <read_then_do_{{stageId}}>
58
+ {{#readChecklist}}
59
+ - [ ] {{{.}}}
60
+ {{/readChecklist}}
61
+ </read_then_do_{{stageId}}>
62
+
63
+ <do_then_confirm_{{stageId}}>
64
+ {{#confirmChecklist}}
65
+ - [ ] {{{.}}}
66
+ {{/confirmChecklist}}
67
+ </do_then_confirm_{{stageId}}>
68
+ {{/stages}}
69
+ {{/hasStages}}