@jenga-ai/agent 2.0.0 → 3.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.
Files changed (177) hide show
  1. package/README.md +82 -243
  2. package/agents/developer.md +5 -5
  3. package/agents/scrum-master.md +23 -23
  4. package/agents/tester.md +5 -5
  5. package/bin/jenga.js +10 -0
  6. package/hooks/copilot_session_end.sh +7 -3
  7. package/hooks/prompt_router_helper.js +17 -5
  8. package/lib/commands/doctor.js +351 -0
  9. package/lib/commands/init.js +16 -0
  10. package/lib/generate-copilot-hooks.js +116 -0
  11. package/lib/generate-skill-allow-list.js +9 -3
  12. package/lib/legacy-shipped-paths.json +336 -0
  13. package/lib/postinstall-manifest.js +469 -0
  14. package/lib/skill-allow-list.json +2 -3
  15. package/package.json +16 -25
  16. package/scripts/apply-j-prefix.sh +25 -12
  17. package/scripts/generate-j-alias.sh +333 -0
  18. package/scripts/generate-legacy-shipped-paths.js +248 -0
  19. package/scripts/postinstall.js +205 -2
  20. package/scripts/verify-legacy-seed-reconcile.sh +254 -0
  21. package/scripts/verify-postinstall-reconcile.sh +392 -0
  22. package/skills/{brainstorm → j-brainstorm}/SKILL.md +9 -2
  23. package/skills/{btw → j-btw}/SKILL.md +9 -2
  24. package/skills/{clearify → j-clearify}/SKILL.md +9 -2
  25. package/skills/{close-story → j-close-story}/SKILL.md +17 -10
  26. package/skills/{close-story → j-close-story}/scripts/check-privatized.sh +2 -2
  27. package/skills/{close-story → j-close-story}/scripts/check-story-closeable.sh +1 -1
  28. package/skills/{close-story → j-close-story}/scripts/extract-task-diff-stats.sh +1 -1
  29. package/skills/{commit → j-commit}/SKILL.md +9 -2
  30. package/skills/j-continue/SKILL.md +36 -0
  31. package/skills/{deep-dive → j-deep-dive}/SKILL.md +9 -8
  32. package/skills/{dev-done → j-dev-done}/SKILL.md +11 -4
  33. package/skills/{dev-done → j-dev-done}/scripts/classify-commit-outcome.sh +4 -4
  34. package/skills/{distribute → j-distribute}/SKILL.md +17 -10
  35. package/skills/{distribute → j-distribute}/scripts/distribute-changes.sh +1 -1
  36. package/skills/{do → j-do}/SKILL.md +12 -5
  37. package/skills/{doc → j-doc}/README.md +5 -5
  38. package/skills/{doc → j-doc}/SKILL.md +15 -8
  39. package/skills/{doc → j-doc}/authoring-notes.md +1 -1
  40. package/skills/{doc-sync → j-doc-sync}/SKILL.md +9 -2
  41. package/skills/{dooo → j-dooo}/SKILL.md +9 -2
  42. package/skills/j-error/SKILL.md +36 -0
  43. package/skills/{evaluate → j-evaluate}/SKILL.md +9 -2
  44. package/skills/j-examplify/SKILL.md +49 -0
  45. package/skills/{help → j-help}/SKILL.md +9 -2
  46. package/skills/{idea → j-idea}/SKILL.md +10 -3
  47. package/skills/{idea → j-idea}/assets/idea_handoff_template.md +1 -1
  48. package/skills/{improve → j-improve}/SKILL.md +9 -2
  49. package/skills/j-init/SKILL.md +2 -2
  50. package/skills/j-jbp/SKILL.md +32 -0
  51. package/skills/j-lgtm/SKILL.md +28 -0
  52. package/skills/{pi-plan → j-pi-plan}/SKILL.md +10 -3
  53. package/skills/{proceed → j-proceed}/SKILL.md +9 -2
  54. package/skills/{publish → j-publish}/SKILL.md +47 -40
  55. package/skills/{publish → j-publish}/adapters/droplet.md +1 -1
  56. package/skills/{publish → j-publish}/adapters/mobile-ios.md +3 -3
  57. package/skills/{publish → j-publish}/adapters/npm-ci.md +3 -3
  58. package/skills/{publish → j-publish}/adapters/npm.md +8 -8
  59. package/skills/{publish → j-publish}/assets/ci-contract.md +2 -2
  60. package/skills/{publish → j-publish}/schemas/publish.schema.json +1 -1
  61. package/skills/{publish → j-publish}/scripts/npm_stage_inspect.sh +34 -1
  62. package/skills/{publish → j-publish}/scripts/npm_stage_pipeline.sh +9 -4
  63. package/skills/{publish → j-publish}/scripts/publish_deploy.sh +4 -4
  64. package/skills/{publish → j-publish}/scripts/validate_npm_stage_env.sh +1 -1
  65. package/skills/{publish → j-publish}/wizards/droplet.md +1 -1
  66. package/skills/{publish → j-publish}/wizards/mobile-ios.md +1 -1
  67. package/skills/{publish → j-publish}/wizards/npm-ci.md +1 -1
  68. package/skills/{publish → j-publish}/wizards/npm.md +1 -1
  69. package/skills/{reconcile → j-reconcile}/SKILL.md +12 -5
  70. package/skills/{reconcile → j-reconcile}/scripts/detect-unlinked-code.sh +2 -2
  71. package/skills/{reconcile → j-reconcile}/scripts/resolve-reconcile-scope.sh +3 -3
  72. package/skills/{reconcile-origin → j-reconcile-origin}/SKILL.md +13 -6
  73. package/skills/{redo → j-redo}/SKILL.md +9 -2
  74. package/skills/{skillify → j-skillify}/SKILL.md +10 -3
  75. package/skills/{spinoff → j-spinoff}/SKILL.md +9 -2
  76. package/skills/{status → j-status}/SKILL.md +9 -2
  77. package/skills/{todo → j-todo}/SKILL.md +10 -3
  78. package/skills/{todo → j-todo}/assets/todo_handoff_template.md +1 -1
  79. package/skills/{todo → j-todo}/scripts/add_trivial_task.sh +3 -3
  80. package/skills/{todo → j-todo}/scripts/update_story_tasks.py +2 -2
  81. package/skills/{uncharted → j-uncharted}/SKILL.md +35 -28
  82. package/skills/{uncharted → j-uncharted}/assets/UNDERSTANDING_DOC_TEMPLATE.md +2 -2
  83. package/skills/{uncharted → j-uncharted}/scripts/detect-dependencies.sh +1 -1
  84. package/skills/{uncharted → j-uncharted}/scripts/detect-tests.sh +1 -1
  85. package/skills/{uncharted → j-uncharted}/scripts/directory-triage.sh +3 -3
  86. package/skills/{uncharted → j-uncharted}/scripts/elicitation-state.sh +3 -3
  87. package/skills/{uncharted → j-uncharted}/scripts/enumerate-target.sh +1 -1
  88. package/skills/{uncharted → j-uncharted}/scripts/import-source.sh +1 -1
  89. package/skills/{uncharted → j-uncharted}/scripts/inspect-provenance.sh +1 -1
  90. package/skills/{uncharted → j-uncharted}/scripts/resolve-segment-target.sh +5 -5
  91. package/skills/{uncharted → j-uncharted}/scripts/run-engine.sh +1 -1
  92. package/skills/{uncharted → j-uncharted}/scripts/validate-proposed-items.sh +2 -2
  93. package/skills/{uncharted → j-uncharted}/scripts/write-backfilled-epics.sh +1 -1
  94. package/skills/j-wtf/SKILL.md +27 -0
  95. package/skills/jenga/SKILL.md +1 -1
  96. package/skills/jenga-permission-level/SKILL.md +1 -1
  97. package/templates/SCRUM_BOARD_SCHEMA.md +1 -1
  98. package/templates/agent-context.md.tpl +10 -10
  99. package/templates/copilot-instructions.md.tpl +89 -19
  100. package/skills/continue/SKILL.md +0 -29
  101. package/skills/error/SKILL.md +0 -29
  102. package/skills/examplify/SKILL.md +0 -42
  103. package/skills/init/SKILL.md +0 -155
  104. package/skills/init/assets/scope-thresholds_template.json +0 -7
  105. package/skills/init/assets/strategy_stub_template.md +0 -38
  106. package/skills/init/assets/workflow_template.json +0 -30
  107. package/skills/init/scripts/apply-project-visibility.sh +0 -176
  108. package/skills/init/scripts/detect-existing-codebase.sh +0 -166
  109. package/skills/init/scripts/init.sh +0 -116
  110. package/skills/jbp/SKILL.md +0 -25
  111. package/skills/lgtm/SKILL.md +0 -21
  112. package/skills/skillify/assets/init-new/assets/.gitignore_template +0 -15
  113. package/skills/skillify/assets/init-new/assets/PROJECT_SUMMARY_template.md +0 -13
  114. package/skills/skillify/assets/init-new/assets/directory_structure.txt +0 -14
  115. package/skills/skillify/assets/init-new/assets/test-config_template.json +0 -4
  116. package/skills/wtf/SKILL.md +0 -20
  117. /package/skills/{close-story → j-close-story}/scripts/compute-scope-divergence.sh +0 -0
  118. /package/skills/{close-story → j-close-story}/scripts/extract-diff-stats.sh +0 -0
  119. /package/skills/{close-story → j-close-story}/scripts/update-task-frontmatter.sh +0 -0
  120. /package/skills/{commit → j-commit}/assets/user_instructions_template.md +0 -0
  121. /package/skills/{distribute → j-distribute}/CONFIG_SCHEMA.md +0 -0
  122. /package/skills/{distribute → j-distribute}/scripts/check-version.sh +0 -0
  123. /package/skills/{distribute → j-distribute}/scripts/commit-version-bump.sh +0 -0
  124. /package/skills/{do → j-do}/assets/intent-vs-diff-prompt.md +0 -0
  125. /package/skills/{do → j-do}/assets/sender_template.json +0 -0
  126. /package/skills/{doc → j-doc}/assets/path-objectives.yaml +0 -0
  127. /package/skills/{doc → j-doc}/scripts/resolve_last_update.py +0 -0
  128. /package/skills/{doc-sync → j-doc-sync}/assets/default_excludes.txt +0 -0
  129. /package/skills/{doc-sync → j-doc-sync}/assets/doc_targets.md +0 -0
  130. /package/skills/{evaluate → j-evaluate}/assets/evaluation_invokation_template.yml +0 -0
  131. /package/skills/{evaluate → j-evaluate}/assets/evaluation_rapport_template.md +0 -0
  132. /package/skills/{idea → j-idea}/assets/idea_template.md +0 -0
  133. /package/skills/{pi-plan → j-pi-plan}/assets/epic.json +0 -0
  134. /package/skills/{pi-plan → j-pi-plan}/assets/story_template.md +0 -0
  135. /package/skills/{publish → j-publish}/assets/ExportOptions.plist.template +0 -0
  136. /package/skills/{publish → j-publish}/assets/ownership-matrix.md +0 -0
  137. /package/skills/{publish → j-publish}/assets/publish.example.json +0 -0
  138. /package/skills/{publish → j-publish}/assets/publish.example.npm-ci.json +0 -0
  139. /package/skills/{publish → j-publish}/assets/publish.example.npm.json +0 -0
  140. /package/skills/{publish → j-publish}/assets/secrets-guide.md +0 -0
  141. /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-minimal.json +0 -0
  142. /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-with-empty-secrets.json +0 -0
  143. /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-with-workflow-path.json +0 -0
  144. /package/skills/{publish → j-publish}/scripts/check_target_config.sh +0 -0
  145. /package/skills/{publish → j-publish}/scripts/droplet_pipeline.sh +0 -0
  146. /package/skills/{publish → j-publish}/scripts/finalize_changelog.sh +0 -0
  147. /package/skills/{publish → j-publish}/scripts/generate_release_notes.sh +0 -0
  148. /package/skills/{publish → j-publish}/scripts/ios_pipeline.sh +0 -0
  149. /package/skills/{publish → j-publish}/scripts/npm_ci_pipeline.sh +0 -0
  150. /package/skills/{publish → j-publish}/scripts/npm_pipeline.sh +0 -0
  151. /package/skills/{publish → j-publish}/scripts/publish_common.sh +0 -0
  152. /package/skills/{publish → j-publish}/scripts/reconcile_tags.sh +0 -0
  153. /package/skills/{publish → j-publish}/scripts/run_gates.sh +0 -0
  154. /package/skills/{publish → j-publish}/scripts/setup_wizard.sh +0 -0
  155. /package/skills/{publish → j-publish}/scripts/show_history.sh +0 -0
  156. /package/skills/{publish → j-publish}/scripts/suggest_semver_bump.sh +0 -0
  157. /package/skills/{publish → j-publish}/scripts/validate_config.sh +0 -0
  158. /package/skills/{publish → j-publish}/scripts/validate_droplet_env.sh +0 -0
  159. /package/skills/{publish → j-publish}/scripts/validate_ios_env.sh +0 -0
  160. /package/skills/{publish → j-publish}/scripts/validate_npm_ci_env.sh +0 -0
  161. /package/skills/{publish → j-publish}/scripts/validate_npm_env.sh +0 -0
  162. /package/skills/{publish → j-publish}/scripts/write_ledger_entry.sh +0 -0
  163. /package/skills/{reconcile → j-reconcile}/assets/report_format.md +0 -0
  164. /package/skills/{reconcile-origin → j-reconcile-origin}/scripts/reconcile-origin.sh +0 -0
  165. /package/skills/{skillify → j-skillify}/assets/init-new/SKILL.md +0 -0
  166. /package/skills/{init → j-skillify/assets/init-new}/assets/.gitignore_template +0 -0
  167. /package/skills/{init → j-skillify/assets/init-new}/assets/PROJECT_SUMMARY_template.md +0 -0
  168. /package/skills/{init → j-skillify/assets/init-new}/assets/directory_structure.txt +0 -0
  169. /package/skills/{init → j-skillify/assets/init-new}/assets/test-config_template.json +0 -0
  170. /package/skills/{skillify → j-skillify}/assets/init-new/assets/workflow_template.json +0 -0
  171. /package/skills/{skillify → j-skillify}/assets/init-new/scripts/init.sh +0 -0
  172. /package/skills/{skillify → j-skillify}/assets/init-old/SKILL.md +0 -0
  173. /package/skills/{status → j-status}/assets/output_format.md +0 -0
  174. /package/skills/{todo → j-todo}/assets/todo_template.md +0 -0
  175. /package/skills/{uncharted → j-uncharted}/assets/SEGMENT_PROPOSAL_TEMPLATE.md +0 -0
  176. /package/skills/{uncharted → j-uncharted}/scripts/apply-subsystem-cap.sh +0 -0
  177. /package/skills/{uncharted → j-uncharted}/scripts/discover-subsystems.sh +0 -0
