@jenga-ai/agent 3.6.0 → 4.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 (86) hide show
  1. package/README.md +32 -1
  2. package/lib/generate-skill-allow-list.js +42 -5
  3. package/lib/skill-allow-list.json +1 -1
  4. package/package.json +1 -2
  5. package/project/app/api/lib/resolve-project-root.js +1 -1
  6. package/project/app/api/scripts/capture-snapshot.js +12 -7
  7. package/project/app/package.json +4 -0
  8. package/project/app/ui/dist/assets/index-BADc5mmH.css +1 -0
  9. package/project/app/ui/dist/assets/index-DX2pfTAW.js +104 -0
  10. package/project/app/ui/dist/index.html +2 -2
  11. package/scripts/acquire-concurrency-slot.sh +34 -4
  12. package/scripts/apply-j-prefix.sh +1 -1
  13. package/scripts/delete-bare-skill-dirs.sh +1 -2
  14. package/scripts/idea_manager.sh +16 -1
  15. package/scripts/release-concurrency-slot.sh +34 -4
  16. package/scripts/render-ranked-list.sh +270 -0
  17. package/scripts/repoint-dead-bare-path-prose.py +81 -0
  18. package/scripts/rewrite-stale-skill-preambles.py +188 -0
  19. package/scripts/strip-polyfill-frontmatter.py +166 -0
  20. package/scripts/todo_manager.sh +16 -1
  21. package/scripts/validate-typed-object.sh +750 -0
  22. package/scripts/verify-postinstall-reconcile.sh +33 -7
  23. package/skills/index/scripts/board_index.py +29 -1
  24. package/skills/j-brainstorm/SKILL.md +3 -4
  25. package/skills/j-btw/SKILL.md +3 -4
  26. package/skills/j-clearify/SKILL.md +3 -4
  27. package/skills/j-close-story/SKILL.md +11 -12
  28. package/skills/j-close-story/scripts/check-story-closeable.sh +11 -4
  29. package/skills/j-commit/SKILL.md +3 -4
  30. package/skills/j-continue/SKILL.md +5 -6
  31. package/skills/j-deep-dive/SKILL.md +3 -4
  32. package/skills/j-distribute/SKILL.md +3 -4
  33. package/skills/j-do/SKILL.md +13 -15
  34. package/skills/j-doc/SKILL.md +3 -4
  35. package/skills/j-doc/scripts/resolve_last_update.py +27 -1
  36. package/skills/j-doc-sync/SKILL.md +3 -4
  37. package/skills/j-dooo/SKILL.md +6 -15
  38. package/skills/j-error/SKILL.md +3 -4
  39. package/skills/j-evaluate/SKILL.md +3 -4
  40. package/skills/j-examplify/SKILL.md +3 -4
  41. package/skills/j-help/SKILL.md +3 -4
  42. package/skills/j-idea/SKILL.md +3 -4
  43. package/skills/j-improve/SKILL.md +3 -4
  44. package/skills/j-init/SKILL.md +20 -11
  45. package/skills/j-init/scripts/apply-scaffold-visibility.sh +8 -6
  46. package/skills/j-jbp/SKILL.md +3 -4
  47. package/skills/j-lgtm/SKILL.md +3 -4
  48. package/skills/j-pi-plan/SKILL.md +3 -4
  49. package/skills/j-proceed/SKILL.md +3 -4
  50. package/skills/j-publish/SKILL.md +3 -4
  51. package/skills/j-publish/scripts/run_gates.sh +1 -1
  52. package/skills/j-reconcile/SKILL.md +38 -5
  53. package/skills/j-reconcile/assets/report_format.md +11 -0
  54. package/skills/j-reconcile/scripts/detect-unlinked-code.sh +2 -2
  55. package/skills/j-reconcile-origin/SKILL.md +3 -4
  56. package/skills/j-redo/SKILL.md +3 -4
  57. package/skills/j-skillify/SKILL.md +3 -4
  58. package/skills/j-spinoff/SKILL.md +3 -4
  59. package/skills/j-status/SKILL.md +4 -5
  60. package/skills/j-todo/SKILL.md +42 -5
  61. package/skills/j-todo/scripts/add_trivial_task.sh +12 -1
  62. package/skills/j-todo/scripts/argument-is-not-ranked-list.sh +92 -0
  63. package/skills/j-todo/scripts/argument-is-ranked-list.sh +78 -0
  64. package/skills/j-uncharted/SKILL.md +251 -12
  65. package/skills/j-uncharted/scripts/detect-dependencies.sh +79 -21
  66. package/skills/j-uncharted/scripts/diff-since-baseline.sh +600 -0
  67. package/skills/j-uncharted/scripts/find-scan-baseline.sh +545 -0
  68. package/skills/j-uncharted/scripts/run-engine.sh +36 -2
  69. package/skills/j-uncharted/scripts/write-scan-record.sh +361 -0
  70. package/skills/j-wtf/SKILL.md +3 -4
  71. package/skills/jenga/SKILL.md +106 -10
  72. package/skills/jenga/playbooks/schema.json +4 -4
  73. package/skills/jenga/scripts/enrich-nl-prompt.sh +225 -0
  74. package/skills/jenga/scripts/load-nl-catalog.js +6 -3
  75. package/skills/jenga/scripts/load-playbooks.sh +289 -4
  76. package/skills/jenga/scripts/match-playbook.sh +6 -5
  77. package/skills/jenga/scripts/run-playbook-step.sh +270 -3
  78. package/templates/permission-levels/level-1-locked.json +1 -1
  79. package/templates/permission-levels/level-2-guarded.json +1 -1
  80. package/templates/permission-levels/level-3-standard.json +1 -1
  81. package/templates/permission-levels/level-4-elevated.json +1 -1
  82. package/templates/permission-levels/level-5-unrestricted.json +1 -1
  83. package/templates/playbook-types.json +6 -0
  84. package/project/app/ui/dist/assets/index-BVR_7Owg.css +0 -1
  85. package/project/app/ui/dist/assets/index-CtU2xLQm.js +0 -104
  86. package/scripts/audit-twin-divergence.sh +0 -693
