@jenga-ai/agent 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/agents/developer.md +82 -2
- package/agents/scrum-master.md +140 -21
- package/agents/tester.md +90 -8
- package/hooks/on_session_end.sh +171 -20
- package/package.json +1 -1
- package/scripts/check-permission-level.sh +107 -0
- package/scripts/check-publicignore-match.sh +122 -0
- package/scripts/check-worktree-liveness.sh +193 -0
- package/scripts/generate-rapport-manifest.sh +43 -0
- package/scripts/idea_manager.sh +47 -0
- package/scripts/install-worktree-commit-guard.sh +134 -0
- package/scripts/jenga-permission-level-switch.sh +109 -0
- package/scripts/smoke-harness.sh +139 -0
- package/scripts/validate-board.sh +62 -0
- package/scripts/with-lock.sh +158 -0
- package/scripts/worktree-remove-guard.sh +204 -0
- package/skills/clearify/SKILL.md +52 -0
- package/skills/commit/SKILL.md +13 -4
- package/skills/distribute/CONFIG_SCHEMA.md +60 -2
- package/skills/do/SKILL.md +48 -11
- package/skills/doc-sync/SKILL.md +16 -0
- package/skills/doc-sync/assets/doc_targets.md +11 -0
- package/skills/idea/SKILL.md +56 -0
- package/skills/idea/assets/idea_handoff_template.md +26 -0
- package/skills/idea/assets/idea_template.md +3 -0
- package/skills/init/SKILL.md +100 -7
- package/skills/init/assets/directory_structure.txt +1 -0
- package/skills/init/assets/workflow_template.json +1 -1
- package/skills/init/scripts/apply-project-visibility.sh +176 -0
- package/skills/init/scripts/detect-existing-codebase.sh +166 -0
- package/skills/init/scripts/init.sh +30 -1
- package/skills/jenga/SKILL.md +160 -17
- package/skills/jenga/scripts/board-scan.sh +238 -0
- package/skills/jenga/scripts/cascade-resolve.sh +297 -0
- package/skills/jenga/scripts/render-confirmation.sh +679 -0
- package/skills/jenga/scripts/render-picker.sh +439 -0
- package/skills/jenga/scripts/resolve-id.sh +367 -0
- package/skills/jenga-permission-level/SKILL.md +81 -0
- package/skills/proceed/SKILL.md +1 -1
- package/skills/publish/SKILL.md +8 -5
- package/skills/publish/assets/ci-contract.md +2 -2
- package/skills/publish/assets/ownership-matrix.md +1 -1
- package/skills/publish/scripts/finalize_changelog.sh +115 -0
- package/skills/publish/scripts/generate_release_notes.sh +475 -28
- package/skills/publish/scripts/npm_ci_pipeline.sh +44 -6
- package/skills/publish/scripts/publish_deploy.sh +38 -8
- package/skills/publish/scripts/run_gates.sh +2 -2
- package/skills/reconcile/SKILL.md +117 -5
- package/skills/reconcile/scripts/detect-unlinked-code.sh +741 -0
- package/skills/skillify/assets/init-new/assets/directory_structure.txt +5 -1
- package/skills/spinoff/SKILL.md +12 -7
- package/skills/todo/SKILL.md +2 -0
- package/skills/uncharted/SKILL.md +711 -0
- package/skills/uncharted/assets/SEGMENT_PROPOSAL_TEMPLATE.md +129 -0
- package/skills/uncharted/assets/UNDERSTANDING_DOC_TEMPLATE.md +160 -0
- package/skills/uncharted/scripts/apply-subsystem-cap.sh +573 -0
- package/skills/uncharted/scripts/detect-dependencies.sh +732 -0
- package/skills/uncharted/scripts/detect-tests.sh +553 -0
- package/skills/uncharted/scripts/discover-subsystems.sh +1029 -0
- package/skills/uncharted/scripts/enumerate-target.sh +470 -0
- package/skills/uncharted/scripts/import-source.sh +517 -0
- package/skills/uncharted/scripts/inspect-provenance.sh +573 -0
- package/skills/uncharted/scripts/resolve-segment-target.sh +640 -0
- package/skills/uncharted/scripts/run-engine.sh +655 -0
- package/skills/uncharted/scripts/validate-proposed-items.sh +125 -0
- package/skills/uncharted/scripts/write-backfilled-epics.sh +498 -0
- package/skills/wtf/SKILL.md +20 -0
- package/templates/CHANGELOG_TEMPLATE.md +13 -0
- package/templates/PROBLEM_RAPPORT_TEMPLATE.md +4 -1
- package/templates/SCRUM_BOARD_SCHEMA.md +157 -10
- package/templates/permission-levels/README.md +73 -0
- package/templates/permission-levels/level-1-locked.json +71 -0
- package/templates/permission-levels/level-2-guarded.json +64 -0
- package/templates/permission-levels/level-3-standard.json +62 -0
- package/templates/permission-levels/level-4-elevated.json +60 -0
- package/templates/permission-levels/level-5-unrestricted.json +58 -0
- package/skills/convert/SKILL.md +0 -124
- package/skills/convert/convert_cli.py +0 -235
- package/skills/convert/tests/sample.csv +0 -4
- package/skills/convert/tests/sample.json +0 -5
- package/skills/convert/tests/sample.jsonl +0 -3
- package/skills/convert/tests/sample.yaml +0 -18
- package/skills/convert/tests/sample_obj.csv +0 -2
- package/skills/convert/tests/sample_obj.json +0 -9
- package/skills/mirror-public/SKILL.md +0 -237
- package/skills/mirror-public/assets/config.json +0 -5
- package/skills/mirror-public/scripts/mirror.sh +0 -374
- package/skills/self-sync/SKILL.md +0 -73
- package/skills/self-sync/scripts/run.js +0 -136
- package/skills/strategy/SKILL.md +0 -312
package/skills/do/SKILL.md
CHANGED
|
@@ -304,7 +304,7 @@ Before starting:
|
|
|
304
304
|
Before invoking the developer, check whether this task was manually scoped by a human operator.
|
|
305
305
|
|
|
306
306
|
1. Read `jenga_assigned` from the resolved task's frontmatter.
|
|
307
|
-
2. If `jenga_assigned` is `true` or the field is absent — proceed to step
|
|
307
|
+
2. If `jenga_assigned` is `true` or the field is absent — proceed to step 4.2 without any further check.
|
|
308
308
|
3. If `jenga_assigned` is `false`:
|
|
309
309
|
a. Read `override_justification` from the task's frontmatter.
|
|
310
310
|
b. If `override_justification` is absent or its value is an empty string, **halt execution** and emit:
|
|
@@ -316,21 +316,58 @@ Before invoking the developer, check whether this task was manually scoped by a
|
|
|
316
316
|
```
|
|
317
317
|
Override acknowledged for <task_id>: <override_justification>
|
|
318
318
|
```
|
|
319
|
-
Then proceed to step
|
|
319
|
+
Then proceed to step 4.2.
|
|
320
320
|
|
|
321
321
|
### 4.2. Inline Execution Path (execution_scope: inline)
|
|
322
322
|
|
|
323
|
-
|
|
323
|
+
After resolving the task context (step 4) and passing override validation (step 4.1), read `execution_scope` from the task frontmatter.
|
|
324
324
|
|
|
325
|
-
|
|
325
|
+
**Locked-task dispatch guard (defense-in-depth).** Before branching on `execution_scope` below, read `crucial_level` from the task frontmatter (per `templates/SCRUM_BOARD_SCHEMA.md`'s Crucial Flag Fields). If `crucial_level: locked`:
|
|
326
|
+
|
|
327
|
+
- 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).
|
|
328
|
+
- If `execution_scope` is already `inline`, proceed directly to the inline steps below — no correction needed.
|
|
329
|
+
- If `execution_scope` is anything other than `inline` (absent, `task`, `story`, or `epic`), auto-correct it to `inline` in the task frontmatter now, and record the correction using the **same logged-note convention** as `skills/jenga/SKILL.md` Phase 0.5 Rule 4 (do not invent a second, inconsistent logging mechanism):
|
|
330
|
+
- Append to the task's `override_justification` frontmatter field:
|
|
331
|
+
```
|
|
332
|
+
override_justification: "/do dispatch guard auto-correction <date>: execution_scope forced from '<previous_value>' to 'inline' because crucial_level: locked."
|
|
333
|
+
```
|
|
334
|
+
- Then emit (non-fatally — do not halt):
|
|
335
|
+
```
|
|
336
|
+
AUTO-CORRECTION [<task_id>]: crucial_level=locked requires execution_scope=inline; corrected from "<previous_value>" to "inline".
|
|
337
|
+
```
|
|
338
|
+
- Then proceed to the inline steps below with the now-corrected `execution_scope: inline`.
|
|
339
|
+
- **Under no circumstance does a `crucial_level: locked` task fall through to step 5** (developer agent invocation / worktree creation) — this applies whether the task was resolved individually or would otherwise have entered the normal per-task worktree-creation flow.
|
|
340
|
+
|
|
341
|
+
**If `execution_scope: inline`** (including tasks corrected above), execute the task directly in the current session without spawning a developer subagent:
|
|
342
|
+
|
|
343
|
+
1. Read the task file and load its full content (description, acceptance criteria). Do NOT create a worktree. Do NOT spawn a developer subagent.
|
|
326
344
|
2. Implement the task inline — make the required changes to files directly in the current session.
|
|
327
|
-
3.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
345
|
+
3. Run the smoke test harness before committing anything:
|
|
346
|
+
- 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.
|
|
347
|
+
- If `scripts/smoke-harness.sh` does not exist, log a warning and treat the result as a pass:
|
|
348
|
+
```
|
|
349
|
+
WARNING [<task_id>]: scripts/smoke-harness.sh not found. Smoke test skipped (stub pass).
|
|
350
|
+
```
|
|
351
|
+
4. **If the smoke test exits non-zero**:
|
|
352
|
+
- Write `status: Failed` to the task's frontmatter.
|
|
353
|
+
- Emit:
|
|
354
|
+
```
|
|
355
|
+
INLINE TASK FAILED [<task_id>]: smoke test returned non-zero exit code. Task marked Failed. Halting.
|
|
356
|
+
```
|
|
357
|
+
- Do not commit. Do not proceed to the next task.
|
|
358
|
+
5. **If the smoke test passes**:
|
|
359
|
+
- Commit the changes using the standard commit convention (`task(<task_id>): <short description>`) via `/commit` in inline mode (E32_S04_T03).
|
|
360
|
+
- Run the **Intent-vs-Diff Check** (see `### 5.1. Intent-vs-Diff Check` below) for this task.
|
|
361
|
+
- Self-verify the implementation against the acceptance criteria.
|
|
362
|
+
- Write `status: Passed` and `date_completed: <today>` to the task's frontmatter if verification passes.
|
|
363
|
+
- Remove the task from `project/todo.md`.
|
|
364
|
+
6. `inline` tasks do not invoke the tester agent — the smoke test and self-verification are the only gates.
|
|
365
|
+
7. `inline` tasks always have `needs_docs: false` — skip plan and summary documentation for the implemented task.
|
|
366
|
+
8. Continue to `### 6. Verify documentation`, then `### 7. After successful completion`.
|
|
367
|
+
|
|
368
|
+
If the implementation cannot be completed inline (scope is larger than anticipated), abort and re-route to the normal developer path (step 5) — unless `crucial_level: locked`, in which case do not re-route; re-attempt inline or halt and report, per the locked-task dispatch guard above.
|
|
332
369
|
|
|
333
|
-
If
|
|
370
|
+
**If `execution_scope` is not `inline`** (or is absent / `task` / `story` / `epic`) **and `crucial_level` is not `locked`**, proceed to step 5 (invoke the developer agent) as normal.
|
|
334
371
|
|
|
335
372
|
### 5. Invoke the developer agent
|
|
336
373
|
Pass the following to the developer agent:
|
|
@@ -392,7 +429,7 @@ If either file is missing, ask the developer to produce it before continuing.
|
|
|
392
429
|
Additionally, if the completed work introduces user-facing changes, update `README.md` and `WARP.md` accordingly.
|
|
393
430
|
|
|
394
431
|
### 7. After successful completion
|
|
395
|
-
- Check for any `_INSTRUCTIONS.md` files in
|
|
432
|
+
- 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.
|
|
396
433
|
- Invoke the `/commit` skill to commit the work (if not already committed by the developer)
|
|
397
434
|
- Run `bash scripts/todo_manager.sh remove '<task title>'` to remove the completed task from `project/todo.md`
|
|
398
435
|
- Run `bash scripts/todo_manager.sh teardown` to delete `project/todo.md` if it is now effectively empty
|
package/skills/doc-sync/SKILL.md
CHANGED
|
@@ -87,6 +87,21 @@ For each update target and its resolved sources:
|
|
|
87
87
|
- Outdated examples, wrong flag names, stale code snippets.
|
|
88
88
|
- Incorrect or missing configuration keys/values.
|
|
89
89
|
|
|
90
|
+
#### 4a. Cross-reference `.publicignore` for "missing documentation" candidates
|
|
91
|
+
|
|
92
|
+
Every candidate identified above as "missing documentation for new things added in source" ships publicly by default unless this project has adopted `/mirror-public`. Before flagging any such candidate, check whether it's actually private-only:
|
|
93
|
+
|
|
94
|
+
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.
|
|
95
|
+
2. **If `.publicignore` exists**, for each "missing documentation" candidate, determine its source path (relative to the repo root) and classify it by running:
|
|
96
|
+
```
|
|
97
|
+
scripts/check-publicignore-match.sh <path> [<path> ...]
|
|
98
|
+
```
|
|
99
|
+
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.
|
|
100
|
+
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.
|
|
101
|
+
4. **`PUBLIC`** → flag it as usual in step 5's report, and name `README.md` and `project/.wiki/documentation.md` (the confirmed canonical full-reference doc — see `assets/doc_targets.md`) as the target docs to check for coverage of this item.
|
|
102
|
+
|
|
103
|
+
This sub-step only changes what gets flagged as "missing documentation" in step 3's third bullet — it does not affect the other three drift categories (renamed/removed references, outdated examples, incorrect config keys), which are flagged regardless of `.publicignore` since they concern existing documentation content, not public-shipping coverage of new source additions.
|
|
104
|
+
|
|
90
105
|
### 5. Report findings before updating
|
|
91
106
|
|
|
92
107
|
Before making any writes, present a concise drift summary per file:
|
|
@@ -165,3 +180,4 @@ If minification could not reach the target, note: `⚠️ docs/API.md reduced to
|
|
|
165
180
|
|
|
166
181
|
- `assets/doc_targets.md` — Editable list of documentation files this skill checks by default.
|
|
167
182
|
- `assets/default_excludes.txt` — Paths always excluded from source analysis unless overridden.
|
|
183
|
+
- `scripts/check-publicignore-match.sh` (repo root) — Used in step 4a to classify "missing documentation" candidates as `PUBLIC`/`BLOCKED` per `.publicignore`, reusing `/mirror-public`'s exact matching semantics.
|
|
@@ -8,7 +8,18 @@ Add one path per line inside the list below. Blank lines and lines starting with
|
|
|
8
8
|
|
|
9
9
|
<!-- Add your project's documentation files here, one per line -->
|
|
10
10
|
README.md
|
|
11
|
+
project/.wiki/documentation.md
|
|
11
12
|
<!-- docs/API.md -->
|
|
12
13
|
<!-- docs/config.md -->
|
|
13
14
|
<!-- CHANGELOG.md -->
|
|
14
15
|
<!-- CONTRIBUTING.md -->
|
|
16
|
+
|
|
17
|
+
<!--
|
|
18
|
+
Note: project/.wiki/documentation.md is the confirmed-canonical full
|
|
19
|
+
skill-reference doc (README.md links to it directly as "Full reference").
|
|
20
|
+
A near-duplicate, project/documentation/documentation.md, has independently
|
|
21
|
+
diverged from this canonical copy — see E28_S03_T01's execution summary for
|
|
22
|
+
the investigation, and story E38_S01 for the planned consolidation. Do not
|
|
23
|
+
add project/documentation/documentation.md here until that consolidation
|
|
24
|
+
lands.
|
|
25
|
+
-->
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: idea
|
|
3
|
+
description: Capture a loosely-defined idea to project/ideas.md — a lightweight, "maybe someday" log with no board or promotion overhead.
|
|
4
|
+
keywords:
|
|
5
|
+
- idea
|
|
6
|
+
- capture idea
|
|
7
|
+
- log idea
|
|
8
|
+
- brain dump
|
|
9
|
+
- maybe someday
|
|
10
|
+
examples:
|
|
11
|
+
- "capture this as an idea"
|
|
12
|
+
- "log this idea for later"
|
|
13
|
+
- "I have a rough idea I want to jot down"
|
|
14
|
+
metadata:
|
|
15
|
+
prefered_agent: scrum-master
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Idea — Lightweight Idea Capture
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
1. **Ensure `project/ideas.md` exists** — If it doesn't exist, it will be auto-created by `idea_manager.sh` from `skills/idea/assets/idea_template.md` — no manual action needed.
|
|
23
|
+
|
|
24
|
+
2. **Ask the user about the idea:**
|
|
25
|
+
- What's the idea?
|
|
26
|
+
- Any known context worth noting (why it came up, what it might relate to)?
|
|
27
|
+
|
|
28
|
+
Keep this light — `/idea` is a low-overhead capture, not a structured mission intake like `/todo`.
|
|
29
|
+
|
|
30
|
+
3. **Add to `project/ideas.md`** by running:
|
|
31
|
+
```
|
|
32
|
+
bash scripts/idea_manager.sh add '<idea>'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
4. **Ask the user**: "Capture another idea, or done?"
|
|
36
|
+
- If **another** — go back to step 2.
|
|
37
|
+
- If **done** — exit.
|
|
38
|
+
|
|
39
|
+
Unlike `/todo`, `/idea` never offers to execute, refine, or promote the captured idea(s) at the end. There is no `/do`-style follow-up here — `/idea` has no refine or promotion logic of its own.
|
|
40
|
+
|
|
41
|
+
## For Reference Only — Promotion Convention (not implemented here)
|
|
42
|
+
|
|
43
|
+
`/idea` does not implement any refine or promotion mechanism. This section documents, for reference, how promotion is expected to work elsewhere so future flows stay consistent:
|
|
44
|
+
|
|
45
|
+
- **Promoting an idea** means re-running `/brainstorm` on it, which routes onward to `/btw` or `/todo` as normal. That routing behavior already exists and is out of scope for `/idea`.
|
|
46
|
+
- **Terminal idea states** are marked directly in `project/ideas.md` using the same HTML-comment tag convention `project/todo.md` uses for `RECONCILED`:
|
|
47
|
+
- `PROMOTED` — the idea was picked up via `/brainstorm` and turned into board work.
|
|
48
|
+
- `DISCARDED` — the idea was reviewed and dropped.
|
|
49
|
+
|
|
50
|
+
Example (mirroring `project/todo.md`'s tagging style):
|
|
51
|
+
```
|
|
52
|
+
Add dark mode toggle to settings page <!-- PROMOTED -->
|
|
53
|
+
Rewrite onboarding copy in a more casual tone <!-- DISCARDED -->
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
No agent invoked by `/idea` applies these tags or acts on them — that is reserved for a future promotion step (e.g. within `/brainstorm`).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Idea Handoff
|
|
2
|
+
|
|
3
|
+
<!-- PREAMBLE (for /idea): This template was pre-filled by a caller (e.g. /spinoff).
|
|
4
|
+
Skip any questions whose answers are already provided below. Only prompt the user
|
|
5
|
+
for fields that remain empty or marked as a placeholder. -->
|
|
6
|
+
|
|
7
|
+
<!-- Format: <mission title>: <E##_S##> (epic/story ref optional) -->
|
|
8
|
+
|
|
9
|
+
## Mission Title
|
|
10
|
+
<!-- PLACEHOLDER: short name for this idea, e.g. "Refactor auth middleware" -->
|
|
11
|
+
|
|
12
|
+
## Goal / Objective
|
|
13
|
+
<!-- PLACEHOLDER: what this idea is trying to achieve -->
|
|
14
|
+
|
|
15
|
+
## Affected Files or Scope
|
|
16
|
+
<!-- PLACEHOLDER: which files, modules, or areas are involved, e.g. src/auth/, skills/idea/ -->
|
|
17
|
+
|
|
18
|
+
## Intended Approach
|
|
19
|
+
<!-- PLACEHOLDER: step-by-step or high-level approach to the work -->
|
|
20
|
+
|
|
21
|
+
## Epic / Story Linkage
|
|
22
|
+
<!-- PLACEHOLDER: known Epic or Story ID this links to, e.g. E02_S03 — or "None" if not linked -->
|
|
23
|
+
|
|
24
|
+
## Origin
|
|
25
|
+
<!-- PLACEHOLDER: EST id (task/story/epic) in progress when the divergence happened, or "None" -->
|
|
26
|
+
<!-- PLACEHOLDER: one-line summary of what the user was doing at the time -->
|
package/skills/init/SKILL.md
CHANGED
|
@@ -18,14 +18,93 @@ examples:
|
|
|
18
18
|
|
|
19
19
|
Follow these steps in order. Do not skip steps — the sequence matters.
|
|
20
20
|
|
|
21
|
-
### 1
|
|
21
|
+
### 1. Detect existing project state
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Before asking anything or scaffolding anything, classify the target directory
|
|
24
|
+
(the current directory) by running the detection script:
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
|
-
|
|
27
|
+
skills/init/scripts/detect-existing-codebase.sh .
|
|
27
28
|
```
|
|
28
29
|
|
|
30
|
+
It prints exactly one verdict on stdout:
|
|
31
|
+
|
|
32
|
+
| Verdict | Meaning | What to do |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `empty` | The directory is empty, or contains only `.git`, `.gitignore`, and top-level `README*`/`LICENSE*` boilerplate. | Proceed to step 2 — behaviour here is unchanged from before this detection step existed. |
|
|
35
|
+
| `already-scaffolded` | `project/board/`, `project/PROJECT_SUMMARY.md`, or `project/configs/workflow.json` already exists. | Tell the user this directory already has a Jenga scaffold and **stop** — do not run the scaffold script. Re-running it would silently overwrite `PROJECT_SUMMARY.md` and `workflow.json` with fresh stubs. Point them at `/continue` or `/status` instead. |
|
|
36
|
+
| `existing-codebase` | The directory has real content (source, configs, docs beyond the boilerplate list) and is not already scaffolded. | **Pause. Do not scaffold.** Present the choice below and wait for an answer. |
|
|
37
|
+
|
|
38
|
+
On `existing-codebase`, present this choice verbatim, per the Interaction Pattern in
|
|
39
|
+
`CLAUDE.md` (numbered, free-text last):
|
|
40
|
+
|
|
41
|
+
This directory already contains code that wasn't built through Jenga. How would
|
|
42
|
+
you like to proceed?
|
|
43
|
+
1. Run /uncharted onboard first, to analyze the existing code and backfill the
|
|
44
|
+
board before scaffolding
|
|
45
|
+
2. Scaffold fresh anyway, leaving the board empty (the existing code is never
|
|
46
|
+
modified either way — onboard mode and fresh scaffolding are both board-only)
|
|
47
|
+
3. Abort — don't scaffold, don't run /uncharted
|
|
48
|
+
4. Other (describe below)
|
|
49
|
+
|
|
50
|
+
- **Option 1** — invoke `/uncharted onboard`. It analyzes the existing code and backfills
|
|
51
|
+
the board; it never modifies, moves, or restructures application code. Once it
|
|
52
|
+
finishes, the directory now has `project/PROJECT_SUMMARY.md` etc., so re-running this
|
|
53
|
+
detection step returns `already-scaffolded` — there is nothing left to scaffold.
|
|
54
|
+
- **Option 2** — continue to step 2 and scaffold fresh. Note in your response that the
|
|
55
|
+
board will start empty despite the directory containing pre-existing code, since the
|
|
56
|
+
user explicitly chose that.
|
|
57
|
+
- **Option 3** — stop here. Do not run the scaffold script and do not invoke `/uncharted`.
|
|
58
|
+
- **Option 4** — handle the free-text response on its own merits.
|
|
59
|
+
|
|
60
|
+
If the run is non-interactive (no user available to answer), default to **option 3
|
|
61
|
+
(abort)**. Unlike the visibility question in step 2, none of these three choices is a
|
|
62
|
+
no-op: running `/uncharted onboard` unattended commits an analysis pass the user never
|
|
63
|
+
asked for, and scaffolding fresh unattended silently discards pre-existing code from the
|
|
64
|
+
board exactly as `/init` did before this step existed. Aborting is the only choice that
|
|
65
|
+
changes nothing on disk, so it is the only safe default.
|
|
66
|
+
|
|
67
|
+
Never treat `existing-codebase` as if it were `empty`, and never skip straight to step 2
|
|
68
|
+
on that verdict without the user (or the non-interactive default) choosing to.
|
|
69
|
+
|
|
70
|
+
### 2. Ask how JengaAgent's working files should appear
|
|
71
|
+
|
|
72
|
+
Ask the user this question, verbatim, before running any script:
|
|
73
|
+
|
|
74
|
+
How should JengaAgent's own working files (project/ — the scrum board, todo.md,
|
|
75
|
+
queue/, rapports/, and logs/) appear in this project?
|
|
76
|
+
1. Visible — keep them at `project/`, tracked and visible in directory listings
|
|
77
|
+
2. Ignored — keep them at `project/` but add them to `.gitignore` so they are never committed
|
|
78
|
+
3. Not sure — explain the trade-offs and ask me again
|
|
79
|
+
|
|
80
|
+
If the user picks option 3, explain the trade-offs and re-ask. Do not proceed until
|
|
81
|
+
the answer is one of `visible` or `ignored`.
|
|
82
|
+
|
|
83
|
+
If the run is non-interactive (no user available to answer), use the default:
|
|
84
|
+
**`visible`**. It is the only choice that changes nothing on disk, so an unattended
|
|
85
|
+
run can never silently relocate directories or edit `.gitignore`.
|
|
86
|
+
|
|
87
|
+
> A third mode, `hidden` (dot-prefixing `project/` to `.project/`, matching the
|
|
88
|
+
> `.agents/`/`.claude/` convention), was built and then withdrawn before release —
|
|
89
|
+
> testing found it left board resolution and session-end hooks writing to two
|
|
90
|
+
> different trees. It is not offered here. See
|
|
91
|
+
> `skills/distribute/CONFIG_SCHEMA.md` for the root-cause note and the tracked
|
|
92
|
+
> follow-up to reintroduce it once fixed.
|
|
93
|
+
|
|
94
|
+
Carry the chosen value into step 3. Do not apply it yourself — the script owns all
|
|
95
|
+
of the mechanical work.
|
|
96
|
+
|
|
97
|
+
### 3. Run the scaffold script
|
|
98
|
+
|
|
99
|
+
Execute the init script from the project root, passing the choice from step 2:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
chmod +x ./scripts/init.sh && ./scripts/init.sh --visibility <visible|ignored>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Omitting `--visibility` falls back to the `JENGA_PROJECT_FILES_VISIBILITY`
|
|
106
|
+
environment variable, then to `visible`.
|
|
107
|
+
|
|
29
108
|
This script handles all scaffolding in one step:
|
|
30
109
|
1. Initializes the git repository
|
|
31
110
|
2. Creates `.gitignore`
|
|
@@ -36,10 +115,24 @@ This script handles all scaffolding in one step:
|
|
|
36
115
|
7. Creates `project/data/baselines.json`
|
|
37
116
|
8. Creates `project/logs/events.json`
|
|
38
117
|
9. Creates `docs/STRATEGY.md` — a strategic brief stub intended for investors, partners, and the product team
|
|
39
|
-
10.
|
|
118
|
+
10. Creates `CHANGELOG.md` from the shared template — a running log of notable changes, seeded with an `[Unreleased]` section
|
|
119
|
+
11. 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
|
|
120
|
+
12. Stages and commits all files with the message `init: scaffold project structure and workflow config`
|
|
121
|
+
|
|
122
|
+
The visibility mode is validated before any scaffolding happens, so an invalid
|
|
123
|
+
value fails fast and leaves nothing behind. It is applied before the commit, so
|
|
124
|
+
the `.gitignore` entry is captured in the initial commit.
|
|
125
|
+
|
|
126
|
+
If the script fails, check that you are in the project root and that git and `jq`
|
|
127
|
+
are available.
|
|
40
128
|
|
|
41
|
-
|
|
129
|
+
See `skills/distribute/CONFIG_SCHEMA.md` for the full `project_files_visibility`
|
|
130
|
+
field reference.
|
|
42
131
|
|
|
43
|
-
###
|
|
132
|
+
### 4. Prompt next step
|
|
44
133
|
|
|
45
|
-
Inform the user that setup is complete
|
|
134
|
+
Inform the user that setup is complete, and state which visibility mode was applied
|
|
135
|
+
and where the working files now live. Mention that `docs/STRATEGY.md` was created as
|
|
136
|
+
a strategic brief stub for investors, partners, and the product team — they can fill
|
|
137
|
+
it in now or return to it later. Suggest running `/pi-plan` to define project goals
|
|
138
|
+
and epics.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"scrum_triggers": "project/queue/scrum_triggers.jsonl",
|
|
13
13
|
"developer_triggers": "project/queue/developer_triggers.jsonl",
|
|
14
14
|
"tester_triggers": "project/queue/tester_triggers.jsonl",
|
|
15
|
-
"session_handoff": "project/queue
|
|
15
|
+
"session_handoff": "project/queue/handoffs/",
|
|
16
16
|
"logs": "project/logs",
|
|
17
17
|
"data": "project/data",
|
|
18
18
|
"configs": "project/configs",
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# apply-project-visibility.sh — apply the `project_files_visibility` mode to a project.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# apply-project-visibility.sh <mode> [project_root]
|
|
7
|
+
# apply-project-visibility.sh --check-only <mode>
|
|
8
|
+
#
|
|
9
|
+
# Modes:
|
|
10
|
+
# visible Working files stay where they are. No-op on disk beyond the config write.
|
|
11
|
+
# ignored Working files are added to the project's .gitignore — present on disk,
|
|
12
|
+
# never committed.
|
|
13
|
+
#
|
|
14
|
+
# NOTE: A third mode, `hidden` (dot-prefixing project/ -> .project/), was
|
|
15
|
+
# implemented and then withdrawn before release. Testing found it functionally
|
|
16
|
+
# broken: scripts/board_resolver.sh hardcodes project/configs/workflow.json
|
|
17
|
+
# and never locates the rewritten path, and hooks/on_session_end.sh
|
|
18
|
+
# unconditionally recreates a shadow project/ tree on every session end,
|
|
19
|
+
# splitting runtime state across two trees. See
|
|
20
|
+
# project/rapports/problems/E31_S05_T01-hidden-mode-path-resolution-gaps.md
|
|
21
|
+
# for the full findings. Re-introducing `hidden` requires fixing both of
|
|
22
|
+
# those hardcoded paths first — tracked as a follow-up /todo item.
|
|
23
|
+
#
|
|
24
|
+
# Exit codes:
|
|
25
|
+
# 0 Success
|
|
26
|
+
# 1 Bad usage or missing prerequisite
|
|
27
|
+
# 2 Invalid mode (outside the two-value enum)
|
|
28
|
+
# 3 Filesystem apply failure
|
|
29
|
+
# 4 jenga.config.json write failure
|
|
30
|
+
|
|
31
|
+
# Do NOT use set -e globally — each step handles its own errors.
|
|
32
|
+
set -uo pipefail
|
|
33
|
+
|
|
34
|
+
info() { echo "[visibility] $*"; }
|
|
35
|
+
warn() { echo "[visibility] WARNING: $*"; }
|
|
36
|
+
err() { echo "[visibility] ERROR: $*" >&2; }
|
|
37
|
+
|
|
38
|
+
usage() {
|
|
39
|
+
echo "Usage: $(basename "$0") <visible|ignored> [project_root]" >&2
|
|
40
|
+
echo " $(basename "$0") --check-only <visible|ignored>" >&2
|
|
41
|
+
exit 1
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Every JengaAgent working file named in E31_S05 — the scrum board, todo.md,
|
|
45
|
+
# queue/, rapports/ and logs/ — nests under this single root, so one entry
|
|
46
|
+
# covers them all. `ignored` consumes this list.
|
|
47
|
+
JENGA_WORKING_PATHS=("project")
|
|
48
|
+
|
|
49
|
+
VALID_MODES="visible ignored"
|
|
50
|
+
|
|
51
|
+
validate_mode() {
|
|
52
|
+
local mode="$1"
|
|
53
|
+
for valid in $VALID_MODES; do
|
|
54
|
+
[ "$mode" = "$valid" ] && return 0
|
|
55
|
+
done
|
|
56
|
+
err "Invalid project_files_visibility value: '${mode}'"
|
|
57
|
+
err "Allowed values are: ${VALID_MODES// /, }"
|
|
58
|
+
exit 2
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
# Argument parsing
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
CHECK_ONLY=0
|
|
66
|
+
if [ "${1:-}" = "--check-only" ]; then
|
|
67
|
+
CHECK_ONLY=1
|
|
68
|
+
shift
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
MODE="${1:-}"
|
|
72
|
+
[ -n "$MODE" ] || usage
|
|
73
|
+
|
|
74
|
+
validate_mode "$MODE"
|
|
75
|
+
|
|
76
|
+
if [ "$CHECK_ONLY" -eq 1 ]; then
|
|
77
|
+
info "Mode '$MODE' is valid."
|
|
78
|
+
exit 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
PROJECT_ROOT="${2:-$PWD}"
|
|
82
|
+
if [ ! -d "$PROJECT_ROOT" ]; then
|
|
83
|
+
err "Project root does not exist: $PROJECT_ROOT"
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
cd "$PROJECT_ROOT" || { err "Cannot enter project root: $PROJECT_ROOT"; exit 1; }
|
|
87
|
+
|
|
88
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
89
|
+
err "jq is required to write jenga.config.json but was not found on PATH."
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# ---------------------------------------------------------------------------
|
|
94
|
+
# ignored — append to .gitignore, without ever duplicating an entry
|
|
95
|
+
# ---------------------------------------------------------------------------
|
|
96
|
+
|
|
97
|
+
gitignore_append() {
|
|
98
|
+
local entry="$1"
|
|
99
|
+
local gitignore=".gitignore"
|
|
100
|
+
|
|
101
|
+
if [ -f "$gitignore" ] && grep -qxF -- "$entry" "$gitignore"; then
|
|
102
|
+
info "'$entry' already present in .gitignore — skipping."
|
|
103
|
+
return 0
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Don't glue our entry onto a final line that lacks a newline.
|
|
107
|
+
if [ -s "$gitignore" ] && [ -n "$(tail -c 1 "$gitignore")" ]; then
|
|
108
|
+
printf '\n' >> "$gitignore"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
if ! printf '%s\n' "$entry" >> "$gitignore"; then
|
|
112
|
+
err "Failed to append '$entry' to .gitignore"
|
|
113
|
+
exit 3
|
|
114
|
+
fi
|
|
115
|
+
info "Added '$entry' to .gitignore"
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# ---------------------------------------------------------------------------
|
|
119
|
+
# jenga.config.json — merge the field in, written atomically (temp + mv)
|
|
120
|
+
# ---------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
write_visibility_config() {
|
|
123
|
+
local mode="$1"
|
|
124
|
+
local config="jenga.config.json"
|
|
125
|
+
local tmp="${config}.tmp"
|
|
126
|
+
local existing='{}'
|
|
127
|
+
|
|
128
|
+
# /init normally runs before any /distribute, so the file usually does not
|
|
129
|
+
# exist yet. Merge rather than overwrite so other fields survive.
|
|
130
|
+
if [ -f "$config" ]; then
|
|
131
|
+
if ! jq empty "$config" 2>/dev/null; then
|
|
132
|
+
err "$config exists but contains malformed JSON — refusing to overwrite it."
|
|
133
|
+
exit 4
|
|
134
|
+
fi
|
|
135
|
+
existing="$(cat "$config")"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
local content
|
|
139
|
+
content="$(jq --arg v "$mode" '.project_files_visibility = $v' <<< "$existing")"
|
|
140
|
+
if [ -z "$content" ]; then
|
|
141
|
+
err "Failed to construct $config content."
|
|
142
|
+
exit 4
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
if ! printf '%s\n' "$content" > "$tmp"; then
|
|
146
|
+
err "Failed to write temporary config file: $tmp"
|
|
147
|
+
exit 4
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
if ! mv "$tmp" "$config"; then
|
|
151
|
+
err "Failed to atomically move $tmp to $config"
|
|
152
|
+
rm -f "$tmp"
|
|
153
|
+
exit 4
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
info "Wrote project_files_visibility = \"$mode\" to $config"
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# ---------------------------------------------------------------------------
|
|
160
|
+
# Apply
|
|
161
|
+
# ---------------------------------------------------------------------------
|
|
162
|
+
|
|
163
|
+
case "$MODE" in
|
|
164
|
+
visible)
|
|
165
|
+
info "Mode 'visible' — working files stay in place; nothing to change on disk."
|
|
166
|
+
;;
|
|
167
|
+
ignored)
|
|
168
|
+
for path in "${JENGA_WORKING_PATHS[@]}"; do
|
|
169
|
+
gitignore_append "${path}/"
|
|
170
|
+
done
|
|
171
|
+
;;
|
|
172
|
+
esac
|
|
173
|
+
|
|
174
|
+
write_visibility_config "$MODE"
|
|
175
|
+
|
|
176
|
+
info "Applied project_files_visibility '$MODE' to $PROJECT_ROOT"
|