@@ -9,8 +9,15 @@ This project uses **Jenga** — a skill-based AI agent framework. Jenga organise
9
9
 
10
10
  ### How Jenga Works
11
11
 
12
- - Each **skill** is a self-contained instruction set stored under `.agents/skills/<skill-name>/` (the non-Claude discovery path; Claude Code reads the same content from `.claude/skills/`).
13
- - Skills are invoked by typing `j:skill-name` in the chat prompt (e.g. `j:status`, `j:commit`). The
12
+ - Each **skill** is a self-contained instruction set: a `SKILL.md` file inside a per-skill directory.
13
+ Copilot discovers project skills from **all three** of `.github/skills/`, `.agents/skills/`, and
14
+ `.claude/skills/`. Jenga installs its skills under `.agents/skills/<skill-name>/` and mirrors
15
+ byte-identical content into `.claude/skills/<skill-name>/`; when the same skill name is found in
16
+ more than one of those directories, `.agents/skills/` takes precedence. Cite and open
17
+ `.agents/skills/` as the canonical path.
18
+ - A skill's **identity is its frontmatter `name:` field, not its directory name**. Jenga names every
19
+ skill `j.<skill-name>` — the skill in `.agents/skills/status/` declares `name: j.status`.
20
+ - Skills are invoked by typing `j.skill-name` in the chat prompt (e.g. `j.status`, `j.commit`). The
14
21
  older bare `/skill-name` form (e.g. `/status`, `/commit`) is a **permanent alias** — it keeps