@@ -1,19 +1,18 @@
1
1
  ---
2
2
  name: j.reconcile
3
- description: Polyfill alias of the reconcile skill under a collision-safe directory name. Identical behavior to /reconcile — Reconcile the scrum board with actual implementation state. Cross-checks every task's board status against git history and worktrees, merges orphaned worktree branches, demotes unimplemented "Done" items, promotes secretly-implemented items, flags code with no board provenance and offers /uncharted segment for it, and cleans stale entries from todo.md. Use when the board feels out of sync, after a big merge session, when tasks were completed outside the normal workflow, or when todo.md has grown stale. Trigger on phrases like "sync the board", "clean up the board", "reconcile", "board is out of date", "todo is stale", or "check what's really done". Use when the bare /reconcile form is shadowed by another tool's own built-in command of the same name.
3
+ description: Reconcile the scrum board with actual implementation state. Cross-checks every task's board status against git history and worktrees, merges orphaned worktree branches, demotes unimplemented "Done" items, promotes secretly-implemented items, flags code with no board provenance and offers /uncharted segment for it, and cleans stale entries from todo.md. Use when the board feels out of sync, after a big merge session, when tasks were completed outside the normal workflow, or when todo.md has grown stale. Trigger on phrases like "sync the board", "clean up the board", "reconcile", "board is out of date", "todo is stale", or "check what's really done".
4
4
  metadata:
5
5
  prefered_agent: scrum-master
6
6
  output_types: id_list
7
7
  keywords:
8
8
  - j-reconcile
9
- - polyfill
10
9
  ---
11
10
 
12
11
  # Reconcile — Board ↔ Code Synchronisation
13
12
 
14
- This skill is a literal-directory-name duplicate of `skills/reconcile/`. It exists so that `/j-reconcile` (and `j.j-reconcile`) give a guaranteed-unshadowed way to reach the same flow as `/reconcile`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/reconcile` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
13
+ `skills/j-reconcile/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-reconcile/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
15
14
 
