@jenga-ai/agent 3.1.0 → 3.2.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 +3 -3
- package/agents/developer.md +15 -15
- package/agents/scrum-master.md +17 -17
- package/agents/tester.md +25 -15
- package/lib/skill-allow-list.json +3 -2
- package/package.json +1 -1
- package/scripts/audit-twin-divergence.sh +625 -0
- package/scripts/build-pages-site.sh +268 -0
- package/scripts/check-public-playbook-steps.sh +136 -0
- package/skills/j-close-story/SKILL.md +1 -1
- package/skills/j-do/SKILL.md +19 -19
- package/skills/j-doc-sync/SKILL.md +12 -1
- package/skills/j-idea/SKILL.md +1 -1
- package/skills/j-init/SKILL.md +5 -4
- package/skills/j-init/assets/directory_structure.txt +1 -0
- package/skills/j-init/scripts/detect-existing-codebase.sh +2 -2
- package/skills/j-init/scripts/init.sh +13 -2
- package/skills/j-playbook/SKILL.md +81 -0
- package/skills/j-proceed/SKILL.md +1 -1
- package/skills/j-publish/SKILL.md +1 -1
- package/skills/j-publish/adapters/npm-ci.md +29 -0
- package/skills/j-publish/scripts/npm_ci_pipeline.sh +3 -0
- package/skills/j-publish/scripts/npm_pipeline.sh +18 -0
- package/skills/j-publish/scripts/npm_stage_pipeline.sh +81 -41
- package/skills/j-reconcile/SKILL.md +1 -0
- package/skills/j-redo/SKILL.md +1 -1
- package/skills/j-status/SKILL.md +12 -0
- package/skills/j-todo/SKILL.md +2 -2
- package/skills/j-uncharted/SKILL.md +8 -7
- package/skills/j-uncharted/scripts/elicitation-state.sh +15 -1
- package/skills/j-uncharted/scripts/validate-proposed-items.sh +18 -2
- package/skills/jenga/SKILL.md +80 -9
- package/skills/jenga/playbooks/idea-to-committed.json +20 -0
- package/skills/jenga/playbooks/schema.json +42 -0
- package/skills/jenga/scripts/detect-nl-intent.sh +179 -0
- package/skills/jenga/scripts/load-nl-catalog.js +206 -0
- package/skills/jenga/scripts/load-nl-catalog.sh +65 -0
- package/skills/jenga/scripts/load-playbooks.sh +1022 -0
- package/skills/jenga/scripts/match-playbook.sh +262 -0
- package/skills/jenga/scripts/render-playbook-confirmation.sh +517 -0
- package/skills/jenga/scripts/run-playbook-step.sh +766 -0
- package/skills/jenga-permission-level/SKILL.md +4 -4
- package/templates/KNOWLEDGE_GRAPH_STUB_SCHEMA_TEMPLATE.md +128 -0
- package/templates/playbook-types.json +8 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/build-pages-site.sh
|
|
3
|
+
#
|
|
4
|
+
# Deterministically (re)generates the wiki-derived pages of the GitHub Pages
|
|
5
|
+
# documentation site (docs/*.md) from the existing wiki mirror under
|
|
6
|
+
# project/.wiki/. This is the sync mechanism behind E41_S13_T01's
|
|
7
|
+
# source-of-truth decision ("restructure from the wiki, keep both in sync"):
|
|
8
|
+
# project/.wiki/ stays the canonical, doc-sync-maintained content; this
|
|
9
|
+
# script is the deterministic transform from that content into the
|
|
10
|
+
# multi-page, navigable Pages site.
|
|
11
|
+
#
|
|
12
|
+
# WHEN TO RE-RUN: after `j.doc-sync` (or any manual edit) updates
|
|
13
|
+
# project/.wiki/documentation.md, project/.wiki/intro-guide.md, or
|
|
14
|
+
# project/.wiki/concepts/*.md, re-run this script to refresh the Pages site
|
|
15
|
+
# so it doesn't silently drift from the wiki the way README.md and the wiki
|
|
16
|
+
# itself have drifted from each other before (see skills/doc-sync/SKILL.md
|
|
17
|
+
# for the doc-sync side of this convention).
|
|
18
|
+
#
|
|
19
|
+
# WHAT THIS SCRIPT DOES NOT TOUCH:
|
|
20
|
+
# - docs/_config.yml, docs/index.md — hand-authored site structure/config,
|
|
21
|
+
# not derived from wiki content. Edit these directly if the page set or
|
|
22
|
+
# nav changes.
|
|
23
|
+
# - docs/README.md — maintainer-facing decision record, not a rendered
|
|
24
|
+
# Jekyll page and not wiki-derived content.
|
|
25
|
+
#
|
|
26
|
+
# WHAT THIS SCRIPT REGENERATES (always overwritten, never hand-edit these):
|
|
27
|
+
# - docs/getting-started.md <- project/.wiki/intro-guide.md
|
|
28
|
+
# - docs/concepts.md <- project/.wiki/concepts/*.md (concatenated)
|
|
29
|
+
# - docs/skills.md <- project/.wiki/documentation.md "## Skills"
|
|
30
|
+
# - docs/agents.md <- project/.wiki/documentation.md "## Agents"
|
|
31
|
+
# - docs/hooks.md <- project/.wiki/documentation.md "## Hooks"
|
|
32
|
+
# - docs/mcp-tools.md <- project/.wiki/documentation.md "## MCP Tools"
|
|
33
|
+
# - docs/reference.md <- project/.wiki/documentation.md
|
|
34
|
+
# "## Directory Structure" +
|
|
35
|
+
# "## Agent Communication Contract"
|
|
36
|
+
# (plus a short hand-authored index blurb
|
|
37
|
+
# linking to skills/agents/hooks/mcp-tools)
|
|
38
|
+
#
|
|
39
|
+
# KNOWN LIMITATION: this is a structural transform, not a fact-checker. It
|
|
40
|
+
# ports project/.wiki/documentation.md's content as-is, including whatever
|
|
41
|
+
# is currently stale in that file (e.g. it documents ~30 skills under the
|
|
42
|
+
# old bare `/<name>` invocation form and does not yet list every skill in
|
|
43
|
+
# skills/, including the `j-<name>` twins — a pre-existing wiki staleness
|
|
44
|
+
# gap, not something introduced by this script). Fixing the wiki's own
|
|
45
|
+
# staleness is doc-sync's job, not this script's — this script only keeps
|
|
46
|
+
# the Pages site faithful to whatever the wiki currently says.
|
|
47
|
+
#
|
|
48
|
+
# HEADING-STABILITY ASSUMPTION: section extraction below is keyed to exact
|
|
49
|
+
# top-level ("## ") heading text in documentation.md (Agents, Skills, MCP
|
|
50
|
+
# Tools, Hooks, Directory Structure, Agent Communication Contract). If any
|
|
51
|
+
# of those headings are renamed, update the `case` statement in
|
|
52
|
+
# extract_sections() to match.
|
|
53
|
+
#
|
|
54
|
+
# Usage: scripts/build-pages-site.sh
|
|
55
|
+
# Safe to re-run any number of times — every run fully overwrites its
|
|
56
|
+
# output files from the current wiki content (no partial/incremental state).
|
|
57
|
+
|
|
58
|
+
set -euo pipefail
|
|
59
|
+
|
|
60
|
+
# shellcheck source=lib/resolve-project-dir.sh disable=SC1091
|
|
61
|
+
source "$(git rev-parse --show-toplevel)/lib/resolve-project-dir.sh"
|
|
62
|
+
|
|
63
|
+
REPO_ROOT="$JENGA_PROJECT_DIR"
|
|
64
|
+
WIKI_DIR="$REPO_ROOT/project/.wiki"
|
|
65
|
+
DOCS_DIR="$REPO_ROOT/docs"
|
|
66
|
+
DOC_MD="$WIKI_DIR/documentation.md"
|
|
67
|
+
INTRO_MD="$WIKI_DIR/intro-guide.md"
|
|
68
|
+
CONCEPTS_DIR="$WIKI_DIR/concepts"
|
|
69
|
+
|
|
70
|
+
for f in "$DOC_MD" "$INTRO_MD"; do
|
|
71
|
+
if [ ! -f "$f" ]; then
|
|
72
|
+
echo "build-pages-site.sh: required source file not found: $f" >&2
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
done
|
|
76
|
+
if [ ! -d "$CONCEPTS_DIR" ]; then
|
|
77
|
+
echo "build-pages-site.sh: required source directory not found: $CONCEPTS_DIR" >&2
|
|
78
|
+
exit 1
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
WORK="$(mktemp -d)"
|
|
82
|
+
trap 'rm -rf "$WORK"' EXIT
|
|
83
|
+
|
|
84
|
+
# --- 1. Split documentation.md into per-section scratch files -------------
|
|
85
|
+
# A line can only belong to one target section at a time; the generic
|
|
86
|
+
# "any other ## heading" rule resets `section` to "" so unrelated top-level
|
|
87
|
+
# sections (e.g. "## Table of Contents") are dropped rather than bleeding
|
|
88
|
+
# into whichever named section preceded them.
|
|
89
|
+
awk -v work="$WORK" '
|
|
90
|
+
/^## Agents$/ { section = "agents"; next }
|
|
91
|
+
/^## Skills$/ { section = "skills"; next }
|
|
92
|
+
/^## MCP Tools$/ { section = "mcp-tools"; next }
|
|
93
|
+
/^## Hooks$/ { section = "hooks"; next }
|
|
94
|
+
/^## Directory Structure$/ { section = "directory-structure"; next }
|
|
95
|
+
/^## Agent Communication Contract$/ { section = "contract"; next }
|
|
96
|
+
/^## / { section = "" }
|
|
97
|
+
{
|
|
98
|
+
if (section != "") {
|
|
99
|
+
print >> (work "/section-" section ".md")
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
' "$DOC_MD"
|
|
103
|
+
|
|
104
|
+
for s in agents skills mcp-tools hooks directory-structure contract; do
|
|
105
|
+
[ -f "$WORK/section-$s.md" ] || touch "$WORK/section-$s.md"
|
|
106
|
+
done
|
|
107
|
+
|
|
108
|
+
write_page() {
|
|
109
|
+
# write_page <output-path> <title> <permalink> <body-file>
|
|
110
|
+
local out="$1" title="$2" permalink="$3" body="$4"
|
|
111
|
+
{
|
|
112
|
+
printf -- '---\n'
|
|
113
|
+
printf 'layout: page\n'
|
|
114
|
+
printf 'title: %s\n' "$title"
|
|
115
|
+
printf 'permalink: %s\n' "$permalink"
|
|
116
|
+
printf -- '---\n\n'
|
|
117
|
+
cat "$body"
|
|
118
|
+
} > "$out"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# --- 2. docs/agents.md, docs/hooks.md, docs/mcp-tools.md -------------------
|
|
122
|
+
# Straight ports — no internal markdown links were found in these sections
|
|
123
|
+
# of documentation.md, so no link rewriting is needed beyond the front
|
|
124
|
+
# matter wrapper.
|
|
125
|
+
write_page "$DOCS_DIR/agents.md" "Agents" "/agents.html" "$WORK/section-agents.md"
|
|
126
|
+
write_page "$DOCS_DIR/hooks.md" "Hooks" "/hooks.html" "$WORK/section-hooks.md"
|
|
127
|
+
write_page "$DOCS_DIR/mcp-tools.md" "MCP Tools" "/mcp-tools.html" "$WORK/section-mcp-tools.md"
|
|
128
|
+
|
|
129
|
+
# --- 3. docs/skills.md ------------------------------------------------------
|
|
130
|
+
# Single reference page (matches the story's own suggested top-level
|
|
131
|
+
# category list: Getting Started / Concepts / Skills reference / Agents /
|
|
132
|
+
# Hooks / MCP Tools — "Skills reference" is one page, not one page per
|
|
133
|
+
# skill). Category (### ) and per-skill (#### ) structure is preserved
|
|
134
|
+
# as-is from the source.
|
|
135
|
+
write_page "$DOCS_DIR/skills.md" "Skills Reference" "/skills.html" "$WORK/section-skills.md"
|
|
136
|
+
|
|
137
|
+
# --- 4. docs/reference.md ---------------------------------------------------
|
|
138
|
+
# Combines the two remaining documentation.md sections (Directory Structure,
|
|
139
|
+
# Agent Communication Contract) behind a short hand-authored index blurb
|
|
140
|
+
# that links out to the pages built above — this replaces documentation.md's
|
|
141
|
+
# original role as the single "full reference" entry point, now that its
|
|
142
|
+
# content is split across multiple pages.
|
|
143
|
+
{
|
|
144
|
+
cat <<'EOF'
|
|
145
|
+
## Full Reference Index
|
|
146
|
+
|
|
147
|
+
This page is the entry point into the full reference material, split across
|
|
148
|
+
several pages so nothing requires scrolling through one giant file:
|
|
149
|
+
|
|
150
|
+
- **[Skills Reference](./skills.md)** — every skill, grouped by Setup &
|
|
151
|
+
Planning, Execution, Status & Review, and Committing & Maintenance.
|
|
152
|
+
- **[Agents](./agents.md)** — Scrum Master, Developer, Tester: roles,
|
|
153
|
+
ownership, and responsibilities.
|
|
154
|
+
- **[Hooks](./hooks.md)** — session lifecycle hooks and what they run.
|
|
155
|
+
- **[MCP Tools](./mcp-tools.md)** — Model Context Protocol tools available
|
|
156
|
+
in a Claude Code session.
|
|
157
|
+
|
|
158
|
+
The rest of this page covers the repo's directory structure and the
|
|
159
|
+
inter-agent communication contract (the typed "sender object" every agent
|
|
160
|
+
call carries).
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
EOF
|
|
165
|
+
cat "$WORK/section-directory-structure.md"
|
|
166
|
+
printf '\n---\n\n'
|
|
167
|
+
cat "$WORK/section-contract.md"
|
|
168
|
+
} > "$WORK/reference-body.md"
|
|
169
|
+
write_page "$DOCS_DIR/reference.md" "Reference" "/reference.html" "$WORK/reference-body.md"
|
|
170
|
+
|
|
171
|
+
# --- 5. docs/getting-started.md ---------------------------------------------
|
|
172
|
+
# Port of intro-guide.md verbatim (drop the leading H1 — front matter
|
|
173
|
+
# supplies the page title instead), with its two links into the
|
|
174
|
+
# now-restructured reference/concepts pages rewritten.
|
|
175
|
+
tail -n +2 "$INTRO_MD" > "$WORK/intro-body.md"
|
|
176
|
+
# NOTE on delimiter choice: sed's `s<delim>pattern<delim>replacement<delim>`
|
|
177
|
+
# breaks if the replacement text itself contains the delimiter character.
|
|
178
|
+
# Several replacements below contain a literal "#" (anchor fragments), so
|
|
179
|
+
# "#" cannot be used as the delimiter here — "|" is used instead, since
|
|
180
|
+
# none of these paths/anchors contain a literal "|".
|
|
181
|
+
sed -i.bak \
|
|
182
|
+
-e 's|\[documentation\.md\](\./documentation\.md)|[reference.md](./reference.md)|g' \
|
|
183
|
+
-e 's|(\./concepts/role-separation\.md)|(./concepts.md#role-separation)|g' \
|
|
184
|
+
-e 's|(\./concepts/board-hierarchy\.md)|(./concepts.md#board-hierarchy)|g' \
|
|
185
|
+
-e 's|(\./concepts/session-continuity\.md)|(./concepts.md#session-continuity)|g' \
|
|
186
|
+
-e 's|(\./concepts/first-feature\.md)|(./concepts.md#your-first-feature)|g' \
|
|
187
|
+
-e 's|(\./concepts/multi-session-work\.md)|(./concepts.md#working-across-sessions)|g' \
|
|
188
|
+
-e 's|(\./concepts/mid-flow-capture\.md)|(./concepts.md#capturing-mid-flow-ideas)|g' \
|
|
189
|
+
-e 's|(\./concepts/parallel-tasks\.md)|(./concepts.md#parallel-tasks)|g' \
|
|
190
|
+
"$WORK/intro-body.md"
|
|
191
|
+
rm -f "$WORK/intro-body.md.bak"
|
|
192
|
+
write_page "$DOCS_DIR/getting-started.md" "Getting Started" "/getting-started.html" "$WORK/intro-body.md"
|
|
193
|
+
|
|
194
|
+
# --- 6. docs/concepts.md -----------------------------------------------------
|
|
195
|
+
# Concatenates all 7 project/.wiki/concepts/*.md files into one page:
|
|
196
|
+
# - each file's H1 becomes an H2 section heading (slug listed below must
|
|
197
|
+
# stay in sync with each file's actual title text — GitHub Pages/kramdown
|
|
198
|
+
# slugifies headings to lowercase-hyphenated automatically)
|
|
199
|
+
# - all other headings are demoted one level (## -> ###, ### -> ####)
|
|
200
|
+
# - sibling/parent links are rewritten to point within the merged page
|
|
201
|
+
# and at the sibling getting-started.md / reference.md pages
|
|
202
|
+
#
|
|
203
|
+
{
|
|
204
|
+
cat <<'EOF'
|
|
205
|
+
## Concepts
|
|
206
|
+
|
|
207
|
+
The ideas behind Jenga AI's structure, and the how-tos for using it day to
|
|
208
|
+
day. Jump to any section:
|
|
209
|
+
|
|
210
|
+
- [Role Separation](#role-separation)
|
|
211
|
+
- [Board Hierarchy](#board-hierarchy)
|
|
212
|
+
- [Session Continuity](#session-continuity)
|
|
213
|
+
- [Your First Feature](#your-first-feature)
|
|
214
|
+
- [Working Across Sessions](#working-across-sessions)
|
|
215
|
+
- [Capturing Mid-Flow Ideas](#capturing-mid-flow-ideas)
|
|
216
|
+
- [Parallel Tasks](#parallel-tasks)
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
EOF
|
|
221
|
+
} > "$WORK/concepts-body.md"
|
|
222
|
+
|
|
223
|
+
append_concept() {
|
|
224
|
+
# append_concept <filename-stem> <section-title>
|
|
225
|
+
local stem="$1"
|
|
226
|
+
local title="$2"
|
|
227
|
+
local src="$CONCEPTS_DIR/$stem.md"
|
|
228
|
+
{
|
|
229
|
+
printf '## %s\n\n' "$title"
|
|
230
|
+
# NOTE on delimiter choice: same reasoning as the getting-started block
|
|
231
|
+
# above — replacements here contain a literal "#" anchor character, so
|
|
232
|
+
# "|" is used as the sed delimiter instead of "#".
|
|
233
|
+
#
|
|
234
|
+
# NOTE on heading demotion: a naive two-pass "## -> ###" then
|
|
235
|
+
# "### -> ####" sed would double-demote lines that were originally
|
|
236
|
+
# "## " (they'd match the first rule, becoming "### ", and then ALSO
|
|
237
|
+
# match the second rule on the same pass, becoming "#### " — wrong).
|
|
238
|
+
# The single extended-regex rule below captures the existing run of
|
|
239
|
+
# 2-3 "#" characters and prepends exactly one more, so each line is
|
|
240
|
+
# demoted exactly once regardless of its original level.
|
|
241
|
+
tail -n +2 "$src" \
|
|
242
|
+
| sed \
|
|
243
|
+
-e 's|\[documentation\.md\](\.\./documentation\.md)|[reference.md](./reference.md)|g' \
|
|
244
|
+
-e 's|(\.\./intro-guide\.md)|(./getting-started.md)|g' \
|
|
245
|
+
-e 's|(\.\./documentation\.md)|(./reference.md)|g' \
|
|
246
|
+
-e 's|(\./role-separation\.md)|(#role-separation)|g' \
|
|
247
|
+
-e 's|(\./board-hierarchy\.md)|(#board-hierarchy)|g' \
|
|
248
|
+
-e 's|(\./session-continuity\.md)|(#session-continuity)|g' \
|
|
249
|
+
-e 's|(\./first-feature\.md)|(#your-first-feature)|g' \
|
|
250
|
+
-e 's|(\./multi-session-work\.md)|(#working-across-sessions)|g' \
|
|
251
|
+
-e 's|(\./mid-flow-capture\.md)|(#capturing-mid-flow-ideas)|g' \
|
|
252
|
+
-e 's|(\./parallel-tasks\.md)|(#parallel-tasks)|g' \
|
|
253
|
+
| sed -E 's/^(#{2,3}) /#\1 /'
|
|
254
|
+
printf '\n---\n\n'
|
|
255
|
+
} >> "$WORK/concepts-body.md"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
append_concept "role-separation" "Role Separation"
|
|
259
|
+
append_concept "board-hierarchy" "Board Hierarchy"
|
|
260
|
+
append_concept "session-continuity" "Session Continuity"
|
|
261
|
+
append_concept "first-feature" "Your First Feature"
|
|
262
|
+
append_concept "multi-session-work" "Working Across Sessions"
|
|
263
|
+
append_concept "mid-flow-capture" "Capturing Mid-Flow Ideas"
|
|
264
|
+
append_concept "parallel-tasks" "Parallel Tasks"
|
|
265
|
+
|
|
266
|
+
write_page "$DOCS_DIR/concepts.md" "Concepts" "/concepts.html" "$WORK/concepts-body.md"
|
|
267
|
+
|
|
268
|
+
echo "build-pages-site.sh: regenerated docs/{getting-started,concepts,skills,agents,hooks,mcp-tools,reference}.md from project/.wiki/*"
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# scripts/check-public-playbook-steps.sh — every public playbook's steps must ship publicly
|
|
4
|
+
#
|
|
5
|
+
# E50_S20_T01. Guards the invariant that a playbook shipped to the public mirror can actually
|
|
6
|
+
# run there: for each playbook JSON that `.publicignore` does NOT block, every step must resolve
|
|
7
|
+
# to a skill directory that `.publicignore` also does not block.
|
|
8
|
+
#
|
|
9
|
+
# Why this exists: `skills/jenga/scripts/load-playbooks.sh` requires every step's
|
|
10
|
+
# `skills/<dir>/SKILL.md` to exist, and silently SKIPS the whole playbook (stderr warning only)
|
|
11
|
+
# when one is missing. In the private repo every skill is present, so a playbook referencing a
|
|
12
|
+
# private-only skill looks perfectly healthy — the breakage appears only in the public mirror,
|
|
13
|
+
# where it surfaced as a stage-deploy gate failure rather than as a test failure (E50_S13).
|
|
14
|
+
# This check reproduces that condition statically, on the private side, before anything ships.
|
|
15
|
+
#
|
|
16
|
+
# Blocklist semantics are NOT re-derived here. Classification is delegated to
|
|
17
|
+
# scripts/check-publicignore-match.sh, which itself reuses /mirror-public's own
|
|
18
|
+
# `rsync --exclude-from=.publicignore` matching — a second, hand-rolled answer to "is this path
|
|
19
|
+
# blocked" is exactly the drift this repo has been bitten by before.
|
|
20
|
+
#
|
|
21
|
+
# Composed steps: a StepObject of the form {"playbook": "<id>"} composes another playbook. Its
|
|
22
|
+
# own steps are checked when that playbook is itself public; a public playbook composing a
|
|
23
|
+
# BLOCKED playbook is a violation in its own right, since the composed id will not resolve in
|
|
24
|
+
# the mirror (see tests/load-playbooks-composition.bats's nonexistent-playbook-id behaviour).
|
|
25
|
+
#
|
|
26
|
+
# Usage:
|
|
27
|
+
# scripts/check-public-playbook-steps.sh [<repo-root>]
|
|
28
|
+
#
|
|
29
|
+
# Exit codes:
|
|
30
|
+
# 0 every public playbook's every step (and composed playbook) is public
|
|
31
|
+
# 1 at least one violation — each is named on stdout
|
|
32
|
+
# 2 usage / environment error (bad root, missing helper, unparseable playbook)
|
|
33
|
+
|
|
34
|
+
set -euo pipefail
|
|
35
|
+
|
|
36
|
+
REPO_ROOT="${1:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"
|
|
37
|
+
|
|
38
|
+
if [ ! -d "$REPO_ROOT" ]; then
|
|
39
|
+
echo "check-public-playbook-steps.sh: error: not a directory: $REPO_ROOT" >&2
|
|
40
|
+
exit 2
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
PLAYBOOKS_DIR="$REPO_ROOT/skills/jenga/playbooks"
|
|
44
|
+
MATCHER="$REPO_ROOT/scripts/check-publicignore-match.sh"
|
|
45
|
+
|
|
46
|
+
if [ ! -f "$REPO_ROOT/.publicignore" ]; then
|
|
47
|
+
echo "check-public-playbook-steps.sh: no .publicignore at $REPO_ROOT — nothing to enforce, skipping"
|
|
48
|
+
exit 0
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if [ ! -f "$MATCHER" ]; then
|
|
52
|
+
echo "check-public-playbook-steps.sh: error: missing $MATCHER (the single source of blocklist semantics)" >&2
|
|
53
|
+
exit 2
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
if [ ! -d "$PLAYBOOKS_DIR" ]; then
|
|
57
|
+
echo "check-public-playbook-steps.sh: no playbooks directory at $PLAYBOOKS_DIR — nothing to check"
|
|
58
|
+
exit 0
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# classify <path-relative-to-repo-root> -> echoes PUBLIC or BLOCKED
|
|
62
|
+
classify() {
|
|
63
|
+
bash "$MATCHER" "$1" 2>/dev/null | head -1 | cut -f1
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
violations=0
|
|
67
|
+
checked=0
|
|
68
|
+
skipped_private=0
|
|
69
|
+
|
|
70
|
+
for pb in "$PLAYBOOKS_DIR"/*.json; do
|
|
71
|
+
[ -f "$pb" ] || continue
|
|
72
|
+
base="$(basename "$pb")"
|
|
73
|
+
# schema.json describes playbooks, it is not one.
|
|
74
|
+
[ "$base" = "schema.json" ] && continue
|
|
75
|
+
|
|
76
|
+
rel="skills/jenga/playbooks/$base"
|
|
77
|
+
if [ "$(classify "$rel")" = "BLOCKED" ]; then
|
|
78
|
+
skipped_private=$((skipped_private + 1))
|
|
79
|
+
continue
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
checked=$((checked + 1))
|
|
83
|
+
|
|
84
|
+
# Emit one "<kind>\t<value>" line per step. A bare string and {"skill": ...} are both skills;
|
|
85
|
+
# {"playbook": ...} is a composition.
|
|
86
|
+
steps="$(python3 -c '
|
|
87
|
+
import json, sys
|
|
88
|
+
with open(sys.argv[1]) as fh:
|
|
89
|
+
pb = json.load(fh)
|
|
90
|
+
for s in pb.get("steps", []):
|
|
91
|
+
if isinstance(s, str):
|
|
92
|
+
print("skill\t" + s)
|
|
93
|
+
elif isinstance(s, dict):
|
|
94
|
+
if "skill" in s:
|
|
95
|
+
print("skill\t" + str(s["skill"]))
|
|
96
|
+
elif "playbook" in s:
|
|
97
|
+
print("playbook\t" + str(s["playbook"]))
|
|
98
|
+
' "$pb")" || {
|
|
99
|
+
echo "check-public-playbook-steps.sh: error: could not parse $rel" >&2
|
|
100
|
+
exit 2
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
while IFS=$'\t' read -r kind value; do
|
|
104
|
+
[ -n "${kind:-}" ] || continue
|
|
105
|
+
case "$kind" in
|
|
106
|
+
skill)
|
|
107
|
+
target="skills/$value/SKILL.md"
|
|
108
|
+
if [ ! -f "$REPO_ROOT/$target" ]; then
|
|
109
|
+
echo "VIOLATION $rel -> step '$value': no $target on disk"
|
|
110
|
+
violations=$((violations + 1))
|
|
111
|
+
elif [ "$(classify "$target")" = "BLOCKED" ]; then
|
|
112
|
+
echo "VIOLATION $rel -> step '$value': $target is blocklisted, so this public playbook cannot load in the mirror"
|
|
113
|
+
violations=$((violations + 1))
|
|
114
|
+
fi
|
|
115
|
+
;;
|
|
116
|
+
playbook)
|
|
117
|
+
target="skills/jenga/playbooks/$value.json"
|
|
118
|
+
if [ ! -f "$REPO_ROOT/$target" ]; then
|
|
119
|
+
echo "VIOLATION $rel -> composes '$value': no $target on disk"
|
|
120
|
+
violations=$((violations + 1))
|
|
121
|
+
elif [ "$(classify "$target")" = "BLOCKED" ]; then
|
|
122
|
+
echo "VIOLATION $rel -> composes '$value': $target is blocklisted, so the composed id will not resolve in the mirror"
|
|
123
|
+
violations=$((violations + 1))
|
|
124
|
+
fi
|
|
125
|
+
;;
|
|
126
|
+
esac
|
|
127
|
+
done <<< "$steps"
|
|
128
|
+
done
|
|
129
|
+
|
|
130
|
+
if [ "$violations" -gt 0 ]; then
|
|
131
|
+
echo "check-public-playbook-steps.sh: $violations violation(s) across $checked public playbook(s) ($skipped_private private playbook(s) not checked)"
|
|
132
|
+
exit 1
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
echo "check-public-playbook-steps.sh: OK — $checked public playbook(s) checked, every step ships publicly ($skipped_private private playbook(s) skipped)"
|
|
136
|
+
exit 0
|
|
@@ -129,7 +129,7 @@ For **each task ID** listed in the story's `tasks:` frontmatter array:
|
|
|
129
129
|
```bash
|
|
130
130
|
bash skills/j-close-story/scripts/check-privatized.sh <task-id> "project/board/tasks/<task-id>_*.md"
|
|
131
131
|
```
|
|
132
|
-
This is a **static** check (per
|
|
132
|
+
This is a **static** check (per `$([ -f templates/SCRUM_BOARD_SCHEMA.md ] && echo templates/SCRUM_BOARD_SCHEMA.md || echo node_modules/@jenga-ai/agent/templates/SCRUM_BOARD_SCHEMA.md)`'s "Static
|
|
133
133
|
vs. Reactive Status Setting" section) — it derives the task's touched-file
|
|
134
134
|
list from its own EST-tagged commit history (same technique as Step 2) and
|
|
135
135
|
tests every file against `.publicignore`, with **no dependency on any
|
package/skills/j-do/SKILL.md
CHANGED
|
@@ -58,7 +58,7 @@ Extract the following named values for use throughout this skill:
|
|
|
58
58
|
These values must be read fresh on each invocation. Never use hardcoded fallbacks.
|
|
59
59
|
|
|
60
60
|
### 1. Check for `project/todo.md`
|
|
61
|
-
Run `bash scripts/todo_manager.sh exists`. If it exits non-zero, inform the user there are no queued tasks and exit.
|
|
61
|
+
Run `bash "$([ -f scripts/todo_manager.sh ] && echo scripts/todo_manager.sh || echo node_modules/@jenga-ai/agent/scripts/todo_manager.sh)" exists`. If it exits non-zero, inform the user there are no queued tasks and exit.
|
|
62
62
|
|
|
63
63
|
### 1.5. Story-Bundle Execution Mode
|
|
64
64
|
|
|
@@ -284,7 +284,7 @@ No patch file is written on success.
|
|
|
284
284
|
If `/do` is invoked with a task ID (`E##_S##_T##`) or a plain-text title, skip this section and use the normal task execution path (steps 2–8 below).
|
|
285
285
|
|
|
286
286
|
### 2. List tasks and let the user choose
|
|
287
|
-
Run `bash scripts/todo_manager.sh list` to display the queued tasks. Ask the user:
|
|
287
|
+
Run `bash "$([ -f scripts/todo_manager.sh ] && echo scripts/todo_manager.sh || echo node_modules/@jenga-ai/agent/scripts/todo_manager.sh)" list` to display the queued tasks. Ask the user:
|
|
288
288
|
- Execute a specific task (by number or title)
|
|
289
289
|
- Execute the next task from the top of the list
|
|
290
290
|
- Exit
|
|
@@ -294,14 +294,14 @@ Run `bash scripts/todo_manager.sh list` to display the queued tasks. Ask the use
|
|
|
294
294
|
Before resolving a task for execution, inspect the selected entry's ID:
|
|
295
295
|
|
|
296
296
|
- **Epic (`E##`)** — the entry refers to a whole epic that has not yet been broken into stories.
|
|
297
|
-
Use the scrum-master agent to read the epic's board file (`$(bash scripts/board_resolver.sh)epics/`) and decompose it into stories. For each story produced:
|
|
298
|
-
1. Write a story file to `$(bash scripts/board_resolver.sh)stories/`.
|
|
299
|
-
2. Run `bash scripts/todo_manager.sh add '<story title>: <E##_S##>'`
|
|
300
|
-
After breakdown, Run `bash scripts/todo_manager.sh remove '<epic entry title>'` and go back to step 2 so the new stories are visible.
|
|
297
|
+
Use the scrum-master agent to read the epic's board file (`$(bash "$([ -f scripts/board_resolver.sh ] && echo scripts/board_resolver.sh || echo node_modules/@jenga-ai/agent/scripts/board_resolver.sh)")epics/`) and decompose it into stories. For each story produced:
|
|
298
|
+
1. Write a story file to `$(bash "$([ -f scripts/board_resolver.sh ] && echo scripts/board_resolver.sh || echo node_modules/@jenga-ai/agent/scripts/board_resolver.sh)")stories/`.
|
|
299
|
+
2. Run `bash "$([ -f scripts/todo_manager.sh ] && echo scripts/todo_manager.sh || echo node_modules/@jenga-ai/agent/scripts/todo_manager.sh)" add '<story title>: <E##_S##>'`
|
|
300
|
+
After breakdown, Run `bash "$([ -f scripts/todo_manager.sh ] && echo scripts/todo_manager.sh || echo node_modules/@jenga-ai/agent/scripts/todo_manager.sh)" remove '<epic entry title>'` and go back to step 2 so the new stories are visible.
|
|
301
301
|
|
|
302
302
|
- **Story (`E##_S##`) with no tasks** — the entry refers to a story that has not yet been broken into tasks.
|
|
303
|
-
Check `$(bash scripts/board_resolver.sh)tasks/` for any task files whose front-matter `story_id` matches this story. If none exist, use the scrum-master agent to read the story's board file and decompose it into tasks. For each task produced:
|
|
304
|
-
1. Write a task file to `$(bash scripts/board_resolver.sh)tasks/`.
|
|
303
|
+
Check `$(bash "$([ -f scripts/board_resolver.sh ] && echo scripts/board_resolver.sh || echo node_modules/@jenga-ai/agent/scripts/board_resolver.sh)")tasks/` for any task files whose front-matter `story_id` matches this story. If none exist, use the scrum-master agent to read the story's board file and decompose it into tasks. For each task produced:
|
|
304
|
+
1. Write a task file to `$(bash "$([ -f scripts/board_resolver.sh ] && echo scripts/board_resolver.sh || echo node_modules/@jenga-ai/agent/scripts/board_resolver.sh)")tasks/`.
|
|
305
305
|
After breakdown, keep the story entry in `project/todo.md` (tasks are discovered from it automatically). Go back to step 2.
|
|
306
306
|
|
|
307
307
|
- **Story (`E##_S##`) with existing tasks**, or **Task (`E##_S##_T##`)** — no breakdown needed; proceed to step 4.
|
|
@@ -310,7 +310,7 @@ Before resolving a task for execution, inspect the selected entry's ID:
|
|
|
310
310
|
Each todo entry uses the format: `<mission title>: <E##_S##_T##>` (or `E##_S##` if no task ID).
|
|
311
311
|
|
|
312
312
|
Before starting:
|
|
313
|
-
1. Locate and read the matching file from `$(bash scripts/board_resolver.sh)tasks/` (or `$(bash scripts/board_resolver.sh)stories/` if story-level)
|
|
313
|
+
1. Locate and read the matching file from `$(bash "$([ -f scripts/board_resolver.sh ] && echo scripts/board_resolver.sh || echo node_modules/@jenga-ai/agent/scripts/board_resolver.sh)")tasks/` (or `$(bash "$([ -f scripts/board_resolver.sh ] && echo scripts/board_resolver.sh || echo node_modules/@jenga-ai/agent/scripts/board_resolver.sh)")stories/` if story-level)
|
|
314
314
|
2. If the file does not exist, warn the user and skip — do not proceed with a task that has no scrum board definition
|
|
315
315
|
3. Present a brief summary of the task: title, acceptance criteria, parent story, parent epic
|
|
316
316
|
|
|
@@ -343,7 +343,7 @@ After override validation (step 4.1) and before branching on `execution_scope` i
|
|
|
343
343
|
|
|
344
344
|
3. **Overwrite `execution_scope` to `inline`** in the task's frontmatter, unconditionally — `--trivial` always forces `inline`, never a softer "lightest safe tier."
|
|
345
345
|
|
|
346
|
-
4. **Record the override for audit**, reusing the existing `jenga_assigned` / `override_justification` pairing already defined in
|
|
346
|
+
4. **Record the override for audit**, reusing the existing `jenga_assigned` / `override_justification` pairing already defined in `$([ -f templates/SCRUM_BOARD_SCHEMA.md ] && echo templates/SCRUM_BOARD_SCHEMA.md || echo node_modules/@jenga-ai/agent/templates/SCRUM_BOARD_SCHEMA.md)` for exactly this situation ("scope overridden by a human"), rather than inventing a new field:
|
|
347
347
|
- Set `jenga_assigned: false` (if not already `false`).
|
|
348
348
|
- Set (or append to, if already present) `override_justification`:
|
|
349
349
|
```
|
|
@@ -368,7 +368,7 @@ After override validation (step 4.1) and before branching on `execution_scope` i
|
|
|
368
368
|
|
|
369
369
|
After resolving the task context (step 4), passing override validation (step 4.1), and applying the `--trivial` dispatch-time override if present (step 4.1.5), read `execution_scope` from the task frontmatter.
|
|
370
370
|
|
|
371
|
-
**Locked-task dispatch guard (defense-in-depth).** Before branching on `execution_scope` below, read `crucial_level` from the task frontmatter (per
|
|
371
|
+
**Locked-task dispatch guard (defense-in-depth).** Before branching on `execution_scope` below, read `crucial_level` from the task frontmatter (per `$([ -f templates/SCRUM_BOARD_SCHEMA.md ] && echo templates/SCRUM_BOARD_SCHEMA.md || echo node_modules/@jenga-ai/agent/templates/SCRUM_BOARD_SCHEMA.md)`'s Crucial Flag Fields). If `crucial_level: locked`:
|
|
372
372
|
|
|
373
373
|
- This task MUST be routed through the inline execution path below — no worktree, no developer subagent — regardless of what `execution_scope` currently reads. This guards against a locked task reaching dispatch with a non-`inline` `execution_scope` (a race, a manually edited file, or a task added to a story's `tasks:` list after `skills/jenga/SKILL.md` Phase 0.5's Rule 4 last ran).
|
|
374
374
|
- If `execution_scope` is already `inline`, proceed directly to the inline steps below — no correction needed.
|
|
@@ -389,10 +389,10 @@ After resolving the task context (step 4), passing override validation (step 4.1
|
|
|
389
389
|
1. Read the task file and load its full content (description, acceptance criteria). Do NOT create a worktree. Do NOT spawn a developer subagent.
|
|
390
390
|
2. Implement the task inline — make the required changes to files directly in the current session.
|
|
391
391
|
3. Run the smoke test harness before committing anything:
|
|
392
|
-
- Run `bash scripts/smoke-harness.sh <changed_file>...`, passing the paths changed in step 2. With no arguments the harness infers them from `git diff --name-only HEAD`. It exits `0` on pass and `1` on failure.
|
|
393
|
-
- If `scripts/smoke-harness.sh`
|
|
392
|
+
- Run `bash "$([ -f scripts/smoke-harness.sh ] && echo scripts/smoke-harness.sh || echo node_modules/@jenga-ai/agent/scripts/smoke-harness.sh)" <changed_file>...`, passing the paths changed in step 2. With no arguments the harness infers them from `git diff --name-only HEAD`. It exits `0` on pass and `1` on failure.
|
|
393
|
+
- If neither `scripts/smoke-harness.sh` nor `node_modules/@jenga-ai/agent/scripts/smoke-harness.sh` exists, log a warning and treat the result as a pass:
|
|
394
394
|
```
|
|
395
|
-
WARNING [<task_id>]:
|
|
395
|
+
WARNING [<task_id>]: smoke-harness.sh not found. Smoke test skipped (stub pass).
|
|
396
396
|
```
|
|
397
397
|
4. **If the smoke test exits non-zero**:
|
|
398
398
|
- **If this is a `--trivial`-forced run** (marker set in step 4.1.5 — and `crucial_level` is not `locked`, which never falls back, per 4.1.5's precedence note): do NOT write `status: Failed`. `--trivial` always forces `inline` with no softer "lightest safe tier" to fall back to first, so a smoke-harness failure here goes straight to the shared `#### Fallback to Full Task-Scope Pipeline` procedure below (origin: `trivial`). Do not proceed with the remaining inline steps below — the Fallback procedure takes over from here.
|
|
@@ -431,10 +431,10 @@ After resolving the task context (step 4), passing override validation (step 4.1
|
|
|
431
431
|
1. **Spawn a developer subagent** (Agent tool, `subagent_type: "developer"`) with the same sender object and context payload as step 5 would use, but with an explicit instruction added to the dispatch prompt: **do not create a worktree** — implement directly against the current checkout (the session's existing working tree), not an isolated `.claude/worktrees/<slug>` copy. This is the one concrete difference from the step-5 `task` path: everything else about how the subagent implements the task (reading the task file, following acceptance criteria, following repo conventions) is unchanged.
|
|
432
432
|
|
|
433
433
|
2. **After the developer subagent reports implementation complete**, run the smoke test harness using the same invocation convention as `### 4.2. Inline Execution Path`:
|
|
434
|
-
- Run `bash scripts/smoke-harness.sh <changed_file>...`, passing the paths the subagent changed. With no arguments the harness infers them from `git diff --name-only HEAD`. It exits `0` on pass and `1` on failure.
|
|
435
|
-
- If `scripts/smoke-harness.sh`
|
|
434
|
+
- Run `bash "$([ -f scripts/smoke-harness.sh ] && echo scripts/smoke-harness.sh || echo node_modules/@jenga-ai/agent/scripts/smoke-harness.sh)" <changed_file>...`, passing the paths the subagent changed. With no arguments the harness infers them from `git diff --name-only HEAD`. It exits `0` on pass and `1` on failure.
|
|
435
|
+
- If neither `scripts/smoke-harness.sh` nor `node_modules/@jenga-ai/agent/scripts/smoke-harness.sh` exists, log a warning and treat the result as a pass:
|
|
436
436
|
```
|
|
437
|
-
WARNING [<task_id>]:
|
|
437
|
+
WARNING [<task_id>]: smoke-harness.sh not found. Smoke test skipped (stub pass).
|
|
438
438
|
```
|
|
439
439
|
|
|
440
440
|
3. **If the smoke test passes**:
|
|
@@ -528,8 +528,8 @@ Additionally, if the completed work introduces user-facing changes, update `READ
|
|
|
528
528
|
### 7. After successful completion
|
|
529
529
|
- Check for any `_INSTRUCTIONS.md` files in `project/instructions/` whose ID matches the completed task. If found, present them to the user and explain that these actions must be completed before the feature will work correctly.
|
|
530
530
|
- Invoke the `/commit` skill to commit the work (if not already committed by the developer)
|
|
531
|
-
- Run `bash scripts/todo_manager.sh remove '<task title>'` to remove the completed task from `project/todo.md`
|
|
532
|
-
- Run `bash scripts/todo_manager.sh teardown` to delete `project/todo.md` if it is now effectively empty
|
|
531
|
+
- Run `bash "$([ -f scripts/todo_manager.sh ] && echo scripts/todo_manager.sh || echo node_modules/@jenga-ai/agent/scripts/todo_manager.sh)" remove '<task title>'` to remove the completed task from `project/todo.md`
|
|
532
|
+
- Run `bash "$([ -f scripts/todo_manager.sh ] && echo scripts/todo_manager.sh || echo node_modules/@jenga-ai/agent/scripts/todo_manager.sh)" teardown` to delete `project/todo.md` if it is now effectively empty
|
|
533
533
|
|
|
534
534
|
### 8. Loop
|
|
535
535
|
Go back to step 1.
|
|
@@ -101,7 +101,7 @@ Every candidate identified above as "missing documentation for new things added
|
|
|
101
101
|
1. **Check for `.publicignore` at the repo root.** Most projects using this framework will not have one (they haven't adopted `/mirror-public`) — if it's absent, **skip this entire sub-step**. Fall through to flagging every "missing documentation" candidate exactly as `3.` above already would, with no further filtering.
|
|
102
102
|
2. **If `.publicignore` exists**, for each "missing documentation" candidate, determine its source path (relative to the repo root) and classify it by running:
|
|
103
103
|
```
|
|
104
|
-
scripts/check-publicignore-match.sh <path> [<path> ...]
|
|
104
|
+
bash "$([ -f scripts/check-publicignore-match.sh ] && echo scripts/check-publicignore-match.sh || echo node_modules/@jenga-ai/agent/scripts/check-publicignore-match.sh)" <path> [<path> ...]
|
|
105
105
|
```
|
|
106
106
|
This reuses `/mirror-public`'s own `mirror.sh` matching logic (`rsync --exclude-from=.publicignore`) — a file this script reports `BLOCKED` is guaranteed to be a file `/mirror-public --dry-run` would also report as "would be blocked", and vice versa for `PUBLIC`. It needs no network access and does not require `/mirror-public` to be configured.
|
|
107
107
|
3. **`BLOCKED`** → do not flag this candidate as missing documentation. It's private-only and will never ship to the public mirror, so public docs coverage is not applicable.
|
|
@@ -181,6 +181,17 @@ After all writes are done, print a summary:
|
|
|
181
181
|
If nothing needed updating, print: `✅ Documentation is already in sync with the source.`
|
|
182
182
|
If minification could not reach the target, note: `⚠️ docs/API.md reduced to X% (target was Y% — essential content limit reached).`
|
|
183
183
|
|
|
184
|
+
### 8. GitHub Pages site follow-up (E41_S13)
|
|
185
|
+
|
|
186
|
+
If this run updated `project/.wiki/documentation.md`, `project/.wiki/intro-guide.md`, or any
|
|
187
|
+
`project/.wiki/concepts/*.md` file, also re-run `bash "$([ -f scripts/build-pages-site.sh ] && echo scripts/build-pages-site.sh || echo node_modules/@jenga-ai/agent/scripts/build-pages-site.sh)"` afterward. That
|
|
188
|
+
script deterministically regenerates the GitHub Pages documentation site's wiki-derived pages
|
|
189
|
+
(`docs/getting-started.md`, `docs/concepts.md`, `docs/skills.md`, `docs/agents.md`,
|
|
190
|
+
`docs/hooks.md`, `docs/mcp-tools.md`, `docs/reference.md`) from the wiki content this step just
|
|
191
|
+
updated — without re-running it, the Pages site silently drifts from the wiki the same way
|
|
192
|
+
`README.md` and the wiki itself have drifted from each other before. Mention this in the
|
|
193
|
+
summary output (e.g. `🔄 Re-ran build-pages-site.sh to refresh the Pages site`).
|
|
194
|
+
|
|
184
195
|
---
|
|
185
196
|
|
|
186
197
|
## Reference files
|
package/skills/j-idea/SKILL.md
CHANGED
|
@@ -36,7 +36,7 @@ This file is generated/synced by `scripts/generate-j-alias.sh idea` from `skills
|
|
|
36
36
|
|
|
37
37
|
3. **Add to `project/ideas.md`** by running:
|
|
38
38
|
```
|
|
39
|
-
bash scripts/idea_manager.sh add '<idea>'
|
|
39
|
+
bash "$([ -f scripts/idea_manager.sh ] && echo scripts/idea_manager.sh || echo node_modules/@jenga-ai/agent/scripts/idea_manager.sh)" add '<idea>'
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
4. **Ask the user**: "Capture another idea, or done?"
|
package/skills/j-init/SKILL.md
CHANGED
|
@@ -144,10 +144,11 @@ This script handles all scaffolding in one step:
|
|
|
144
144
|
7. Creates `project/configs/scope-thresholds.json` with default execution-scope thresholds (consumed by `/jenga` and `/do`, which halt if it's missing)
|
|
145
145
|
8. Creates `project/data/baselines.json`
|
|
146
146
|
9. Creates `project/logs/events.json`
|
|
147
|
-
10. Creates `
|
|
148
|
-
11. Creates `
|
|
149
|
-
12.
|
|
150
|
-
13.
|
|
147
|
+
10. Creates `project/knowledge-graph/STUB_SCHEMA.md` from the shared template and `project/knowledge-graph/graph.json` seeded with empty `nodes`/`edges` arrays — consumed by `/uncharted`'s conversational elicitation flow
|
|
148
|
+
11. Creates `docs/STRATEGY.md` — a strategic brief stub intended for investors, partners, and the product team
|
|
149
|
+
12. Creates `CHANGELOG.md` from the shared template — a running log of notable changes, seeded with an `[Unreleased]` section
|
|
150
|
+
13. Applies the chosen visibility mode via `scripts/apply-project-visibility.sh`, which records it as `project_files_visibility` in `jenga.config.json` and performs any `.gitignore` change
|
|
151
|
+
14. Stages and commits all files with the message `init: scaffold project structure and workflow config`
|
|
151
152
|
|
|
152
153
|
The visibility mode is validated before any scaffolding happens, so an invalid
|
|
153
154
|
value fails fast and leaves nothing behind. It is applied before the commit, so
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# ---------------------------------------------------------------------------
|
|
3
|
-
# skills/init/scripts/detect-existing-codebase.sh
|
|
3
|
+
# skills/j-init/scripts/detect-existing-codebase.sh
|
|
4
4
|
#
|
|
5
5
|
# Deterministic front half of the /init "detect existing project state" step.
|
|
6
6
|
# /init currently always scaffolds as though the target directory were empty.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# This script answers exactly one question -- "what kind of directory is
|
|
13
13
|
# this?" -- and nothing else. It never scaffolds, never prompts, never runs
|
|
14
14
|
# /uncharted, and never modifies anything on disk. Deciding what to DO with
|
|
15
|
-
# the verdict is agent judgement and lives in skills/init/SKILL.md.
|
|
15
|
+
# the verdict is agent judgement and lives in skills/j-init/SKILL.md.
|
|
16
16
|
#
|
|
17
17
|
# ---------------------------------------------------------------------------
|
|
18
18
|
# VERDICTS -- exactly one is printed on stdout, nothing else
|
|
@@ -8,9 +8,9 @@ VISIBILITY_SCRIPT="$SCRIPT_DIR/apply-project-visibility.sh"
|
|
|
8
8
|
# ─── Resolve the package root that owns templates/ and lib/ ──────────────────
|
|
9
9
|
# postinstall.js mirrors only skills/ and agents/ into .claude/ and .agents/ —
|
|
10
10
|
# templates/ and lib/ are never copied there, so a script running from a
|
|
11
|
-
# mirrored copy (.claude/skills/init/scripts/ or .agents/skills/init/scripts/)
|
|
11
|
+
# mirrored copy (.claude/skills/j-init/scripts/ or .agents/skills/j-init/scripts/)
|
|
12
12
|
# cannot reach its siblings via a fixed ../../../ climb the way it can in this
|
|
13
|
-
# monorepo checkout, where init.sh actually lives at skills/init/scripts/ with
|
|
13
|
+
# monorepo checkout, where init.sh actually lives at skills/j-init/scripts/ with
|
|
14
14
|
# templates/ and lib/ three levels up. Consumers instead have them inside the
|
|
15
15
|
# installed npm package.
|
|
16
16
|
if [[ -d "$SCRIPT_DIR/../../../templates" ]]; then
|
|
@@ -81,6 +81,17 @@ echo '{}' > project/data/baselines.json
|
|
|
81
81
|
echo "→ Creating events.json..."
|
|
82
82
|
echo '[]' > project/logs/events.json
|
|
83
83
|
|
|
84
|
+
# ─── 8.5. Create project/knowledge-graph/{STUB_SCHEMA.md,graph.json} ─────────
|
|
85
|
+
# Consumed by skills/uncharted's conversational elicitation flow (`onboard`,
|
|
86
|
+
# `segment --mode investigate`), which writes coarse graph nodes/edges to
|
|
87
|
+
# graph.json per the stub schema — both must exist before that flow's first
|
|
88
|
+
# write, per templates/KNOWLEDGE_GRAPH_STUB_SCHEMA_TEMPLATE.md's own header
|
|
89
|
+
# comment (E20_S08_T01; replaced wholesale once E20_S01's real schema lands).
|
|
90
|
+
echo "→ Copying knowledge-graph STUB_SCHEMA.md from template..."
|
|
91
|
+
cp "$PKG_ROOT/templates/KNOWLEDGE_GRAPH_STUB_SCHEMA_TEMPLATE.md" project/knowledge-graph/STUB_SCHEMA.md
|
|
92
|
+
echo "→ Creating project/knowledge-graph/graph.json..."
|
|
93
|
+
echo '{"nodes": [], "edges": []}' > project/knowledge-graph/graph.json
|
|
94
|
+
|
|
84
95
|
# ─── 9. Create docs/STRATEGY.md ──────────────────────────────────────────────
|
|
85
96
|
echo "→ Creating docs/STRATEGY.md (strategic brief for investors, partners, and the product team)..."
|
|
86
97
|
mkdir -p docs
|