15
22
  resolving indefinitely, with no deprecation warning and no removal planned — so treat a message in
16
23
  either form as the exact same invocation.
@@ -18,22 +25,43 @@ This project uses **Jenga** — a skill-based AI agent framework. Jenga organise
18
25
 
19
26
  ### Skill Routing
20
27
 
21
- Unlike Claude Code, GitHub Copilot has **no native slash-command interception** — typing `j:skill-name`
22
- (or the older bare `/skill-name` alias) does not automatically load or run anything on its own. Copilot
23
- depends entirely on the instructions below to know what "invoking a skill" concretely means. Do not
24
- improvise a plausible-sounding response instead of following these steps — that is the exact failure
25
- this section exists to prevent.
28
+ **Copilot loads these skills natively.** Copilot has a real, validating skill loader. It reads every
29
+ `SKILL.md` under the discovery paths above and validates each one's frontmatter `name:` against:
26
30
 
27
- **Old bare-form alias.** `j:skill-name` is the canonical invocation form. A message using the older
31
+ ```
32
+ Skill name must start with an ASCII letter or number and contain only
33
+ ASCII letters (a-z, A-Z), numbers, hyphens, underscores, dots, and spaces
34
+ ```
35
+
36
+ A skill whose name fails that rule **does not load at all** — it is reported under "failed to load"
37
+ by `copilot skill list` and is simply absent from the session. Every skill that does load is
38
+ registered as a **native slash command named after its frontmatter `name`**, matched
39
+ case-insensitively: `j.status` is invocable as `/j.status` and appears in the slash-command picker.
40
+ That native path loads and applies the skill on its own — you do not need to locate or open the file
41
+ yourself when the user types it.
42
+
43
+ **What still depends on these instructions.** Native registration covers only the exact
44
+ `/j.skill-name` form. These forms have **no** native handler and are routed entirely by the steps
45
+ below:
46
+
47
+ - the no-slash `j.skill-name` form, which is Jenga's documented invocation style;
48
+ - the older bare `/skill-name` alias (`/status`, `/commit`);
49
+ - a message that matches a skill by keyword or intent rather than by a literal command.
50
+
51
+ For those, do not improvise a plausible-sounding response instead of following these steps — that is
52
+ the exact failure this section exists to prevent.
53
+
54
+ **Old bare-form alias.** `j.skill-name` is the canonical invocation form. A message using the older
28
55
  bare `/skill-name` form is not deprecated and must not be treated as an error, a warning case, or a