16
- This file is generated/synced by `scripts/generate-j-alias.sh reconcile` from `skills/reconcile/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
15
+ > ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/reconcile/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
17
16
 
18
17
  Walks the full board (epics → stories → tasks), verifies each item's status against what actually exists in git, and fixes any drift. Also cleans `project/todo.md` of entries that are already done. Then runs the same check in reverse — code that exists with no board item and no EST-tagged commit behind it — and offers `/uncharted segment` for what it finds.
19
18
 
@@ -136,7 +135,41 @@ in-scope tasks when scoped) whose status is **not** a completed status (Pending,
136
135
  2. **Check documentation artefacts** as in phase 2.
137
136
  3. **Spot-check acceptance criteria** against the codebase.
138
137
 
139
- If implementation **is confirmed**:
138
+ Before treating a matching commit as grounds to promote, run two more checks. These exist because
139
+ a commit referencing a task ID is evidence the code was *touched*, not evidence it is *finished* —
140
+ a separate, still-running `/do` pipeline for this exact task may have a real fix sitting unmerged
141
+ in a worktree while an earlier, incomplete commit already landed on the branch this `/reconcile`
142
+ pass is reading. This is the exact race documented in
143
+ `project/rapports/problems/E40_S01_T05-premature-main-reconcile-vs-worktree-fix.md` — a `/reconcile`
144
+ pass promoted a task to `Passed`/`Done` from a matching commit alone while a fallback developer/tester
145
+ pipeline for that same task still had its bugfix unmerged on a worktree branch.
146
+
147
+ 4. **Check for an active concurrency-slot holder** — glob `project/queue/concurrency-slots-*.json`
148
+ (there can be several; one per orchestrating session, per `skills/j-do/SKILL.md`'s
149
+ `### 4.4. Developer Concurrency Slot Enforcement`). For each file found, check both
150
+ `.developer.holders` and `.tester.holders` for a key matching this task's id (`E##_S##_T##`) —
151
+ or, if this task belongs to a story-bundle dispatch, the containing story's id (`E##_S##`),
152
+ since a bundle acquires one shared slot keyed to the story id rather than one per task (`### 1.5`
153
+ step 3 of that skill). A matching key means a developer or tester subagent for this exact item is
154
+ (or very recently was) live in another session.
155
+ 5. **Check for an unmerged worktree or branch** — run `git worktree list` and `git branch --all`,
156
+ and look for an entry matching this task's `<E##_S##_T##-short-slug>` naming convention
157
+ (`skills/j-do/SKILL.md`'s worktree-naming convention, e.g. its Light Execution Path and Fallback
158
+ to Full Task-Scope Pipeline sections) that has not yet been merged into the branch this
159
+ `/reconcile` run is executing against. A match means real work for this task exists on a branch
160
+ this reconcile pass hasn't accounted for yet.
161
+
162
+ If **either** check 4 or 5 matches, skip promotion for this task:
163
+ - Leave the task's status exactly as it is now — do not touch `date_started`, `date_completed`, or
164
+ its `project/todo.md` entry.
165
+ - Do **not** merge the branch/worktree found in check 5 yourself — that is a live pipeline's own
166
+ work-in-progress, not an orphaned branch like phase 2's merge case.
167
+ - Report it in the reconcile report as **"likely still in-flight — skipped"** (see
168
+ `assets/report_format.md`'s "⏳ IN-FLIGHT — SKIPPED" section) — not silently promoted, and not
169
+ silently left unmentioned.
170
+ - Continue to the next task in Phase 3 — this is a per-task skip, not a phase abort.
171
+
172
+ If implementation **is confirmed** and **neither** check 4 nor 5 matched:
140
173
  - Update the task's status to **Passed** in its board file.
141
174
  - Set `date_completed` to today (ISO 8601).
142
175
  - If the task is listed in `project/todo.md`, **comment it out** by wrapping the line:
@@ -18,6 +18,10 @@ Scope: <resolved scope — see forms below>
18
18
  ⬆️ PROMOTED (were incomplete → now Passed)
19
19
  🔧 E##_S##_T## · <Task Title> — commits found, acceptance criteria met
20
20
 
21
+ ⏳ IN-FLIGHT — SKIPPED (implementation confirmed by commit, but not promoted — active work appears ongoing)
22
+ 🔧 E##_S##_T## · <Task Title> — concurrency-slot holder found in <concurrency-slots-file>
23
+ 🔧 E##_S##_T## · <Task Title> — unmerged branch <branch-name>
24
+
21
25
  🔄 ROLL-UP CHANGES
22
26
  📖 E##_S## · <Story Title> — <old status> → <new status>
23
27
  📦 E## · <Epic Title> — <old status> → <new status>
@@ -51,6 +55,13 @@ Scope: <resolved scope — see forms below>
51
55
  own epics/stories/tasks only — not the whole board's.
52
56
  - Omit any section that has zero items (e.g. if nothing was demoted, skip the DEMOTED block entirely).
53
57
  - The MERGED section should include the branch name that was merged.
58
+ - The IN-FLIGHT — SKIPPED section is distinct from both PROMOTED and the ordinary "implementation
59
+ not confirmed, no action" case (which is never reported at all): it means Phase 3 found a
60
+ matching commit (implementation confirmed) but withheld promotion because an active
61
+ concurrency-slot holder or an unmerged matching worktree/branch was also found — see
62
+ `/reconcile`'s Phase 3. Name the specific reason found (the concurrency-slots file, or the
63
+ branch/worktree name) so the report is checkable, not just asserted. Omit this section entirely
64
+ when no task was skipped for this reason.
54
65
  - The TODO CLEANUP section is always shown if `project/todo.md` existed at the start, even if zero changes were made (in that case show all counts as 0).
55
66
  - If `project/todo.md` did not exist, omit the TODO CLEANUP section.
56
67
  - The DOD GAPS section is omitted if no completed stories have unchecked DoD checkboxes.
@@ -143,7 +143,7 @@
143
143
  # --board-dir <dir> Board directory to consult.
144
144
  # Default: <repo-root>/project/board
145
145
  # --resolver <path> Path to resolve-segment-target.sh.
146
- # Default: ../../uncharted/scripts/resolve-segment-target.sh
146
+ # Default: ../../j-uncharted/scripts/resolve-segment-target.sh
147
147
  # --exclude <glob> Additional exclusion, matched against the repo-relative
148
148
  # path with shell-glob semantics. Repeatable.
149
149
  # --limit N Cap on files listed per group. Default 10. 0 = unlimited.
@@ -292,7 +292,7 @@ REPO_ROOT=$(cd -- "$REPO_ROOT" && pwd -P)
292
292
  [ -n "$BOARD_DIR" ] || BOARD_DIR="$REPO_ROOT/project/board"
293
293
 
294
294
  # --- the borrowed linkage check -------------------------------------------------------------
295
- [ -n "$RESOLVER" ] || RESOLVER="$SCRIPT_DIR/../../uncharted/scripts/resolve-segment-target.sh"
295
+ [ -n "$RESOLVER" ] || RESOLVER="$SCRIPT_DIR/../../j-uncharted/scripts/resolve-segment-target.sh"
296
296
  [ -f "$RESOLVER" ] || die 4 "board-linkage checker not found: $RESOLVER
297
297
  This script deliberately has no fallback implementation -- see the header. Restore
