@jenga-ai/agent 1.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -256
- package/agents/developer.md +9 -8
- package/agents/scrum-master.md +57 -23
- package/agents/tester.md +51 -5
- package/hooks/on_session_end.sh +13 -1
- package/lib/generate-agent-context.js +18 -1
- package/lib/generate-copilot-instructions.js +18 -1
- package/lib/generate-skill-allow-list.js +197 -0
- package/lib/skill-allow-list.json +42 -0
- package/package.json +17 -13
- package/scripts/apply-j-prefix.sh +243 -0
- package/scripts/consume-context-digest.sh +103 -0
- package/scripts/generate-j-alias.sh +333 -0
- package/scripts/postinstall.js +25 -0
- package/scripts/sweep-stale-context-digests.sh +132 -0
- package/scripts/validate-board.sh +5 -0
- package/scripts/write-context-digest.sh +230 -0
- package/skills/{brainstorm → j-brainstorm}/SKILL.md +9 -2
- package/skills/{btw → j-btw}/SKILL.md +9 -2
- package/skills/{clearify → j-clearify}/SKILL.md +9 -2
- package/skills/{close-story → j-close-story}/SKILL.md +92 -13
- package/skills/j-close-story/scripts/check-privatized.sh +345 -0
- package/skills/{close-story → j-close-story}/scripts/check-story-closeable.sh +1 -1
- package/skills/{close-story → j-close-story}/scripts/extract-task-diff-stats.sh +1 -1
- package/skills/{commit → j-commit}/SKILL.md +9 -2
- package/skills/j-continue/SKILL.md +36 -0
- package/skills/{deep-dive → j-deep-dive}/SKILL.md +9 -8
- package/skills/{dev-done → j-dev-done}/SKILL.md +11 -4
- package/skills/{dev-done → j-dev-done}/scripts/classify-commit-outcome.sh +4 -4
- package/skills/{distribute → j-distribute}/SKILL.md +17 -10
- package/skills/{distribute → j-distribute}/scripts/distribute-changes.sh +1 -1
- package/skills/{do → j-do}/SKILL.md +111 -14
- package/skills/j-doc/README.md +155 -0
- package/skills/{doc → j-doc}/SKILL.md +55 -18
- package/skills/j-doc/authoring-notes.md +72 -0
- package/skills/j-doc/scripts/resolve_last_update.py +149 -0
- package/skills/{doc-sync → j-doc-sync}/SKILL.md +9 -2
- package/skills/{dooo → j-dooo}/SKILL.md +9 -2
- package/skills/j-error/SKILL.md +36 -0
- package/skills/{evaluate → j-evaluate}/SKILL.md +9 -2
- package/skills/j-examplify/SKILL.md +49 -0
- package/skills/{help → j-help}/SKILL.md +9 -2
- package/skills/{idea → j-idea}/SKILL.md +10 -3
- package/skills/{idea → j-idea}/assets/idea_handoff_template.md +1 -1
- package/skills/{improve → j-improve}/SKILL.md +9 -2
- package/skills/{init → j-init}/SKILL.md +21 -8
- package/skills/j-init/assets/scope-thresholds_template.json +7 -0
- package/skills/j-jbp/SKILL.md +32 -0
- package/skills/j-lgtm/SKILL.md +28 -0
- package/skills/{pi-plan → j-pi-plan}/SKILL.md +10 -3
- package/skills/{proceed → j-proceed}/SKILL.md +9 -2
- package/skills/{publish → j-publish}/SKILL.md +47 -40
- package/skills/{publish → j-publish}/adapters/droplet.md +1 -1
- package/skills/{publish → j-publish}/adapters/mobile-ios.md +3 -3
- package/skills/{publish → j-publish}/adapters/npm-ci.md +29 -7
- package/skills/{publish → j-publish}/adapters/npm.md +8 -8
- package/skills/{publish → j-publish}/assets/ci-contract.md +2 -2
- package/skills/{publish → j-publish}/schemas/publish.schema.json +1 -1
- package/skills/{publish → j-publish}/scripts/npm_ci_pipeline.sh +21 -1
- package/skills/{publish → j-publish}/scripts/npm_stage_inspect.sh +34 -1
- package/skills/{publish → j-publish}/scripts/npm_stage_pipeline.sh +9 -4
- package/skills/{publish → j-publish}/scripts/publish_deploy.sh +4 -4
- package/skills/{publish → j-publish}/scripts/validate_npm_stage_env.sh +1 -1
- package/skills/{publish → j-publish}/wizards/droplet.md +1 -1
- package/skills/{publish → j-publish}/wizards/mobile-ios.md +1 -1
- package/skills/{publish → j-publish}/wizards/npm-ci.md +1 -1
- package/skills/{publish → j-publish}/wizards/npm.md +1 -1
- package/skills/{reconcile → j-reconcile}/SKILL.md +12 -5
- package/skills/{reconcile → j-reconcile}/scripts/detect-unlinked-code.sh +2 -2
- package/skills/{reconcile → j-reconcile}/scripts/resolve-reconcile-scope.sh +3 -3
- package/skills/{reconcile-origin → j-reconcile-origin}/SKILL.md +13 -6
- package/skills/{redo → j-redo}/SKILL.md +9 -2
- package/skills/{skillify → j-skillify}/SKILL.md +10 -3
- package/skills/{spinoff → j-spinoff}/SKILL.md +9 -2
- package/skills/{status → j-status}/SKILL.md +9 -2
- package/skills/j-todo/SKILL.md +92 -0
- package/skills/{todo → j-todo}/assets/todo_handoff_template.md +1 -1
- package/skills/j-todo/scripts/add_trivial_task.sh +216 -0
- package/skills/j-todo/scripts/update_story_tasks.py +87 -0
- package/skills/{uncharted → j-uncharted}/SKILL.md +35 -28
- package/skills/{uncharted → j-uncharted}/assets/UNDERSTANDING_DOC_TEMPLATE.md +2 -2
- package/skills/{uncharted → j-uncharted}/scripts/detect-dependencies.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/detect-tests.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/directory-triage.sh +3 -3
- package/skills/{uncharted → j-uncharted}/scripts/elicitation-state.sh +3 -3
- package/skills/{uncharted → j-uncharted}/scripts/enumerate-target.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/import-source.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/inspect-provenance.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/resolve-segment-target.sh +5 -5
- package/skills/{uncharted → j-uncharted}/scripts/run-engine.sh +1 -1
- package/skills/{uncharted → j-uncharted}/scripts/validate-proposed-items.sh +2 -2
- package/skills/{uncharted → j-uncharted}/scripts/write-backfilled-epics.sh +1 -1
- package/skills/j-wtf/SKILL.md +27 -0
- package/skills/jenga/SKILL.md +1 -1
- package/skills/jenga/scripts/render-confirmation.sh +55 -18
- package/skills/jenga-permission-level/SKILL.md +1 -1
- package/templates/SCRUM_BOARD_SCHEMA.md +33 -2
- package/templates/agent-context.md.tpl +32 -9
- package/templates/copilot-instructions.md.tpl +66 -11
- package/skills/continue/SKILL.md +0 -29
- package/skills/error/SKILL.md +0 -29
- package/skills/examplify/SKILL.md +0 -42
- package/skills/init/assets/scope-thresholds_template.json +0 -7
- package/skills/jbp/SKILL.md +0 -25
- package/skills/lgtm/SKILL.md +0 -21
- package/skills/todo/SKILL.md +0 -48
- package/skills/wtf/SKILL.md +0 -20
- /package/skills/{close-story → j-close-story}/scripts/compute-scope-divergence.sh +0 -0
- /package/skills/{close-story → j-close-story}/scripts/extract-diff-stats.sh +0 -0
- /package/skills/{close-story → j-close-story}/scripts/update-task-frontmatter.sh +0 -0
- /package/skills/{commit → j-commit}/assets/user_instructions_template.md +0 -0
- /package/skills/{distribute → j-distribute}/CONFIG_SCHEMA.md +0 -0
- /package/skills/{distribute → j-distribute}/scripts/check-version.sh +0 -0
- /package/skills/{distribute → j-distribute}/scripts/commit-version-bump.sh +0 -0
- /package/skills/{do → j-do}/assets/intent-vs-diff-prompt.md +0 -0
- /package/skills/{do → j-do}/assets/sender_template.json +0 -0
- /package/skills/{doc → j-doc}/assets/path-objectives.yaml +0 -0
- /package/skills/{doc-sync → j-doc-sync}/assets/default_excludes.txt +0 -0
- /package/skills/{doc-sync → j-doc-sync}/assets/doc_targets.md +0 -0
- /package/skills/{evaluate → j-evaluate}/assets/evaluation_invokation_template.yml +0 -0
- /package/skills/{evaluate → j-evaluate}/assets/evaluation_rapport_template.md +0 -0
- /package/skills/{idea → j-idea}/assets/idea_template.md +0 -0
- /package/skills/{init → j-init}/assets/.gitignore_template +0 -0
- /package/skills/{init → j-init}/assets/PROJECT_SUMMARY_template.md +0 -0
- /package/skills/{init → j-init}/assets/directory_structure.txt +0 -0
- /package/skills/{init → j-init}/assets/strategy_stub_template.md +0 -0
- /package/skills/{init → j-init}/assets/test-config_template.json +0 -0
- /package/skills/{init → j-init}/assets/workflow_template.json +0 -0
- /package/skills/{init → j-init}/scripts/apply-project-visibility.sh +0 -0
- /package/skills/{init → j-init}/scripts/detect-existing-codebase.sh +0 -0
- /package/skills/{init → j-init}/scripts/init.sh +0 -0
- /package/skills/{pi-plan → j-pi-plan}/assets/epic.json +0 -0
- /package/skills/{pi-plan → j-pi-plan}/assets/story_template.md +0 -0
- /package/skills/{publish → j-publish}/assets/ExportOptions.plist.template +0 -0
- /package/skills/{publish → j-publish}/assets/ownership-matrix.md +0 -0
- /package/skills/{publish → j-publish}/assets/publish.example.json +0 -0
- /package/skills/{publish → j-publish}/assets/publish.example.npm-ci.json +0 -0
- /package/skills/{publish → j-publish}/assets/publish.example.npm.json +0 -0
- /package/skills/{publish → j-publish}/assets/secrets-guide.md +0 -0
- /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-minimal.json +0 -0
- /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-with-empty-secrets.json +0 -0
- /package/skills/{publish → j-publish}/schemas/fixtures/npm-ci-with-workflow-path.json +0 -0
- /package/skills/{publish → j-publish}/scripts/check_target_config.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/droplet_pipeline.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/finalize_changelog.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/generate_release_notes.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/ios_pipeline.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/npm_pipeline.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/publish_common.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/reconcile_tags.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/run_gates.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/setup_wizard.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/show_history.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/suggest_semver_bump.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_config.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_droplet_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_ios_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_npm_ci_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/validate_npm_env.sh +0 -0
- /package/skills/{publish → j-publish}/scripts/write_ledger_entry.sh +0 -0
- /package/skills/{reconcile → j-reconcile}/assets/report_format.md +0 -0
- /package/skills/{reconcile-origin → j-reconcile-origin}/scripts/reconcile-origin.sh +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/SKILL.md +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/.gitignore_template +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/PROJECT_SUMMARY_template.md +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/directory_structure.txt +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/test-config_template.json +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/assets/workflow_template.json +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-new/scripts/init.sh +0 -0
- /package/skills/{skillify → j-skillify}/assets/init-old/SKILL.md +0 -0
- /package/skills/{status → j-status}/assets/output_format.md +0 -0
- /package/skills/{todo → j-todo}/assets/todo_template.md +0 -0
- /package/skills/{uncharted → j-uncharted}/assets/SEGMENT_PROPOSAL_TEMPLATE.md +0 -0
- /package/skills/{uncharted → j-uncharted}/scripts/apply-subsystem-cap.sh +0 -0
- /package/skills/{uncharted → j-uncharted}/scripts/discover-subsystems.sh +0 -0
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: reconcile
|
|
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".
|
|
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.
|
|
4
4
|
metadata:
|
|
5
5
|
prefered_agent: scrum-master
|
|
6
|
+
keywords:
|
|
7
|
+
- j-reconcile
|
|
8
|
+
- polyfill
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
# Reconcile — Board ↔ Code Synchronisation
|
|
9
12
|
|
|
13
|
+
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").
|
|
14
|
+
|
|
15
|
+
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.
|
|
16
|
+
|
|
10
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.
|
|
11
18
|
|
|
12
19
|
## Scope argument
|
|
@@ -35,7 +42,7 @@ Omitting the argument entirely keeps today's full-board behavior completely unch
|
|
|
35
42
|
phase below.
|
|
36
43
|
|
|
37
44
|
Scope resolution itself is deterministic and handled entirely by
|
|
38
|
-
`skills/reconcile/scripts/resolve-reconcile-scope.sh` (see Phase 0 immediately below) — this skill
|
|
45
|
+
`skills/j-reconcile/scripts/resolve-reconcile-scope.sh` (see Phase 0 immediately below) — this skill
|
|
39
46
|
only interprets that script's output; it does not re-parse scope arguments or re-derive range
|
|
40
47
|
expansion.
|
|
41
48
|
|
|
@@ -50,7 +57,7 @@ Before touching anything else, resolve the scope argument (if any — see "Scope
|
|
|
50
57
|
into a concrete set of epic/story/task ids:
|
|
51
58
|
|
|
52
59
|
```bash
|
|
53
|
-
skills/reconcile/scripts/resolve-reconcile-scope.sh <scope-argument>
|
|
60
|
+
skills/j-reconcile/scripts/resolve-reconcile-scope.sh <scope-argument>
|
|
54
61
|
```
|
|
55
62
|
|
|
56
63
|
Omit `<scope-argument>` entirely for an unscoped, full-board run (the script's own no-argument
|
|
@@ -176,7 +183,7 @@ Phases 2 and 3 ask "does this board item exist in the code?". This phase asks th
|
|
|
176
183
|
Run:
|
|
177
184
|
|
|
178
185
|
```bash
|
|
179
|
-
skills/reconcile/scripts/detect-unlinked-code.sh
|
|
186
|
+
skills/j-reconcile/scripts/detect-unlinked-code.sh
|
|
180
187
|
```
|
|
181
188
|
|
|
182
189
|
It emits a single JSON object and exits `0` whether or not it finds anything; read
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ---------------------------------------------------------------------------
|
|
3
|
-
# skills/reconcile/scripts/detect-unlinked-code.sh
|
|
3
|
+
# skills/j-reconcile/scripts/detect-unlinked-code.sh
|
|
4
4
|
#
|
|
5
5
|
# The inverse half of `/reconcile`. The normal pass asks "does this board item
|
|
6
6
|
# exist in the code?"; this asks "does this code exist on the board?" and finds
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
# It scans, it classifies, it reports. It NEVER writes anything, never touches
|
|
32
32
|
# the board, and never invokes `/uncharted`. Deciding which groups are worth
|
|
33
33
|
# investigating and presenting the offer is agent judgement and lives in
|
|
34
|
-
# `skills/reconcile/SKILL.md`.
|
|
34
|
+
# `skills/j-reconcile/SKILL.md`.
|
|
35
35
|
#
|
|
36
36
|
# ---------------------------------------------------------------------------
|
|
37
37
|
# SIGNAL A IS BORROWED, NOT REBUILT
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ---------------------------------------------------------------------------
|
|
3
|
-
# skills/reconcile/scripts/resolve-reconcile-scope.sh
|
|
3
|
+
# skills/j-reconcile/scripts/resolve-reconcile-scope.sh
|
|
4
4
|
#
|
|
5
5
|
# Deterministic scope-argument resolver backing `/reconcile`'s new scope
|
|
6
6
|
# argument (story E17_S07). This script owns ALL scope-argument parsing and
|
|
7
|
-
# id-range expansion for `/reconcile` — `skills/reconcile/SKILL.md` (wired in
|
|
7
|
+
# id-range expansion for `/reconcile` — `skills/j-reconcile/SKILL.md` (wired in
|
|
8
8
|
# the sibling task E17_S07_T02) only interprets this script's structured
|
|
9
9
|
# stdout output; it must not re-derive any parsing or resolution logic
|
|
10
10
|
# inline.
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
# "epic_ids": ["E12"],
|
|
125
125
|
# "story_ids": ["E12_S03", "E12_S04", "E12_S05"],
|
|
126
126
|
# "task_ids": ["E12_S03_T01", "..."],
|
|
127
|
-
# "owned_path_hints": ["skills/reconcile/", "..."]
|
|
127
|
+
# "owned_path_hints": ["skills/j-reconcile/", "..."]
|
|
128
128
|
# }
|
|
129
129
|
#
|
|
130
130
|
# scope_type "full" epic_ids/story_ids/task_ids are all EMPTY arrays.
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: reconcile-origin
|
|
3
|
-
description: Sync the current (or specified) branch with origin by rebasing local commits on top of the latest upstream state.
|
|
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.
|
|
4
4
|
keywords:
|
|
5
5
|
- "sync branch"
|
|
6
6
|
- "rebase origin"
|
|
7
7
|
- "reconcile origin"
|
|
8
8
|
- "pull rebase"
|
|
9
|
+
- j-reconcile-origin
|
|
10
|
+
- polyfill
|
|
9
11
|
examples:
|
|
10
12
|
- "sync my branch with origin"
|
|
11
13
|
- "rebase local commits on top of origin"
|
|
12
14
|
- "reconcile-origin feature/my-branch"
|
|
15
|
+
- "j-reconcile-origin"
|
|
13
16
|
---
|
|
14
17
|
|
|
15
18
|
# Reconcile Origin
|
|
16
19
|
|
|
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").
|
|
21
|
+
|
|
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.
|
|
23
|
+
|
|
17
24
|
Use this skill to rebase local work on top of the latest `origin/<branch>` state without re-implementing git logic inline.
|
|
18
25
|
|
|
19
26
|
## Instructions
|
|
@@ -22,7 +29,7 @@ Use this skill to rebase local work on top of the latest `origin/<branch>` state
|
|
|
22
29
|
- If the user passed an argument, use that branch name.
|
|
23
30
|
- Otherwise, use the current branch name.
|
|
24
31
|
|
|
25
|
-
2. Invoke `.agents/skills/reconcile-origin/scripts/reconcile-origin.sh [<branch>]` and capture stdout.
|
|
32
|
+
2. Invoke `.agents/skills/j-reconcile-origin/scripts/reconcile-origin.sh [<branch>]` and capture stdout.
|
|
26
33
|
- Do not run any inline git commands in this skill — all git work is handled by the script.
|
|
27
34
|
- The script handles dirty-worktree detection internally and returns `{"status":"error","code":"uncommitted_changes",...}` if the working tree is not clean.
|
|
28
35
|
|
|
@@ -38,7 +45,7 @@ Use this skill to rebase local work on top of the latest `origin/<branch>` state
|
|
|
38
45
|
2. Cancel and inspect the branch setup manually
|
|
39
46
|
3. Other (describe below)
|
|
40
47
|
|
|
41
|
-
- If the user chooses option 1, invoke `.agents/skills/reconcile-origin/scripts/reconcile-origin.sh <branch> --create-tracking`.
|
|
48
|
+
- If the user chooses option 1, invoke `.agents/skills/j-reconcile-origin/scripts/reconcile-origin.sh <branch> --create-tracking`.
|
|
42
49
|
- If `remote_exists` is `false`, explain that neither a local branch nor `origin/<branch>` was found and stop.
|
|
43
50
|
- `conflict`
|
|
44
51
|
- Present one structured conflict rapport per item in `conflicts`.
|
|
@@ -55,7 +62,7 @@ Use this skill to rebase local work on top of the latest `origin/<branch>` state
|
|
|
55
62
|
3. Handle it later — leave annotated conflict markers in the file and continue the scripted flow
|
|
56
63
|
4. Other (describe below)
|
|
57
64
|
|
|
58
|
-
- If the user chooses “Handle it later”, invoke `.agents/skills/reconcile-origin/scripts/reconcile-origin.sh <branch> --handle-later <file>` for the selected conflict file.
|
|
65
|
+
- If the user chooses “Handle it later”, invoke `.agents/skills/j-reconcile-origin/scripts/reconcile-origin.sh <branch> --handle-later <file>` for the selected conflict file.
|
|
59
66
|
- `handled_later`
|
|
60
67
|
- Confirm that the selected file was annotated for later resolution.
|
|
61
68
|
- Tell the user the conflict markers were intentionally preserved with a `# RECONCILE-ORIGIN CONFLICT:` note.
|
|
@@ -71,5 +78,5 @@ Use this skill to rebase local work on top of the latest `origin/<branch>` state
|
|
|
71
78
|
|
|
72
79
|
## Guard Rails
|
|
73
80
|
|
|
74
|
-
- All git work must go through `.agents/skills/reconcile-origin/scripts/reconcile-origin.sh`.
|
|
81
|
+
- All git work must go through `.agents/skills/j-reconcile-origin/scripts/reconcile-origin.sh`.
|
|
75
82
|
- Do not inline fetch, checkout, pull, merge, rebase, or status commands in this skill body.
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: redo
|
|
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.
|
|
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.
|
|
4
4
|
keywords:
|
|
5
5
|
- redo
|
|
6
6
|
- rework
|
|
7
7
|
- rewrite
|
|
8
8
|
- revisit
|
|
9
9
|
- redo task
|
|
10
|
+
- j-redo
|
|
11
|
+
- polyfill
|
|
10
12
|
examples:
|
|
11
13
|
- "redo the login implementation"
|
|
12
14
|
- "rewrite story E02_S01"
|
|
15
|
+
- "j-redo"
|
|
13
16
|
metadata:
|
|
14
17
|
prefered_agent: scrum-master
|
|
15
18
|
---
|
|
16
19
|
|
|
17
20
|
# Redo — Rework a Previous Implementation
|
|
18
21
|
|
|
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").
|
|
23
|
+
|
|
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.
|
|
25
|
+
|
|
19
26
|
## Input Format
|
|
20
27
|
|
|
21
28
|
```
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: skillify
|
|
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?".
|
|
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.
|
|
4
|
+
keywords:
|
|
5
|
+
- j-skillify
|
|
6
|
+
- polyfill
|
|
4
7
|
---
|
|
5
8
|
|
|
6
9
|
# Skillify — Refactor a Skill into a Cleaner Structure
|
|
7
10
|
|
|
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").
|
|
12
|
+
|
|
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.
|
|
14
|
+
|
|
8
15
|
## What this skill does
|
|
9
16
|
|
|
10
17
|
Takes one or more existing skills and refactors them by:
|
|
@@ -65,4 +72,4 @@ The rewritten SKILL.md should:
|
|
|
65
72
|
- `assets/init-old/SKILL.md` — The init skill before refactoring (hardcoded heredocs, inline JSON, hardcoded directory list)
|
|
66
73
|
- `assets/init-new/SKILL.md` — The init skill after refactoring (all content in assets, steps delegated to `init.sh`)
|
|
67
74
|
|
|
68
|
-
Read these when you need a concrete example of the before/after pattern.
|
|
75
|
+
Read these when you need a concrete example of the before/after pattern.
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: spinoff
|
|
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.
|
|
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.
|
|
4
4
|
keywords:
|
|
5
5
|
- spinoff
|
|
6
6
|
- diverge
|
|
7
7
|
- side topic
|
|
8
8
|
- capture topic
|
|
9
9
|
- new thread
|
|
10
|
+
- j-spinoff
|
|
11
|
+
- polyfill
|
|
10
12
|
examples:
|
|
11
13
|
- "let's spinoff this idea"
|
|
12
14
|
- "capture this as a separate thread"
|
|
15
|
+
- "j-spinoff"
|
|
13
16
|
metadata:
|
|
14
17
|
prefered_agent: scrum-master
|
|
15
18
|
---
|
|
16
19
|
|
|
17
20
|
# Spinoff — Capture a Diverging Topic
|
|
18
21
|
|
|
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").
|
|
23
|
+
|
|
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.
|
|
25
|
+
|
|
19
26
|
## Instructions
|
|
20
27
|
|
|
21
28
|
1. **Identify the diverging topic** — Ask the user to confirm or briefly describe the diverging topic.
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: status
|
|
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.
|
|
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.
|
|
4
4
|
keywords:
|
|
5
5
|
- status
|
|
6
6
|
- board summary
|
|
7
7
|
- overview
|
|
8
8
|
- project state
|
|
9
9
|
- what's done
|
|
10
|
+
- j-status
|
|
11
|
+
- polyfill
|
|
10
12
|
examples:
|
|
11
13
|
- "show me the project status"
|
|
12
14
|
- "what's the state of the board?"
|
|
15
|
+
- "j-status"
|
|
13
16
|
---
|
|
14
17
|
|
|
15
18
|
# Status — Board Overview
|
|
16
19
|
|
|
20
|
+
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").
|
|
21
|
+
|
|
22
|
+
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.
|
|
23
|
+
|
|
17
24
|
## Instructions
|
|
18
25
|
|
|
19
26
|
1. **Read `project/configs/workflow.json`** to confirm board paths. Fall back to `project/board/` if the file does not exist.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
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
|
+
keywords:
|
|
5
|
+
- todo
|
|
6
|
+
- add task
|
|
7
|
+
- queue work
|
|
8
|
+
- backlog
|
|
9
|
+
- add to list
|
|
10
|
+
- j-todo
|
|
11
|
+
- polyfill
|
|
12
|
+
examples:
|
|
13
|
+
- "add this to the todo list"
|
|
14
|
+
- "queue this as a task"
|
|
15
|
+
- "j-todo"
|
|
16
|
+
metadata:
|
|
17
|
+
prefered_agent: scrum-master
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Todo — Add Missions to the Todo List
|
|
21
|
+
|
|
22
|
+
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").
|
|
23
|
+
|
|
24
|
+
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.
|
|
25
|
+
|
|
26
|
+
## `--trivial` Flag
|
|
27
|
+
|
|
28
|
+
**Syntax:** `/todo --trivial <description>` — optionally combined with the same `: <Epic no.>_<Story no.>` linkage syntax normal `/todo` entries use, e.g. `/todo --trivial Fix typo in error message: E12_S03`.
|
|
29
|
+
|
|
30
|
+
When `--trivial` is present, the mission is written as a **fully-formed task board file immediately** (not just a raw `todo.md` line deferred to `/do`'s own breakdown pass) with `execution_scope: inline` forced unconditionally — no threshold computation is consulted for the scope value itself. See step 4.5 below for the mechanics.
|
|
31
|
+
|
|
32
|
+
**Human-only override.** `--trivial` is invoked by a human typing `/todo --trivial ...` — it is never applied by the scrum-master to itself during autonomous story/epic breakdown elsewhere (e.g. `/jenga`'s Phase 0.5, or `/do`'s own scrum-master decomposition step in `skills/do/SKILL.md` step 3). Those paths keep using the normal heuristic-only `execution_scope` assignment documented in `agents/scrum-master.md`'s Execution Scope Assignment section, unmodified by this flag.
|
|
33
|
+
|
|
34
|
+
**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.
|
|
35
|
+
|
|
36
|
+
## Instructions
|
|
37
|
+
|
|
38
|
+
1. **Ensure `project/todo.md` exists** — If it doesn't exist, it will be auto-created by `todo_manager.sh` — no manual action needed.
|
|
39
|
+
|
|
40
|
+
2. **Ask the user about the mission:**
|
|
41
|
+
- Where do you want to do this?
|
|
42
|
+
- What would you like to do?
|
|
43
|
+
- What is the goal?
|
|
44
|
+
- (If `--trivial` was passed, these answers still apply — `--trivial` changes how the mission is written to the board in step 4.5, not what's asked here.)
|
|
45
|
+
|
|
46
|
+
3. **Classify the mission** — Check if it fits into:
|
|
47
|
+
- An existing story
|
|
48
|
+
- A new story inside an existing Epic
|
|
49
|
+
- A new story inside a new Epic
|
|
50
|
+
- None of the above
|
|
51
|
+
|
|
52
|
+
**`--trivial` requires an existing (or, in this same step, newly-created) story to attach to.** It forces the scope of a single task, not a container — if the mission has no story yet, create it now via step 4 below exactly as normal, then continue to step 4.5. `--trivial` cannot be used for "None of the above."
|
|
53
|
+
|
|
54
|
+
4. **Update project documentation** — Add the mission to the appropriate files under `project/board/epics/` and `project/board/stories/` if applicable.
|
|
55
|
+
- If the mission involves implementing or modifying a skill, apply the **Skill Implementation Principle — Scripts Over Inline Logic** (see `CLAUDE.md` / `AGENTS.md`): note in the story/task's acceptance criteria that deterministic, repeatable steps must be offloaded to scripts under `skills/<name>/scripts/` (or `scripts/`) rather than encoded as inline agent instructions in `SKILL.md`.
|
|
56
|
+
- If the user indicates the mission is high-risk, or explicitly asks to flag it, set an elevated caution tier directly on the story or task frontmatter: `crucial_level` (one of `advisory`, `gated`, `locked` — see `templates/SCRUM_BOARD_SCHEMA.md` for valid values and their meaning), `crucial_set_by: user`, and `crucial_note` capturing the user's stated reason. This user-initiated flag is written immediately — it does not require the confirm-before-write gate, which applies only to scrum-master-*proposed* caution tiers (a separate, heuristic-driven path).
|
|
57
|
+
|
|
58
|
+
4.5. **If `--trivial` was passed, create the task now** (skip step 5 — this step writes the todo.md entry itself):
|
|
59
|
+
|
|
60
|
+
a. **Estimate the change**, using the same judgment `agents/scrum-master.md`'s Execution Scope Assignment heuristic applies: how many files will this mission likely touch, and roughly how many lines. This is a reasoning step, not a script step — do not guess wildly, but a rough, honest estimate is sufficient.
|
|
61
|
+
|
|
62
|
+
b. **Determine `computed_tier`** — what `execution_scope` the normal heuristic would have assigned to this estimate, purely for the audit trail (it is never written as the actual `execution_scope`, which is always forced to `inline`):
|
|
63
|
+
- Read `inline_max_files`, `inline_max_lines`, and `story_max_files` from `project/configs/scope-thresholds.json` at run time — never hardcode these numbers here.
|
|
64
|
+
- Apply `agents/scrum-master.md`'s `inline` / `story` / `task` heuristics (file count vs. `inline_max_files`, line estimate vs. `inline_max_lines`, contention and cross-cutting checks for `story`) to the estimate from (a). The result is `computed_tier` — one of `inline`, `task`, or `story` (never `epic` — the heuristic never autonomously computes `epic`).
|
|
65
|
+
|
|
66
|
+
c. **Run the helper script**, which handles everything mechanical — next task-ID assignment, writing the task board file with `execution_scope: inline` forced, registering the new task ID into the parent story's `tasks:` frontmatter list, and adding the `project/todo.md` entry using the full task ID (so `/do` routes straight into its Inline Execution Path with no redundant breakdown pass):
|
|
67
|
+
```
|
|
68
|
+
bash skills/j-todo/scripts/add_trivial_task.sh \
|
|
69
|
+
--story <E##_S##> \
|
|
70
|
+
--title "<mission title>" \
|
|
71
|
+
--description "<mission description>" \
|
|
72
|
+
--criteria "<criterion 1>|<criterion 2>|..." \
|
|
73
|
+
--computed-tier <inline|task|story> \
|
|
74
|
+
--est-files <N> \
|
|
75
|
+
--est-lines <M> \
|
|
76
|
+
[--prerequisites "<text>"]
|
|
77
|
+
```
|
|
78
|
+
The script writes `scope_rationale` in the form `"forced inline via --trivial; computed scope would have been '<computed_tier>' — estimated <N> files, ~<M> lines"` and sets `jenga_assigned: false` with a matching `override_justification`, so `/do` step 4.1's existing override-validation logs the override on dispatch — no separate acknowledgement step needed here.
|
|
79
|
+
On success the script prints the new task ID to stdout; on failure (e.g. the story doesn't exist yet, or `--computed-tier` is invalid) it exits non-zero with an explanatory message on stderr — surface that to the user rather than retrying blindly.
|
|
80
|
+
d. Continue to step 6 (skip step 5 — the script already added the `todo.md` entry).
|
|
81
|
+
|
|
82
|
+
5. **Add to `project/todo.md`** by running (skip this step if step 4.5 already ran):
|
|
83
|
+
```
|
|
84
|
+
bash scripts/todo_manager.sh add '<mission title>: <Epic no.>_<Story no.>'
|
|
85
|
+
```
|
|
86
|
+
The epic and story reference is only required if the mission is assigned to one.
|
|
87
|
+
|
|
88
|
+
6. **Ask the user**: "Add another todo" or "Done"?
|
|
89
|
+
- If **add another** — go back to step 2. (`--trivial` applies only to the mission it was passed with — it does not carry over to the next mission unless the user says `--trivial` again.)
|
|
90
|
+
- If **done** — ask if they want to execute the todo list.
|
|
91
|
+
- If **yes** — invoke the `/do` skill.
|
|
92
|
+
- If **no** — exit.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<!-- PLACEHOLDER: what this todo is trying to achieve -->
|
|
14
14
|
|
|
15
15
|
## Affected Files or Scope
|
|
16
|
-
<!-- PLACEHOLDER: which files, modules, or areas are involved, e.g. src/auth/, skills/todo/ -->
|
|
16
|
+
<!-- PLACEHOLDER: which files, modules, or areas are involved, e.g. src/auth/, skills/j-todo/ -->
|
|
17
17
|
|
|
18
18
|
## Intended Approach
|
|
19
19
|
<!-- PLACEHOLDER: step-by-step or high-level approach to the work -->
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# skills/j-todo/scripts/add_trivial_task.sh
|
|
3
|
+
#
|
|
4
|
+
# Creates a fully-formed task board file for a `/todo --trivial` mission,
|
|
5
|
+
# forced to execution_scope: inline unconditionally, and registers it both
|
|
6
|
+
# in its parent story's tasks: frontmatter list and in project/todo.md.
|
|
7
|
+
#
|
|
8
|
+
# This script performs only the MECHANICAL half of --trivial: templating the
|
|
9
|
+
# task file, assigning the next task number, and wiring it into the board.
|
|
10
|
+
# The JUDGMENT half — estimating file/line counts and deciding what
|
|
11
|
+
# execution_scope the normal heuristic in agents/scrum-master.md would have
|
|
12
|
+
# assigned (computed_tier) — happens in the calling agent's instructions
|
|
13
|
+
# (skills/j-todo/SKILL.md), per the Skill Implementation Principle: a step that
|
|
14
|
+
# requires reasoning about branching logic, new dependencies, etc. does not
|
|
15
|
+
# belong in a script. This script never reads project/configs/scope-thresholds.json
|
|
16
|
+
# or recomputes computed_tier itself — it only records what it was told.
|
|
17
|
+
#
|
|
18
|
+
# Usage:
|
|
19
|
+
# add_trivial_task.sh --story <E##_S##> --title "<title>" \
|
|
20
|
+
# --description "<description>" --criteria "<c1>|<c2>|..." \
|
|
21
|
+
# --computed-tier <inline|task|story> --est-files <N> --est-lines <M> \
|
|
22
|
+
# [--prerequisites "<text>"]
|
|
23
|
+
#
|
|
24
|
+
# Requires an ALREADY-EXISTING parent story file (--trivial does not create
|
|
25
|
+
# stories or epics — resolve/create those first via the normal /todo flow).
|
|
26
|
+
#
|
|
27
|
+
# On success, prints the new task ID (e.g. E32_S14_T05) to stdout and exits 0.
|
|
28
|
+
|
|
29
|
+
set -euo pipefail
|
|
30
|
+
|
|
31
|
+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
|
32
|
+
cd "$REPO_ROOT"
|
|
33
|
+
|
|
34
|
+
TASKS_DIR="project/board/tasks"
|
|
35
|
+
STORIES_DIR="project/board/stories"
|
|
36
|
+
UPDATE_STORY_SCRIPT="skills/j-todo/scripts/update_story_tasks.py"
|
|
37
|
+
|
|
38
|
+
story_id=""
|
|
39
|
+
title=""
|
|
40
|
+
description=""
|
|
41
|
+
criteria=""
|
|
42
|
+
computed_tier=""
|
|
43
|
+
est_files=""
|
|
44
|
+
est_lines=""
|
|
45
|
+
prerequisites="None."
|
|
46
|
+
|
|
47
|
+
usage() {
|
|
48
|
+
cat >&2 <<EOF
|
|
49
|
+
Usage: $0 --story <E##_S##> --title "<title>" --description "<description>" \\
|
|
50
|
+
--criteria "<c1>|<c2>|..." --computed-tier <inline|task|story> \\
|
|
51
|
+
--est-files <N> --est-lines <M> [--prerequisites "<text>"]
|
|
52
|
+
EOF
|
|
53
|
+
exit 1
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
while [ $# -gt 0 ]; do
|
|
57
|
+
case "$1" in
|
|
58
|
+
--story) story_id="$2"; shift 2 ;;
|
|
59
|
+
--title) title="$2"; shift 2 ;;
|
|
60
|
+
--description) description="$2"; shift 2 ;;
|
|
61
|
+
--criteria) criteria="$2"; shift 2 ;;
|
|
62
|
+
--computed-tier) computed_tier="$2"; shift 2 ;;
|
|
63
|
+
--est-files) est_files="$2"; shift 2 ;;
|
|
64
|
+
--est-lines) est_lines="$2"; shift 2 ;;
|
|
65
|
+
--prerequisites) prerequisites="$2"; shift 2 ;;
|
|
66
|
+
-h|--help) usage ;;
|
|
67
|
+
*) echo "Error: unknown argument '$1'" >&2; usage ;;
|
|
68
|
+
esac
|
|
69
|
+
done
|
|
70
|
+
|
|
71
|
+
for req_name in story_id title description criteria computed_tier est_files est_lines; do
|
|
72
|
+
if [ -z "${!req_name}" ]; then
|
|
73
|
+
echo "Error: --${req_name//_/-} is required" >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
done
|
|
77
|
+
|
|
78
|
+
if ! [[ "$story_id" =~ ^E[0-9]+_S[0-9]+$ ]]; then
|
|
79
|
+
echo "Error: --story must look like E##_S## (got '$story_id')" >&2
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
case "$computed_tier" in
|
|
84
|
+
inline|task|story) ;;
|
|
85
|
+
*) echo "Error: --computed-tier must be one of: inline, task, story (got '$computed_tier')" >&2; exit 1 ;;
|
|
86
|
+
esac
|
|
87
|
+
|
|
88
|
+
case "$est_files" in
|
|
89
|
+
''|*[!0-9]*) echo "Error: --est-files must be a non-negative integer (got '$est_files')" >&2; exit 1 ;;
|
|
90
|
+
esac
|
|
91
|
+
case "$est_lines" in
|
|
92
|
+
''|*[!0-9]*) echo "Error: --est-lines must be a non-negative integer (got '$est_lines')" >&2; exit 1 ;;
|
|
93
|
+
esac
|
|
94
|
+
|
|
95
|
+
epic_id="${story_id%%_S*}"
|
|
96
|
+
|
|
97
|
+
# Locate the parent story file. --trivial requires it to already exist.
|
|
98
|
+
story_file=""
|
|
99
|
+
for f in "${STORIES_DIR}/${story_id}_"*.md; do
|
|
100
|
+
if [ -f "$f" ]; then
|
|
101
|
+
story_file="$f"
|
|
102
|
+
break
|
|
103
|
+
fi
|
|
104
|
+
done
|
|
105
|
+
if [ -z "$story_file" ]; then
|
|
106
|
+
echo "Error: no story file found for $story_id under $STORIES_DIR/. --trivial requires an already-resolved story — create it via the normal /todo flow first." >&2
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
if [ ! -f "$UPDATE_STORY_SCRIPT" ]; then
|
|
111
|
+
echo "Error: $UPDATE_STORY_SCRIPT not found." >&2
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Determine the next task number for this story by scanning existing task files.
|
|
116
|
+
max_num=0
|
|
117
|
+
shopt -s nullglob
|
|
118
|
+
for f in "${TASKS_DIR}/${story_id}_T"*.md; do
|
|
119
|
+
base="$(basename "$f")"
|
|
120
|
+
num="$(printf '%s' "$base" | sed -nE "s/^${story_id}_T([0-9]+)_.*/\1/p")"
|
|
121
|
+
if [ -n "$num" ]; then
|
|
122
|
+
num=$((10#$num))
|
|
123
|
+
if [ "$num" -gt "$max_num" ]; then
|
|
124
|
+
max_num=$num
|
|
125
|
+
fi
|
|
126
|
+
fi
|
|
127
|
+
done
|
|
128
|
+
shopt -u nullglob
|
|
129
|
+
next_num=$((max_num + 1))
|
|
130
|
+
next_num_padded="$(printf '%02d' "$next_num")"
|
|
131
|
+
task_id="${story_id}_T${next_num_padded}"
|
|
132
|
+
|
|
133
|
+
shopt -s nullglob
|
|
134
|
+
existing_matches=("${TASKS_DIR}/${task_id}_"*.md)
|
|
135
|
+
shopt -u nullglob
|
|
136
|
+
if [ "${#existing_matches[@]}" -gt 0 ]; then
|
|
137
|
+
echo "Error: a task file for $task_id already exists (ID collision). Aborting." >&2
|
|
138
|
+
exit 1
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Slugify the title for the filename.
|
|
142
|
+
slug="$(printf '%s' "$title" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//')"
|
|
143
|
+
slug="${slug:0:60}"
|
|
144
|
+
slug="${slug%-}"
|
|
145
|
+
if [ -z "$slug" ]; then
|
|
146
|
+
slug="trivial-task"
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
today="$(date -u +%Y-%m-%d)"
|
|
150
|
+
|
|
151
|
+
scope_rationale="forced inline via --trivial; computed scope would have been '${computed_tier}' — estimated ${est_files} files, ~${est_lines} lines"
|
|
152
|
+
override_justification="/todo --trivial invoked by user on ${today}; execution_scope forced to 'inline', overriding the heuristic's computed '${computed_tier}' tier (see scope_rationale)."
|
|
153
|
+
|
|
154
|
+
# Build the Acceptance Criteria block from the pipe-separated --criteria value.
|
|
155
|
+
criteria_block=""
|
|
156
|
+
IFS='|' read -ra crit_arr <<< "$criteria"
|
|
157
|
+
for c in "${crit_arr[@]}"; do
|
|
158
|
+
c_trimmed="$(printf '%s' "$c" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')"
|
|
159
|
+
if [ -n "$c_trimmed" ]; then
|
|
160
|
+
criteria_block+="- [ ] ${c_trimmed}"$'\n'
|
|
161
|
+
fi
|
|
162
|
+
done
|
|
163
|
+
if [ -z "$criteria_block" ]; then
|
|
164
|
+
echo "Error: --criteria produced no usable acceptance criteria" >&2
|
|
165
|
+
exit 1
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
task_file="${TASKS_DIR}/${task_id}_${slug}.md"
|
|
169
|
+
|
|
170
|
+
cat > "$task_file" <<EOF
|
|
171
|
+
---
|
|
172
|
+
id: ${task_id}
|
|
173
|
+
story_id: ${story_id}
|
|
174
|
+
epic_id: ${epic_id}
|
|
175
|
+
title: ${title}
|
|
176
|
+
status: Pending
|
|
177
|
+
date_created: ${today}
|
|
178
|
+
date_started:
|
|
179
|
+
date_completed:
|
|
180
|
+
dates_previously_completed:
|
|
181
|
+
reopened_on:
|
|
182
|
+
reopened_reason:
|
|
183
|
+
assigned_to: developer
|
|
184
|
+
docs: []
|
|
185
|
+
execution_scope: inline
|
|
186
|
+
needs_docs: false
|
|
187
|
+
scope_rationale: "${scope_rationale}"
|
|
188
|
+
jenga_assigned: false
|
|
189
|
+
override_justification: "${override_justification}"
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
# Task: ${title}
|
|
193
|
+
|
|
194
|
+
## Description
|
|
195
|
+
${description}
|
|
196
|
+
|
|
197
|
+
## Prerequisites
|
|
198
|
+
${prerequisites}
|
|
199
|
+
|
|
200
|
+
## Acceptance Criteria
|
|
201
|
+
${criteria_block}
|
|
202
|
+
EOF
|
|
203
|
+
|
|
204
|
+
echo "Wrote task file: ${task_file}"
|
|
205
|
+
|
|
206
|
+
# Register the new task under its parent story's tasks: frontmatter list.
|
|
207
|
+
if ! scripts/with-lock.sh "$story_file" -- python3 "$UPDATE_STORY_SCRIPT" "$story_file" "$task_id"; then
|
|
208
|
+
echo "Error: failed to register ${task_id} in ${story_file}'s tasks: list (lock timeout or write failure)." >&2
|
|
209
|
+
exit 1
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
# Register the todo entry using the FULL task ID, so /do routes straight into
|
|
213
|
+
# its Inline Execution Path without a redundant breakdown pass.
|
|
214
|
+
bash scripts/todo_manager.sh add "${title}: ${task_id}"
|
|
215
|
+
|
|
216
|
+
echo "${task_id}"
|