29
- migration prompt — route it to the identical skill as its `j:skill-name` equivalent. Both forms remain
56
+ migration prompt — route it to the identical skill as its `j.skill-name` equivalent. Both forms remain
30
57
  equally valid indefinitely.
31
58
 
32
- When the user's message is or matches `j:skill-name`, or matches the older bare `/skill-name` alias (or
59
+ When the user's message is or matches `j.skill-name`, or matches the older bare `/skill-name` alias (or
33
60
  otherwise clearly matches a known skill's keyword or intent):
34
61
 
35
62
  1. Locate the target file at `.agents/skills/<skill-name>/SKILL.md` (the discovery path from "How
36
- Jenga Works" above).
63
+ Jenga Works" above; `.claude/skills/<skill-name>/SKILL.md` holds identical content if the first
64
+ is absent). Note the directory is the **unprefixed** name — `j.status` lives in `status/`.
37
65
  2. Open and read that file **in full** before doing anything else.
38
66
  3. Execute its instructions exactly as written, for the rest of this turn — including running any
39
67
  shell scripts or commands it references (e.g. via a terminal/shell tool).
@@ -46,20 +74,61 @@ answer directly using your full capabilities.
46
74
 
47
75
  #### Routing decision table
48
76
 
49
- Before acting on any row below that opens a `SKILL.md` file, first check the identifier against
50
- the trusted allow-list: {{ALLOWED_SKILL_IDS}}. Since Copilot/Codex has no native interception for
51
- `j:skill-name`, this prose-level check is the entire enforcement mechanism — there is no runtime
52
- guard behind it.
77
+ Before acting on any row below that opens a `SKILL.md` file yourself, check the identifier against
78
+ the trusted allow-list: {{ALLOWED_SKILL_IDS}}.
79
+
80
+ There are two enforcement layers, and they cover different inputs:
81
+
82
+ 1. **Copilot's own loader** handles the native `/j.skill-name` form. It only ever registers a skill
83
+ that is actually present under a discovery path and passed name validation.
84
+ 2. **This prose allow-list check** is the second layer — and the *only* layer for the forms Copilot
85
+ does not natively intercept: the no-slash `j.skill-name` form, the bare `/skill-name` alias, and
86
+ keyword or intent matches. Apply it whenever you are about to open a `SKILL.md` yourself.
87
+
88
+ Neither layer inspects a skill's *contents*; both defend the invocation-matching layer only.
53
89
 
54
90
  | Situation | Action |
55
91
  |-----------|--------|
56
- | Message matches `j:skill-name` and `skill-name` is in the allow-list | Open `.agents/skills/<skill-name>/SKILL.md`, read it fully, execute it as written |
57
- | Message matches the older bare `/skill-name` alias and `skill-name` is in the allow-list | Treat identically to `j:skill-name` — same skill, same file, no warning, no migration prompt |
92
+ | User types the native `/j.skill-name` slash command | Copilot's loader applies the skill; follow the loaded instructions as written |
93
+ | Message matches `j.skill-name` (no slash) and `skill-name` is in the allow-list | Open `.agents/skills/<skill-name>/SKILL.md`, read it fully, execute it as written |
94
+ | Message matches the older bare `/skill-name` alias and `skill-name` is in the allow-list | Treat identically to `j.skill-name` — same skill, same file, no warning, no migration prompt |
58
95
  | Message matches a skill keyword or intent and the matched skill is in the allow-list | Open `.agents/skills/<skill-name>/SKILL.md`, read it fully, execute it as written |
59
- | Message matches `j:skill-name` or `/skill-name`, but `skill-name` is **not** in the allow-list | Do not open or execute anything — tell the user the identifier is unrecognized and is not a known Jenga skill |
96
+ | Message matches `j.skill-name` or `/skill-name`, but `skill-name` is **not** in the allow-list | Do not open or execute anything — tell the user the identifier is unrecognized and is not a known Jenga skill |
60
97
  | Message is a general coding or project question | Answer directly |
61
98
  | Ambiguous — could be skill or free-form | Prefer the skill; open and execute its `SKILL.md` rather than describing it |
62
99
 