298
298
  skills/j-uncharted/scripts/resolve-segment-target.sh or pass --resolver <path>."
@@ -1,13 +1,12 @@
1
1
  ---
2
2
  name: j.reconcile-origin
3
- description: Polyfill alias of the reconcile-origin skill under a collision-safe directory name. Identical behavior to /reconcile-origin — Sync the current (or specified) branch with origin by rebasing local commits on top of the latest upstream state. Use when the bare /reconcile-origin form is shadowed by another tool's own built-in command of the same name.
3
+ description: Sync the current (or specified) branch with origin by rebasing local commits on top of the latest upstream state.
4
4
  keywords:
5
5
  - "sync branch"
6
6
  - "rebase origin"
7
7
  - "reconcile origin"
8
8
  - "pull rebase"
9
9
  - j-reconcile-origin
10
- - polyfill
11
10
  examples:
12
11
  - "sync my branch with origin"
13
12
  - "rebase local commits on top of origin"
@@ -17,9 +16,9 @@ examples:
17
16
 
18
17
  # Reconcile Origin
19
18
 
20
- This skill is a literal-directory-name duplicate of `skills/reconcile-origin/`. It exists so that `/j-reconcile-origin` (and `j.j-reconcile-origin`) give a guaranteed-unshadowed way to reach the same flow as `/reconcile-origin`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/reconcile-origin` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
19
+ `skills/j-reconcile-origin/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-reconcile-origin/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
21
20
 
22
- This file is generated/synced by `scripts/generate-j-alias.sh reconcile-origin` from `skills/reconcile-origin/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
21
+ > ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/reconcile-origin/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
23
22
 
24
23
  Use this skill to rebase local work on top of the latest `origin/<branch>` state without re-implementing git logic inline.
25
24
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: j.redo
3
- description: Polyfill alias of the redo skill under a collision-safe directory name. Identical behavior to /redo — Redo parts or entire previous implementations identified by a commit SHA or an Epic/Story number (e.g. E01, E02_S03). Expects an identifier and a description of what to redo and why. Use when the user wants to revisit, rework, or rewrite previously completed work, including updating all affected documentation. Use when the bare /redo form is shadowed by another tool's own built-in command of the same name.
3
+ description: Redo parts or entire previous implementations identified by a commit SHA or an Epic/Story number (e.g. E01, E02_S03). Expects an identifier and a description of what to redo and why. Use when the user wants to revisit, rework, or rewrite previously completed work, including updating all affected documentation.
4
4
  keywords:
5
5
  - redo
6
6
  - rework
@@ -8,7 +8,6 @@ keywords:
8
8
  - revisit
9
9
  - redo task
10
10
  - j-redo
11
- - polyfill
12
11
  examples:
13
12
  - "redo the login implementation"
14
13
  - "rewrite story E02_S01"
@@ -19,9 +18,9 @@ metadata:
19
18
 
20
19
  # Redo — Rework a Previous Implementation
21
20
 
22
- This skill is a literal-directory-name duplicate of `skills/redo/`. It exists so that `/j-redo` (and `j.j-redo`) give a guaranteed-unshadowed way to reach the same flow as `/redo`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/redo` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
21
+ `skills/j-redo/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-redo/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
23
22
 
24
- This file is generated/synced by `scripts/generate-j-alias.sh redo` from `skills/redo/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
23
+ > ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/redo/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
25
24
 
26
25
  ## Input Format
27
26
 
@@ -1,16 +1,15 @@
1
1
  ---
2
2
  name: j.skillify
3
- description: Polyfill alias of the skillify skill under a collision-safe directory name. Identical behavior to /skillify — Refactor one or more existing skills into a cleaner, more maintainable structure — extracting hardcoded content into asset files, offloading deterministic steps into scripts, and reorganizing the skill body to reflect the leaner result. Use this whenever the user wants to clean up, improve, or restructure an existing skill, mentions that a skill has hardcoded content that could be templated, or asks to "skillify", "refactor", or "tidy up" a skill. Trigger even if the user just pastes a skill and says something like "can we make this better?". Use when the bare /skillify form is shadowed by another tool's own built-in command of the same name.
3
+ description: Refactor one or more existing skills into a cleaner, more maintainable structure — extracting hardcoded content into asset files, offloading deterministic steps into scripts, and reorganizing the skill body to reflect the leaner result. Use this whenever the user wants to clean up, improve, or restructure an existing skill, mentions that a skill has hardcoded content that could be templated, or asks to "skillify", "refactor", or "tidy up" a skill. Trigger even if the user just pastes a skill and says something like "can we make this better?".
4
4
  keywords:
5
5
  - j-skillify
6
- - polyfill
7
6
  ---
8
7
 
9
8
  # Skillify — Refactor a Skill into a Cleaner Structure
10
9
 
11
- This skill is a literal-directory-name duplicate of `skills/skillify/`. It exists so that `/j-skillify` (and `j.j-skillify`) give a guaranteed-unshadowed way to reach the same flow as `/skillify`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/skillify` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
10
+ `skills/j-skillify/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-skillify/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
12
11
 
13
- This file is generated/synced by `scripts/generate-j-alias.sh skillify` from `skills/skillify/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
12
+ > ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/skillify/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
14
13
 
15
14
  ## What this skill does
16
15
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: j.spinoff
3
- description: Polyfill alias of the spinoff skill under a collision-safe directory name. Identical behavior to /spinoff — Capture a diverging topic mid-conversation. Collects context and a mandatory origin, optionally runs /brainstorm for prerequisites, saves an /idea entry, and returns focus to the primary thread. Use when the bare /spinoff form is shadowed by another tool's own built-in command of the same name.
3
+ description: Capture a diverging topic mid-conversation. Collects context and a mandatory origin, optionally runs /brainstorm for prerequisites, saves an /idea entry, and returns focus to the primary thread.
4
4
  keywords:
5
5
  - spinoff
6
6
  - diverge
@@ -8,7 +8,6 @@ keywords:
8
8
  - capture topic
9
9
  - new thread
10
10
  - j-spinoff
11
- - polyfill
12
11
  examples:
13
12
  - "let's spinoff this idea"
14
13
  - "capture this as a separate thread"
@@ -19,9 +18,9 @@ metadata:
19
18
 
20
19
  # Spinoff — Capture a Diverging Topic
21
20
 
22
- This skill is a literal-directory-name duplicate of `skills/spinoff/`. It exists so that `/j-spinoff` (and `j.j-spinoff`) give a guaranteed-unshadowed way to reach the same flow as `/spinoff`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/spinoff` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
21
+ `skills/j-spinoff/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-spinoff/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
23
22
 
24
- This file is generated/synced by `scripts/generate-j-alias.sh spinoff` from `skills/spinoff/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
23
+ > ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/spinoff/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
25
24
 
26
25
  ## Instructions
27
26
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: j.status
3
- description: Polyfill alias of the status skill under a collision-safe directory name. Identical behavior to /status — Print a human-readable summary of the entire scrum board — all epics, stories, and tasks with their statuses — plus any open rapports and unprocessed queue triggers. Use when you want a quick overview of project state without reading raw files. Use when the bare /status form is shadowed by another tool's own built-in command of the same name.
3
+ description: Print a human-readable summary of the entire scrum board — all epics, stories, and tasks with their statuses — plus any open rapports and unprocessed queue triggers. Use when you want a quick overview of project state without reading raw files.
4
4
  output_types: text
5
5
  keywords:
6
6
  - status
@@ -9,7 +9,6 @@ keywords:
9
9
  - project state
10
10
  - what's done
11
11
  - j-status
12
- - polyfill
13
12
  examples:
14
13
  - "show me the project status"
15
14
  - "what's the state of the board?"
@@ -18,9 +17,9 @@ examples:
18
17
 
19
18
  # Status — Board Overview
20
19
 
21
- This skill is a literal-directory-name duplicate of `skills/status/`. It exists so that `/j-status` (and `j.j-status`) give a guaranteed-unshadowed way to reach the same flow as `/status`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/status` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
20
+ `skills/j-status/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-status/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
22
21
 
23
- This file is generated/synced by `scripts/generate-j-alias.sh status` from `skills/status/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
22
+ > ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/status/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
24
23
 
25
24
  ## Instructions
26
25
 
@@ -40,7 +39,7 @@ This file is generated/synced by `scripts/generate-j-alias.sh status` from `skil
40
39
  `scripts/` directory of its own comparable to `/self-sync`'s, so invoke the shared pipeline
41
40
  directly rather than adding a third skill-local wrapper script:
42
41
  ```
43
- bash scripts/mark-deployed.sh
42
+ bash "$([ -f scripts/mark-deployed.sh ] && echo scripts/mark-deployed.sh || echo node_modules/@jenga-ai/agent/scripts/mark-deployed.sh)"
44
43
  ```
45
44
  This defaults to invoking its own sibling `scripts/compute-deploy-reconcile.sh`, which
46
45
  discovers any not-yet-reconciled `vX.Y.Z-stage`/`vX.Y.Z` tags on the public `jenga-npm` repo
@@ -1,7 +1,11 @@
1
1
  ---
2
2
  name: j.todo
3
- description: Polyfill alias of the todo skill under a collision-safe directory name. Identical behavior to /todo — Add missions to the project todo list (project/todo.md), optionally linking them to epics and stories. Loops until the user is done, then optionally executes the list. Use when the bare /todo form is shadowed by another tool's own built-in command of the same name.
4
- output_types: id_list
3
+ description: Add missions to the project todo list (project/todo.md), optionally linking them to epics and stories. Loops until the user is done, then optionally executes the list.
4
+ output_types:
5
+ - when: argument-is-ranked-list
6
+ type: ranked_list
7
+ - when: argument-is-not-ranked-list
8
+ type: id_list
5
9
  input_types: id_list
6
10
  keywords:
7
11
  - todo
@@ -10,7 +14,6 @@ keywords:
10
14
  - backlog
11
15
  - add to list
12
16
  - j-todo
13
- - polyfill
14
17
  examples:
15
18
  - "add this to the todo list"
16
19
  - "queue this as a task"
@@ -21,9 +24,9 @@ metadata:
21
24
 