100
+ ### Sub-Agent Delegation (`prefered_agent`)
101
+
102
+ Some skills declare a `metadata.prefered_agent: <agent_name>` field in their `SKILL.md`
103
+ frontmatter. This names a sub-agent persona — a file under `agents/` (`scrum-master`,
104
+ `developer`, `tester`) — that should execute the skill, the same delegation Claude Code performs
105
+ natively for the same skill via root `CLAUDE.md`'s "Skill Frontmatter" section.
106
+
107
+ **Copilot CLI has its own native custom-agent-loading mechanism for this.** The `--agent <name>`
108
+ CLI flag and the interactive `/agent [name]` command both load a custom agent-definition file
109
+ discovered from `.github/agents/*.md` or `.claude/agents/*.md`, keyed by that file's frontmatter
110
+ `name:` field — not its filename. Jenga's `agents/*.md` personas are mirrored into both of those
111
+ paths by `/self-sync` (`skills/self-sync/scripts/run.js`); cite `.github/agents/` as the
112
+ canonical path for this purpose, parallel to how "How Jenga Works" above cites `.agents/skills/`
113
+ as canonical for skills. `.agents/agents/` is also mirrored (for reasons unrelated to Copilot)
114
+ but is a **confirmed Copilot-discovery dead-end** — the native agent loader does not read it;
115
+ never rely on it when resolving a `prefered_agent`.
116
+
117
+ When a matched skill's frontmatter has `metadata.prefered_agent: <agent_name>`:
118
+
119
+ 1. Before executing the skill's instructions, load that persona by invoking `--agent
120
+ <agent_name>` (if starting a new `copilot` invocation) or the interactive `/agent
121
+ <agent_name>` command (if already in an interactive session).
122
+ 2. Then proceed with the skill's instructions exactly as written, per the "Skill Routing"
123
+ section above — the loaded agent persona governs *how* the skill executes, not *whether* it
124
+ does, and does not change which `SKILL.md` file gets opened or the allow-list check that
125
+ precedes it.
126
+ 3. If a skill's frontmatter has no `prefered_agent` field, execute it directly with no agent
127
+ switch.
128
+
129
+ Valid `<agent_name>` values match the agent definitions under `agents/` (frontmatter `name:`
130
+ field, not the filename): `scrum-master`, `developer`, `tester`.
131
+
63
132
  ### Available Skills
64
133
 
65
134
  {{SKILL_LIST}}
@@ -77,6 +146,7 @@ The `hooks/`, `lib/`, `scripts/`, `templates/`, and `mcp/` directories all live
77
146
  ### Notes
78
147
 
79
148
  - Always resolve file paths relative to `JENGA_PROJECT_DIR`.
80
- - When a skill asks you to read a file such as `SKILL.md` or a task file, look for it inside `JENGA_PROJECT_DIR/.agents/skills/` or `JENGA_PROJECT_DIR/project/board/` respectively.
149
+ - When a skill asks you to read a file such as `SKILL.md` or a task file, look for it inside `JENGA_PROJECT_DIR/.agents/skills/` (or `JENGA_PROJECT_DIR/.claude/skills/`, which mirrors it) or `JENGA_PROJECT_DIR/project/board/` respectively.
150
+ - If a Jenga skill seems to be missing entirely, run `copilot skill list` and check the "failed to load" section before assuming it does not exist — a name that fails validation is absent rather than broken.
81
151
  - Commit messages and branch names follow the EST naming convention (`E<n>_S<n>_T<n>`).
82
152
  <!-- JENGA:END -->
@@ -1,29 +0,0 @@
1
- ---
2
- name: j:continue
3
- description: Check project status across PROJECT_SUMMARY.md, epics, and stories to determine what should be done next. Reports "All done!" if everything is complete.
4
- keywords:
5
- - continue
6
- - next
7
- - proceed
8
- - what's next
9
- - status
10
- examples:
11
- - "what should I do next?"
12
- - "continue with the project"
13
- ---
14
-
15
- # Continue — Pick Up the Next Work Item
16
-
17
- ## Instructions
18
-
19
- 1. **Check `project/PROJECT_SUMMARY.md`** — Determine if there is outstanding work at the project level.
20
-
21
- 2. **Check `project/epics/`** — If the project summary is done, check if any epics have remaining work.
22
-
23
- 3. **Check `project/stories/`** — If epics are done, check if any stories have remaining work.
24
-
25
- **Important:** Always check story status within an epic even if the epic itself is marked as done.
26
-
27
- 4. **If everything is complete** — Respond with: "All done! 🎉"
28
-
29
- 5. **Otherwise** — Begin work on the next incomplete item.
@@ -1,29 +0,0 @@
1
- ---
2
- name: j:error
3
- description: Guided troubleshooting flow that gathers context about an error — where it occurs, what was attempted, what went wrong, and what was expected.
4
- keywords:
5
- - error
6
- - bug
7
- - fix
8
- - troubleshoot
9
- - debug
10
- - broken
11
- examples:
12
- - "I'm getting an error"
13
- - "help me fix this bug"
14
- metadata:
15
- prefered_agent: tester
16
- ---
17
-
18
- # Error — Guided Troubleshooting
19
-
20
- ## Instructions
21
-
22
- Ask the following questions to understand the background of the error:
23
-
24
- 1. Where does the error occur?
25
- 2. What are you trying to do?
26
- 3. What went wrong?
27
- 4. What was the expected outcome?
28
-
29
- Then use the answers to investigate and resolve the issue by creating a issue using the /todo skill.
@@ -1,42 +0,0 @@
1
- ---
2
- name: j:examplify
3
- description: Explains concepts, features, use cases, and patterns based on provided context — a description, scenario, code snippet, or file. Use when the user wants to understand what something is, how it works, when to use it, or wants a concrete example.
4
- keywords:
5
- - examplify
6
- - explain
7
- - example
8
- - how does
9
- - understand
10
- examples:
11
- - "explain how this works"
12
- - "give me an example of X"
13
- ---
14
-
15
- # Concept Explainer
16
-
17
- ## Instructions
18
-
19
- If the context is unclear or too broad, ask one focused clarifying question before proceeding. Otherwise, infer and proceed.
20
-
21
- Explain the concept by covering:
22
-
23
- 1. **What it is** — a plain-language definition
24
- 2. **Why it exists** — the problem it solves
25
- 3. **How it works** — core mechanics
26
- 4. **When to use it** — and when not to
27
- 5. **Example(s)** — grounded in the user's context; show a before/after when relevant
28
-
29
- After delivering the explanation, save a copy to:
30
- `project/documentation/examples/<concept_and_context>.md`
31
-
32
- Derive the filename from the concept + context (lowercased, hyphenated). Tell the user where the file was saved.
33
-
34
- ## Follow-up
35
-
36
- If further discussion reveals new information about the topic — a new use case, correction, or better example — ask the user:
37
-
38
- > "That adds something new to what we covered — want me to update the saved file?"
39
- 1. Yes
40
- 2. No
41
-
42
- If yes, append the new content under an `## Additional Notes` section. Do not overwrite the original.
@@ -1,155 +0,0 @@
1
- ---
2
- name: j:init
3
- description: Initialize a new project with the standard directory structure, PROJECT_SUMMARY.md, workflow.json, git repo, and gitignore. Follows a defined ordered onboarding sequence. Use when setting up a new or empty project.
4
- keywords:
5
- - init
6
- - initialize
7
- - setup
8
- - new project
9
- - scaffold
10
- examples:
11
- - "initialize a new project"
12
- - "set up a new workspace"
13
- ---
14
-
15
- # Init — Project Setup
16
-
17
- ## Instructions
18
-
19
- Follow these steps in order. Do not skip steps — the sequence matters.
20
-
21
- ### 1. Detect existing project state
22
-
23
- Before asking anything or scaffolding anything, classify the target directory
24
- (the current directory) by running the detection script:
25
-
26
- ```bash
27
- skills/init/scripts/detect-existing-codebase.sh .
28
- ```
29
-
30
- It prints exactly one verdict on stdout:
31
-
32
- | Verdict | Meaning | What to do |
33
- |---|---|---|
34
- | `empty` | The directory is empty, or contains only `.git`, `.gitignore`, and top-level `README*`/`LICENSE*` boilerplate. | Proceed to step 2 — behaviour here is unchanged from before this detection step existed. |
35
- | `already-scaffolded` | `project/board/`, `project/PROJECT_SUMMARY.md`, or `project/configs/workflow.json` already exists. | Tell the user this directory already has a Jenga scaffold and **stop** — do not run the scaffold script. Re-running it would silently overwrite `PROJECT_SUMMARY.md` and `workflow.json` with fresh stubs. Point them at `/continue` or `/status` instead. |
36
- | `existing-codebase` | The directory has real content (source, configs, docs beyond the boilerplate list) and is not already scaffolded. | **Pause. Do not scaffold.** Present the choice below and wait for an answer. |
37
-
38
- On `existing-codebase`, present this choice verbatim, per the Interaction Pattern in
39
- `CLAUDE.md` (numbered, free-text last):
40
-
41
- This directory already contains code that wasn't built through Jenga. How would
42
- you like to proceed?
43
- 1. Run /uncharted onboard first, to analyze the existing code and backfill the
44
- board before scaffolding
45
- 2. Scaffold fresh anyway, leaving the board empty (the existing code is never
46
- modified either way — onboard mode and fresh scaffolding are both board-only)
47
- 3. Abort — don't scaffold, don't run /uncharted
48
- 4. Other (describe below)
49
-
50
- - **Option 1** — invoke `/uncharted onboard`. It analyzes the existing code and backfills
51
- the board; it never modifies, moves, or restructures application code. Once it
52
- finishes, the directory now has `project/PROJECT_SUMMARY.md` etc., so re-running this
53
- detection step returns `already-scaffolded` — there is nothing left to scaffold.
54
- - **Option 2** — continue to step 2 and scaffold fresh. Note in your response that the
55
- board will start empty despite the directory containing pre-existing code, since the
56
- user explicitly chose that.
57
- - **Option 3** — stop here. Do not run the scaffold script and do not invoke `/uncharted`.
58
- - **Option 4** — handle the free-text response on its own merits.
59
-
60
- If the run is non-interactive (no user available to answer), default to **option 3
61
- (abort)**. Unlike the visibility question in step 2, none of these three choices is a
62
- no-op: running `/uncharted onboard` unattended commits an analysis pass the user never
63
- asked for, and scaffolding fresh unattended silently discards pre-existing code from the
64
- board exactly as `/init` did before this step existed. Aborting is the only choice that
65
- changes nothing on disk, so it is the only safe default.
66
-
67
- Never treat `existing-codebase` as if it were `empty`, and never skip straight to step 2
68
- on that verdict without the user (or the non-interactive default) choosing to.
69
-
70
- ### 2. Ask how Jenga AI's working files should appear
71
-
72
- Ask the user this question, verbatim, before running any script:
73
-
74
- How should Jenga AI's own working files (project/ — the scrum board, todo.md,
75
- queue/, rapports/, and logs/) appear in this project?
76
- 1. Visible — keep them at `project/`, tracked and visible in directory listings
77
- 2. Ignored — keep them at `project/` but add them to `.gitignore` so they are never committed
78
- 3. Not sure — explain the trade-offs and ask me again
79
-
80
- If the user picks option 3, explain the trade-offs and re-ask. Do not proceed until
81
- the answer is one of `visible` or `ignored`.
82
-
83
- If the run is non-interactive (no user available to answer), use the default:
84
- **`visible`**. It is the only choice that changes nothing on disk, so an unattended
85
- run can never silently relocate directories or edit `.gitignore`.
86
-
87
- > A third mode, `hidden` (dot-prefixing `project/` to `.project/`, matching the
88
- > `.agents/`/`.claude/` convention), was built and then withdrawn before release —
89
- > testing found it left board resolution and session-end hooks writing to two
90
- > different trees. It is not offered here. See
91
- > `skills/distribute/CONFIG_SCHEMA.md` for the root-cause note and the tracked
92
- > follow-up to reintroduce it once fixed.
93
-
94
- Carry the chosen value into step 3. Do not apply it yourself — the script owns all
95
- of the mechanical work.
96
-
97
- ### 3. Run the scaffold script
98
-
99
- `init.sh` is not guaranteed to live at a single fixed path: in a project that
100
- installed Jenga via npm, it was mirrored to `.claude/skills/init/scripts/`
101
- (Claude Code) and `.agents/skills/init/scripts/` (Copilot/other agents) by
102
- `postinstall.js`, and neither of those exists yet in this framework's own
103
- source checkout, where it lives at the bare `skills/init/scripts/` path
104
- instead. This step runs before `CLAUDE.md`/`AGENTS.md` exist, so it cannot
105
- rely on either file's routing instructions to resolve the path — it must
106
- locate its own script directly. Execute the init script from the project
107
- root, passing the choice from step 2:
108
-
109
- ```bash
110
- INIT_SCRIPT=""
111
- for candidate in .claude/skills/init/scripts/init.sh .agents/skills/init/scripts/init.sh skills/init/scripts/init.sh; do
112
- [[ -f "$candidate" ]] && { INIT_SCRIPT="$candidate"; break; }
113
- done
114
- if [[ -z "$INIT_SCRIPT" ]]; then
115
- echo "Error: could not locate init.sh under .claude/skills/, .agents/skills/, or skills/" >&2
116
- exit 1
117
- fi
118
- chmod +x "$INIT_SCRIPT" && "$INIT_SCRIPT" --visibility <visible|ignored>
119
- ```
120
-
121
- Omitting `--visibility` falls back to the `JENGA_PROJECT_FILES_VISIBILITY`
122
- environment variable, then to `visible`.
123
-
124
- This script handles all scaffolding in one step:
125
- 1. Initializes the git repository
126
- 2. Creates `.gitignore`
127
- 3. Creates the full directory structure under `project/`
128
- 4. Creates `project/PROJECT_SUMMARY.md` with placeholder content
129
- 5. Creates `project/configs/workflow.json` with shared constants
130
- 6. Creates `project/configs/test-config.json` stub
131
- 7. Creates `project/configs/scope-thresholds.json` with default execution-scope thresholds (consumed by `/jenga` and `/do`, which halt if it's missing)
132
- 8. Creates `project/data/baselines.json`
133
- 9. Creates `project/logs/events.json`
134
- 10. Creates `docs/STRATEGY.md` — a strategic brief stub intended for investors, partners, and the product team
135
- 11. Creates `CHANGELOG.md` from the shared template — a running log of notable changes, seeded with an `[Unreleased]` section
136
- 12. Applies the chosen visibility mode via `scripts/apply-project-visibility.sh`, which records it as `project_files_visibility` in `jenga.config.json` and performs any `.gitignore` change
137
- 13. Stages and commits all files with the message `init: scaffold project structure and workflow config`
138
-
139
- The visibility mode is validated before any scaffolding happens, so an invalid
140
- value fails fast and leaves nothing behind. It is applied before the commit, so
141
- the `.gitignore` entry is captured in the initial commit.
142
-
143
- If the script fails, check that you are in the project root and that git and `jq`
144
- are available.
145
-
146
- See `skills/distribute/CONFIG_SCHEMA.md` for the full `project_files_visibility`
147
- field reference.
148
-
149
- ### 4. Prompt next step
150
-
151
- Inform the user that setup is complete, and state which visibility mode was applied
152
- and where the working files now live. Mention that `docs/STRATEGY.md` was created as
153
- a strategic brief stub for investors, partners, and the product team — they can fill
154
- it in now or return to it later. Suggest running `/pi-plan` to define project goals
155
- and epics.
@@ -1,7 +0,0 @@
1
- {
2
- "threshold_version": 2,
3
- "inline_max_files": 3,
4
- "inline_max_lines": 75,
5
- "story_max_files": 5,
6
- "bundle_lock_ttl_minutes": 30
7
- }
@@ -1,38 +0,0 @@
1
- # Strategy
2
-
3
- <!-- This document is intended for investors, strategic partners, and senior stakeholders.
4
- Write in clear, confident language that conveys conviction and focus.
5
- Avoid jargon. Prioritise substance over length. -->
6
-
7
- ## Vision
8
-
9
- <!-- Describe the long-term direction of this project over a 3–5 year horizon.
10
- What change do you want to see in the world, and what role does this project play in bringing it about?
11
- A strong vision statement is specific, ambitious, and grounded — it should be possible to hold yourself accountable to it. -->
12
-
13
- ## Value Proposition
14
-
15
- <!-- Articulate what makes this project uniquely valuable and to whom.
16
- Answer: Why does this exist? Why now? Why this team?
17
- Focus on the distinct advantage or insight that underpins the project — not features, but the underlying value delivered. -->
18
-
19
- ## Scope
20
-
21
- ### In Scope
22
-
23
- <!-- List the capabilities, domains, or problem spaces this project actively addresses.
24
- Be specific enough that a new stakeholder can quickly understand the boundaries of the work.
25
- Use bullet points for readability. -->
26
-
27
- ### Out of Scope
28
-
29
- <!-- List what this project explicitly does not cover.
30
- Revenue model, pricing strategy, and competitive analysis are intentionally excluded from this document —
31
- they belong in separate artefacts and are out of scope here.
32
- Use this section to prevent scope creep and set clear expectations with stakeholders. -->
33
-
34
- ## Target Audience
35
-
36
- <!-- Describe who this project is built for.
37
- Include both the end users (who experiences the product) and the stakeholders (who evaluates or funds it).
38
- Be specific: a well-defined audience sharpens every other section of this document. -->
@@ -1,30 +0,0 @@
1
- {
2
- "statuses": ["Pending", "In Progress", "Passed", "Passed with remarks", "Failed", "Rejected", "Blocked"],
3
- "rapport_types": ["conflict", "implementation_blocker", "security_concern", "test_failure", "analysis"],
4
- "paths": {
5
- "board": "project/board",
6
- "epics": "project/board/epics",
7
- "stories": "project/board/stories",
8
- "tasks": "project/board/tasks",
9
- "rapports_problems": "project/rapports/problems",
10
- "rapports_analysis": "project/rapports/analysis",
11
- "queue": "project/queue",
12
- "scrum_triggers": "project/queue/scrum_triggers.jsonl",
13
- "developer_triggers": "project/queue/developer_triggers.jsonl",
14
- "tester_triggers": "project/queue/tester_triggers.jsonl",
15
- "session_handoff": "project/queue/handoffs/",
16
- "logs": "project/logs",
17
- "data": "project/data",
18
- "configs": "project/configs",
19
- "documentation": "project/documentation",
20
- "documentation_plans": "project/documentation/plans",
21
- "documentation_summaries": "project/documentation/summaries"
22
- },
23
- "agents": ["developer", "tester", "scrum-master"],
24
- "pipeline": [
25
- {"step": 1, "agent": "scrum-master", "phase": "planning", "on_complete": "write planning_complete handoff → developer_triggers.jsonl"},
26
- {"step": 2, "agent": "developer", "phase": "implementation", "on_complete": "write implementation_complete handoff → tester_triggers.jsonl"},
27
- {"step": 3, "agent": "tester", "phase": "verification", "on_complete": "write test status handoff → scrum_triggers.jsonl (+ developer_triggers.jsonl if failed)"},
28
- {"step": 4, "agent": "scrum-master", "phase": "rollup_review", "on_complete": "update board statuses, close epic/story if all done"}
29
- ]
30
- }
@@ -1,176 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # apply-project-visibility.sh — apply the `project_files_visibility` mode to a project.
4
- #
5
- # Usage:
6
- # apply-project-visibility.sh <mode> [project_root]
7
- # apply-project-visibility.sh --check-only <mode>
8
- #
9
- # Modes:
10
- # visible Working files stay where they are. No-op on disk beyond the config write.
11
- # ignored Working files are added to the project's .gitignore — present on disk,
12
- # never committed.
13
- #
14
- # NOTE: A third mode, `hidden` (dot-prefixing project/ -> .project/), was
15
- # implemented and then withdrawn before release. Testing found it functionally
16
- # broken: scripts/board_resolver.sh hardcodes project/configs/workflow.json
17
- # and never locates the rewritten path, and hooks/on_session_end.sh
18
- # unconditionally recreates a shadow project/ tree on every session end,
19
- # splitting runtime state across two trees. See
20
- # project/rapports/problems/E31_S05_T01-hidden-mode-path-resolution-gaps.md
21
- # for the full findings. Re-introducing `hidden` requires fixing both of
22
- # those hardcoded paths first — tracked as a follow-up /todo item.
23
- #
24
- # Exit codes:
25
- # 0 Success
26
- # 1 Bad usage or missing prerequisite
27
- # 2 Invalid mode (outside the two-value enum)
28
- # 3 Filesystem apply failure
29
- # 4 jenga.config.json write failure
30
-
31
- # Do NOT use set -e globally — each step handles its own errors.
32
- set -uo pipefail
33
-
34
- info() { echo "[visibility] $*"; }
35
- warn() { echo "[visibility] WARNING: $*"; }
36
- err() { echo "[visibility] ERROR: $*" >&2; }
37
-
38
- usage() {
39
- echo "Usage: $(basename "$0") <visible|ignored> [project_root]" >&2
40
- echo " $(basename "$0") --check-only <visible|ignored>" >&2
41
- exit 1
42
- }
43
-
44
- # Every Jenga AI working file named in E31_S05 — the scrum board, todo.md,
45
- # queue/, rapports/ and logs/ — nests under this single root, so one entry
46
- # covers them all. `ignored` consumes this list.
47
- JENGA_WORKING_PATHS=("project")
48
-
49
- VALID_MODES="visible ignored"
50
-
51
- validate_mode() {
52
- local mode="$1"
53
- for valid in $VALID_MODES; do
54
- [ "$mode" = "$valid" ] && return 0
55
- done
56
- err "Invalid project_files_visibility value: '${mode}'"
57
- err "Allowed values are: ${VALID_MODES// /, }"
58
- exit 2
59
- }
60
-
61
- # ---------------------------------------------------------------------------
62
- # Argument parsing
63
- # ---------------------------------------------------------------------------
64
-
65
- CHECK_ONLY=0
66
- if [ "${1:-}" = "--check-only" ]; then
67
- CHECK_ONLY=1
68
- shift
69
- fi
70
-
71
- MODE="${1:-}"
72
- [ -n "$MODE" ] || usage
73
-
74
- validate_mode "$MODE"
75
-
76
- if [ "$CHECK_ONLY" -eq 1 ]; then
77
- info "Mode '$MODE' is valid."
78
- exit 0
79
- fi
80
-
81
- PROJECT_ROOT="${2:-$PWD}"
82
- if [ ! -d "$PROJECT_ROOT" ]; then
83
- err "Project root does not exist: $PROJECT_ROOT"
84
- exit 1
85
- fi
86
- cd "$PROJECT_ROOT" || { err "Cannot enter project root: $PROJECT_ROOT"; exit 1; }
87
-
88
- if ! command -v jq >/dev/null 2>&1; then
89
- err "jq is required to write jenga.config.json but was not found on PATH."
90
- exit 1
91
- fi
92
-
93
- # ---------------------------------------------------------------------------
94
- # ignored — append to .gitignore, without ever duplicating an entry
95
- # ---------------------------------------------------------------------------
96
-
97
- gitignore_append() {
98
- local entry="$1"
99
- local gitignore=".gitignore"
100
-
101
- if [ -f "$gitignore" ] && grep -qxF -- "$entry" "$gitignore"; then
102
- info "'$entry' already present in .gitignore — skipping."
103
- return 0
104
- fi
105
-
106
- # Don't glue our entry onto a final line that lacks a newline.
107
- if [ -s "$gitignore" ] && [ -n "$(tail -c 1 "$gitignore")" ]; then
108
- printf '\n' >> "$gitignore"
109
- fi
110
-
111
- if ! printf '%s\n' "$entry" >> "$gitignore"; then
112
- err "Failed to append '$entry' to .gitignore"
113
- exit 3
114
- fi
115
- info "Added '$entry' to .gitignore"
116
- }
117
-
118
- # ---------------------------------------------------------------------------
119
- # jenga.config.json — merge the field in, written atomically (temp + mv)
120
- # ---------------------------------------------------------------------------
121
-
122
- write_visibility_config() {
123
- local mode="$1"
124
- local config="jenga.config.json"
125
- local tmp="${config}.tmp"
126
- local existing='{}'
127
-
128
- # /init normally runs before any /distribute, so the file usually does not
129
- # exist yet. Merge rather than overwrite so other fields survive.
130
- if [ -f "$config" ]; then
131
- if ! jq empty "$config" 2>/dev/null; then
132
- err "$config exists but contains malformed JSON — refusing to overwrite it."
133
- exit 4
134
- fi
135
- existing="$(cat "$config")"
136
- fi
137
-
138
- local content
139
- content="$(jq --arg v "$mode" '.project_files_visibility = $v' <<< "$existing")"
140
- if [ -z "$content" ]; then
141
- err "Failed to construct $config content."
142
- exit 4
143
- fi
144
-
145
- if ! printf '%s\n' "$content" > "$tmp"; then
146
- err "Failed to write temporary config file: $tmp"
147
- exit 4
148
- fi
149
-
150
- if ! mv "$tmp" "$config"; then
151
- err "Failed to atomically move $tmp to $config"
152
- rm -f "$tmp"
153
- exit 4
154
- fi
155
-
156
- info "Wrote project_files_visibility = \"$mode\" to $config"
157
- }
158
-
159
- # ---------------------------------------------------------------------------
160
- # Apply
161
- # ---------------------------------------------------------------------------
162
-
163
- case "$MODE" in
164
- visible)
165
- info "Mode 'visible' — working files stay in place; nothing to change on disk."
166
- ;;
167
- ignored)
168
- for path in "${JENGA_WORKING_PATHS[@]}"; do
169
- gitignore_append "${path}/"
170
- done
171
- ;;
172
- esac
173
-
174
- write_visibility_config "$MODE"
175
-
176
- info "Applied project_files_visibility '$MODE' to $PROJECT_ROOT"