22
25
  # Todo — Add Missions to the Todo List
23
26
 
24
- This skill is a literal-directory-name duplicate of `skills/todo/`. It exists so that `/j-todo` (and `j.j-todo`) give a guaranteed-unshadowed way to reach the same flow as `/todo`, even if a host tool's own built-in command of the same name would otherwise shadow or override the bare `/todo` alias (Claude Code's native skill resolution is a literal-string, directory-name-based match — see `docs/skill-authoring.md`'s "Invocation Convention").
27
+ `skills/j-todo/` is the **canonical, hand-edited** directory for this skill, per CLAUDE.md's "The Canonical Naming Contract" (the `E50` reopening of 2026-09-09, which promoted `skills/j-todo/` from generated twin to sole canonical form). The `j-` prefix is there for collision safety — a real directory under a distinct name, so a host tool shipping its own same-named built-in command cannot shadow it (Claude Code's native skill resolution is a literal-string, directory-name-based match; see `docs/skill-authoring.md`'s "Invocation Convention").
25
28
 
26
- This file is generated/synced by `scripts/generate-j-alias.sh todo` from `skills/todo/SKILL.md` — do not hand-edit it; re-run the generator instead to pick up source changes.
29
+ > ⚠️ **`scripts/generate-j-alias.sh` was retired by `E50_S14` and no longer exists — there is nothing to run.** This file was previously generated from a bare `skills/todo/SKILL.md` source; `E50_S15` deleted that directory. This file is now the sole canonical, hand-edited source for this skill — edit it directly.
27
30
 
28
31
  ## `--trivial` Flag
29
32
 
@@ -35,8 +38,42 @@ When `--trivial` is present, the mission is written as a **fully-formed task boa
35
38
 
36
39
  **Fallback on failure is out of scope here.** If a `--trivial`-forced inline run fails the smoke-harness or shows scope creep at dispatch time, `/do`'s own `--trivial` handling (a separate task, E32_S14_T02) is responsible for falling back to the full `task` pipeline — this skill only ever writes the initial forced-inline task.
37
40
 
41
+ ## `--ranked-list` Flag
42
+
43
+ **Syntax:** `/todo --ranked-list` — takes no other arguments.
44
+
45
+ **Non-interactive, one-shot, read-only.** `--ranked-list` is a distinct mode, not a modifier on a
46
+ normal `/todo` mission-add invocation. It calls the shared `scripts/render-ranked-list.sh` (built by
47
+ `E63_S01_T01`; see that script's own header comment for the full eligibility rule and its env-var
48
+ overrides — do not re-derive or restate the scan logic here) and prints its stdout **verbatim**, then
49
+ exits — this is exactly the same script and the same eligibility scan `/dooo`'s own step 2/3 already
50
+ uses (`skills/j-dooo/SKILL.md`), so `--ranked-list`'s output is byte-for-byte identical to `/dooo`'s
51
+ list for the same board/`todo.md` state. Do not append a trailing "Done" option or any interactive
52
+ prompt — that framing belongs to `/dooo`'s own UI layer on top of the script, not to the shared
53
+ script's output, and not to `--ranked-list` either.
54
+
55
+ **No mutation.** `--ranked-list` never writes `project/todo.md`, never writes a board file, and never
56
+ dispatches a task. It is a pure read/render, matching `scripts/render-ranked-list.sh`'s own
57
+ no-mutation contract.
58
+
59
+ **Takes precedence over mission text.** If the user somehow passes `--ranked-list` together with
60
+ mission text, treat `--ranked-list` as taking precedence and ignore the mission text — it has no
61
+ mission to attach to, so it cannot combine the way `--trivial` combines with an epic/story reference.
62
+
63
+ **Short-circuits the whole flow.** See step 0 below — when `--ranked-list` is passed, none of the
64
+ normal `/todo` steps 1-6 (the "where/what/goal" questions, mission classification, board writes, the
65
+ "add another" loop) are ever reached.
66
+
38
67
  ## Instructions
39
68
 
69
+ 0. **If `--ranked-list` was passed, handle it now and stop — do not proceed to step 1:**
70
+ ```
71
+ bash "$([ -f scripts/render-ranked-list.sh ] && echo scripts/render-ranked-list.sh || echo node_modules/@jenga-ai/agent/scripts/render-ranked-list.sh)"
72
+ ```
73
+ Print the script's stdout verbatim as the response (no added framing, no "Done" option, no
74
+ follow-up question) and end the skill invocation here. Steps 1-6 below do not apply to
75
+ `--ranked-list` at all.
76
+
40
77
  1. **Ensure `project/todo.md` exists** — If it doesn't exist, it will be auto-created by `todo_manager.sh` — no manual action needed.
41
78
 
42
79
  2. **Ask the user about the mission:**
@@ -28,7 +28,18 @@
28
28
 
29
29
  set -euo pipefail
30
30
 
31
- REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
31
+ # Locate the project root via git, not a fixed relative climb — this script
32
+ # is deployed both at its source location (skills/j-todo/scripts/) and
33
+ # mirrored to .claude/skills/j-todo/scripts/ / .agents/skills/j-todo/scripts/,
34
+ # and a fixed "three levels up" climb lands in the wrong place from a mirror.
35
+ # Same approach as skills/j-close-story/scripts/check-story-closeable.sh,
36
+ # check-privatized.sh:138, and compute-scope-divergence.sh:54.
37
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
38
+ REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || true)"
39
+ if [[ -z "$REPO_ROOT" ]]; then
40
+ echo "ERROR: could not locate project root (git rev-parse --show-toplevel failed from $SCRIPT_DIR)" >&2
41
+ exit 1
42
+ fi
32
43
  cd "$REPO_ROOT"
33
44
 
34
45
  TASKS_DIR="project/board/tasks"
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env bash
2
+ # ---------------------------------------------------------------------------
3
+ # skills/j-todo/scripts/argument-is-not-ranked-list.sh
4
+ #
5
+ # Classifier for the OTHER half of j-todo's conditional `output_types` declaration
6
+ # (E63_S01_T04, corrected). `output_types: id_list` was deliberately declared on j-todo by
7
+ # `E53_S11_T01` ("j-todo (none) -> id_list (emits board item ids)") -- /todo's normal
8
+ # mission-capture flow genuinely does produce a forwardable board-item id, and that claim is
9
+ # still true after E63_S01_T03 added --ranked-list. It must stay declared, not be silently
10
+ # dropped when the ranked_list branch is added alongside it.
11
+ #
12
+ # This script is the "when" for that id_list branch. It is the exact logical complement of
13
+ # `argument-is-ranked-list.sh` -- deliberately implemented as a thin delegate to that script
14
+ # rather than a second, independently-written check, so the two branches can never quietly
15
+ # drift apart on what "--ranked-list" means. There is exactly one place that decision is made
16
+ # (argument-is-ranked-list.sh); this script only inverts its verdict.
17
+ #
18
+ # Why not the built-in `argument_nonempty` predicate instead of a real script: `--ranked-list`
19
+ # is ALSO a non-empty argument, so `argument_nonempty -> id_list` would be a false claim for
20
+ # that one specific invocation shape (its actual output is ranked_list, never id_list). Using
21
+ # the built-in here would pass load-playbooks.sh's structural check trivially (no script to
22
+ # find), but it would misdescribe the one case this task exists to carve out -- exactly the
23
+ # honesty-over-breadth violation E53_S11 rejects. A dedicated classifier that excludes
24
+ # `--ranked-list` precisely is the honest choice.
25
+ #
26
+ # ---------------------------------------------------------------------------
27
+ # USAGE
28
+ # ---------------------------------------------------------------------------
29
+ # skills/j-todo/scripts/argument-is-not-ranked-list.sh "<raw /todo invocation argument>"
30
+ #
31
+ # ---------------------------------------------------------------------------
32
+ # OUTPUT CONTRACT
33
+ # ---------------------------------------------------------------------------
34
+ # stdout is always a single JSON object:
35
+ #
36
+ # {"classification": "normal"} -- exit 0 -- the argument is anything OTHER than exactly
37
+ # `--ranked-list` (empty, mission text, `--trivial ...`,
38
+ # etc.) -- /todo's normal mission-capture flow applies.
39
+ # {"classification": "ranked_list"} -- exit 1 -- the argument IS exactly `--ranked-list`; the
40
+ # complement branch (argument-is-ranked-list.sh) applies
41
+ # instead, not this one.
42
+ #
43
+ # ---------------------------------------------------------------------------
44
+ # EXIT CODES
45
+ # ---------------------------------------------------------------------------
46
+ # 0 "normal" classification (see above)
47
+ # 1 "ranked_list" classification (see above) -- a legitimate outcome, not an error
48
+ # 2 usage error (no argument given), or the delegate script is missing/unreadable, or the
49
+ # delegate exited with an exit code this script does not recognize
50
+ #
51
+ # ---------------------------------------------------------------------------
52
+
53
+ set -euo pipefail
54
+
55
+ if [ $# -lt 1 ]; then
56
+ echo 'Usage: argument-is-not-ranked-list.sh "<raw /todo invocation argument>"' >&2
57
+ exit 2
58
+ fi
59
+
60
+ RAW_INPUT="$1"
61
+
62
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
63
+ RANKED_LIST_CLASSIFIER="$SCRIPT_DIR/argument-is-ranked-list.sh"
64
+
65
+ if [ ! -f "$RANKED_LIST_CLASSIFIER" ]; then
66
+ echo "Error: argument-is-ranked-list.sh not found at $RANKED_LIST_CLASSIFIER" >&2
67
+ exit 2
68
+ fi
69
+
70
+ # Guard the capture explicitly so `set -e` doesn't abort this script on the delegate's own
71
+ # legitimate non-zero exit (1 == "normal" from the delegate's point of view).
72
+ set +e
73
+ bash "$RANKED_LIST_CLASSIFIER" "$RAW_INPUT" >/dev/null 2>&1
74
+ DELEGATE_EXIT=$?
75
+ set -e
76
+
77
+ case "$DELEGATE_EXIT" in
78
+ 0)
79
+ # Delegate says "ranked_list" -- the complement is false.
80
+ echo '{"classification": "ranked_list"}'
81
+ exit 1
82
+ ;;
83
+ 1)
84
+ # Delegate says "normal" -- the complement is true.
85
+ echo '{"classification": "normal"}'
86
+ exit 0
87
+ ;;
88
+ *)
89
+ echo "Error: argument-is-ranked-list.sh exited with unexpected status $DELEGATE_EXIT" >&2
90
+ exit 2
91
+ ;;
92
+ esac
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env bash
2
+ # ---------------------------------------------------------------------------
3
+ # skills/j-todo/scripts/argument-is-ranked-list.sh
4
+ #
5
+ # Classifier for `j-todo`'s conditional `output_types` declaration (E63_S01_T04). `/todo`'s normal
6
+ # behavior (adding a mission to the board) produces no forwardable output -- only the distinct
7
+ # `--ranked-list` invocation (E63_S01_T03) does, by printing `scripts/render-ranked-list.sh`'s
8
+ # `ranked_list`-typed output verbatim (see `skills/j-todo/SKILL.md`'s "--ranked-list Flag" section).
9
+ #
10
+ # Declaring `output_types: ranked_list` unconditionally would misdescribe every normal /todo
11
+ # invocation as a ranked_list producer, violating E53_S11's honesty-over-breadth policy. This script
12
+ # is the classifier `skills/j-todo/SKILL.md`'s `output_types` keys off of instead, per
13
+ # `docs/skill-authoring.md`'s conditional `{when, type}` form -- the same pattern `j.jenga` already
14
+ # uses for `detect-nl-intent.sh`.
15
+ #
16
+ # Neither built-in predicate (`argument_empty` / `argument_nonempty`) fits here: `--ranked-list` is a
17
+ # non-empty argument, but so is mission text and `--trivial ...` -- both of which still produce
18
+ # `/todo`'s normal (undeclared-type) output, not `ranked_list`. `argument_nonempty` alone cannot tell
19
+ # those apart, so this dedicated classifier exists to draw that one distinction.
20
+ #
21
+ # ---------------------------------------------------------------------------
22
+ # WHAT THIS SCRIPT IS FOR (read before assuming it gates runtime routing)
23
+ # ---------------------------------------------------------------------------
24
+ # `skills/jenga/scripts/load-playbooks.sh` only ever checks that a classifier-script `when` value
25
+ # resolves to an existing, executable file on disk under this skill's own `scripts/` directory -- it
26
+ # never runs this script to decide which `output_types` branch actually fires (see
27
+ # `docs/skill-authoring.md`'s "output_types" and "forward_from resolution" sections for the exact,
28
+ # narrow claim that load-time check does and does not make). This script exists so that structural
29
+ # check has a real file to find, and so the classification it names is genuinely correct if anything
30
+ # ever does execute it (e.g. a future runtime-verification path) -- not because anything wires its
31
+ # exit code into routing today. `skills/j-todo/SKILL.md`'s own step 0 short-circuit is what actually
32
+ # decides the `--ranked-list` branch at real invocation time; this script's job is narrower and
33
+ # purely descriptive.
34
+ #
35
+ # ---------------------------------------------------------------------------
36
+ # USAGE
37
+ # ---------------------------------------------------------------------------
38
+ # skills/j-todo/scripts/argument-is-ranked-list.sh "<raw /todo invocation argument>"
39
+ #
40
+ # ---------------------------------------------------------------------------
41
+ # OUTPUT CONTRACT
42
+ # ---------------------------------------------------------------------------
43
+ # stdout is always a single JSON object:
44
+ #
45
+ # {"classification": "ranked_list"} -- exit 0 -- the argument, trimmed, is exactly `--ranked-list`
46
+ # {"classification": "normal"} -- exit 1 -- anything else, including an empty argument,
47
+ # mission text, or `--trivial ...`
48
+ #
49
+ # ---------------------------------------------------------------------------
50
+ # EXIT CODES
51
+ # ---------------------------------------------------------------------------
52
+ # 0 "ranked_list" classification (see above)
53
+ # 1 "normal" classification (see above) -- a legitimate outcome, not an error
54
+ # 2 usage error (no argument given)
55
+ #
56
+ # ---------------------------------------------------------------------------
57
+
58
+ set -euo pipefail
59
+
60
+ if [ $# -lt 1 ]; then
61
+ echo 'Usage: argument-is-ranked-list.sh "<raw /todo invocation argument>"' >&2
62
+ exit 2
63
+ fi
64
+
65
+ RAW_INPUT="$1"
66
+
67
+ # Trim leading/trailing whitespace only -- no other normalization. `--ranked-list` "takes no other
68
+ # arguments" per skills/j-todo/SKILL.md, so anything beyond the flag itself (e.g. trailing mission
69
+ # text accidentally combined with it) is deliberately NOT classified as ranked_list here.
70
+ TRIMMED="$(printf '%s' "$RAW_INPUT" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
71
+
72
+ if [ "$TRIMMED" = "--ranked-list" ]; then
73
+ echo '{"classification": "ranked_list"}'
74
+ exit 0
75
+ fi
76
+
77
+ echo '{"classification": "normal"}'
78
+ exit 1