@jenga-ai/agent 1.3.0 → 2.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.
Files changed (76) hide show
  1. package/README.md +97 -92
  2. package/agents/developer.md +9 -8
  3. package/agents/scrum-master.md +57 -23
  4. package/agents/tester.md +51 -5
  5. package/hooks/on_session_end.sh +13 -1
  6. package/lib/generate-agent-context.js +18 -1
  7. package/lib/generate-copilot-instructions.js +18 -1
  8. package/lib/generate-skill-allow-list.js +191 -0
  9. package/lib/skill-allow-list.json +43 -0
  10. package/package.json +18 -4
  11. package/scripts/apply-j-prefix.sh +230 -0
  12. package/scripts/consume-context-digest.sh +103 -0
  13. package/scripts/postinstall.js +25 -0
  14. package/scripts/sweep-stale-context-digests.sh +132 -0
  15. package/scripts/validate-board.sh +5 -0
  16. package/scripts/write-context-digest.sh +230 -0
  17. package/skills/brainstorm/SKILL.md +1 -1
  18. package/skills/btw/SKILL.md +1 -1
  19. package/skills/clearify/SKILL.md +1 -1
  20. package/skills/close-story/SKILL.md +78 -6
  21. package/skills/close-story/scripts/check-privatized.sh +345 -0
  22. package/skills/commit/SKILL.md +1 -1
  23. package/skills/continue/SKILL.md +1 -1
  24. package/skills/deep-dive/SKILL.md +1 -1
  25. package/skills/dev-done/SKILL.md +1 -1
  26. package/skills/distribute/SKILL.md +1 -1
  27. package/skills/do/SKILL.md +100 -10
  28. package/skills/doc/README.md +155 -0
  29. package/skills/doc/SKILL.md +43 -13
  30. package/skills/doc/authoring-notes.md +72 -0
  31. package/skills/doc/scripts/resolve_last_update.py +149 -0
  32. package/skills/doc-sync/SKILL.md +1 -1
  33. package/skills/dooo/SKILL.md +1 -1
  34. package/skills/error/SKILL.md +1 -1
  35. package/skills/evaluate/SKILL.md +1 -1
  36. package/skills/examplify/SKILL.md +1 -1
  37. package/skills/help/SKILL.md +1 -1
  38. package/skills/idea/SKILL.md +1 -1
  39. package/skills/improve/SKILL.md +1 -1
  40. package/skills/init/SKILL.md +1 -1
  41. package/skills/init/assets/scope-thresholds_template.json +3 -3
  42. package/skills/j-init/SKILL.md +168 -0
  43. package/skills/j-init/assets/.gitignore_template +15 -0
  44. package/skills/j-init/assets/PROJECT_SUMMARY_template.md +13 -0
  45. package/skills/j-init/assets/directory_structure.txt +14 -0
  46. package/skills/j-init/assets/scope-thresholds_template.json +7 -0
  47. package/skills/j-init/assets/strategy_stub_template.md +38 -0
  48. package/skills/j-init/assets/test-config_template.json +4 -0
  49. package/skills/j-init/assets/workflow_template.json +30 -0
  50. package/skills/j-init/scripts/apply-project-visibility.sh +176 -0
  51. package/skills/j-init/scripts/detect-existing-codebase.sh +166 -0
  52. package/skills/j-init/scripts/init.sh +116 -0
  53. package/skills/jbp/SKILL.md +1 -1
  54. package/skills/jenga/SKILL.md +1 -1
  55. package/skills/jenga/scripts/render-confirmation.sh +55 -18
  56. package/skills/jenga-permission-level/SKILL.md +1 -1
  57. package/skills/lgtm/SKILL.md +1 -1
  58. package/skills/pi-plan/SKILL.md +1 -1
  59. package/skills/proceed/SKILL.md +1 -1
  60. package/skills/publish/SKILL.md +1 -1
  61. package/skills/publish/adapters/npm-ci.md +26 -4
  62. package/skills/publish/scripts/npm_ci_pipeline.sh +21 -1
  63. package/skills/reconcile/SKILL.md +1 -1
  64. package/skills/reconcile-origin/SKILL.md +1 -1
  65. package/skills/redo/SKILL.md +1 -1
  66. package/skills/skillify/SKILL.md +1 -1
  67. package/skills/spinoff/SKILL.md +1 -1
  68. package/skills/status/SKILL.md +1 -1
  69. package/skills/todo/SKILL.md +40 -3
  70. package/skills/todo/scripts/add_trivial_task.sh +216 -0
  71. package/skills/todo/scripts/update_story_tasks.py +87 -0
  72. package/skills/uncharted/SKILL.md +1 -1
  73. package/skills/wtf/SKILL.md +1 -1
  74. package/templates/SCRUM_BOARD_SCHEMA.md +33 -2
  75. package/templates/agent-context.md.tpl +32 -9
  76. package/templates/copilot-instructions.md.tpl +25 -8
@@ -0,0 +1,155 @@
1
+ # `/doc` Authoring and Usage Guide
2
+
3
+ `/doc` generates or regenerates a complete Markdown document for a resolved target path. The skill owns the entire target file: it resolves the documentation objective first, gathers evidence, reads any existing target for still-valid maintainer intent, then writes a full replacement document.
4
+
5
+ ## Basic Usage
6
+
7
+ ### Default target
8
+
9
+ ```text
10
+ /doc
11
+ ```
12
+
13
+ When no target is provided, `/doc` resolves the default target from `skills/doc/assets/path-objectives.yaml`. Today that default is `README.md`.
14
+
15
+ Expected flow:
16
+ 1. Resolve `README.md`
17
+ 2. Match the `project overview` objective
18
+ 3. Gather project evidence
19
+ 4. Regenerate the full `README.md`
20
+
21
+ ### Custom target
22
+
23
+ Canonical custom-target form:
24
+
25
+ ```text
26
+ /doc docs/API.md
27
+ ```
28
+
29
+ Accepted convenience form:
30
+
31
+ ```text
32
+ /doc update: docs/API.md
33
+ ```
34
+
35
+ Both forms resolve `docs/API.md`, then apply the matching rule from `skills/doc/assets/path-objectives.yaml`.
36
+
37
+ ## Target Resolution and Objective Rules
38
+
39
+ `skills/doc/assets/path-objectives.yaml` is the source of truth for:
40
+ - the default target
41
+ - known target paths
42
+ - each path's documentation objective
43
+ - required and optional sections for known targets
44
+
45
+ Known targets bypass ambiguity. Unknown targets must stop for clarification.
46
+
47
+ ## Evidence Sources and Precedence
48
+
49
+ `/doc` builds a synthesis context before writing. When sources disagree, use this precedence order:
50
+ 1. explicit user instruction
51
+ 2. scrum-board context
52
+ 3. codebase evidence
53
+ 4. git history
54
+
55
+ The synthesis context contract currently includes:
56
+ - `target_path`
57
+ - `objective`
58
+ - `project_name`
59
+ - `project_description`
60
+ - `features`
61
+ - `getting_started`
62
+ - `board_items`
63
+ - `conflicts_resolved`
64
+ - `sources_used`
65
+ - `existing_intent`
66
+
67
+ Use stronger sources to break ties. Do not let weaker evidence overwrite explicit user direction.
68
+
69
+ ## `last_update` Provenance
70
+
71
+ `last_update` is the documentation provenance field described by Epic E24's provenance work. It is intended to capture the most recent completed board item that materially updated the target document.
72
+
73
+ ### Expected source of truth
74
+
75
+ The provenance lookup relies on scrum-board `docs: [...]` annotations that point at repo-relative documentation targets such as:
76
+ - `README.md`
77
+ - `docs/API.md`
78
+
79
+ Board authors should add `docs` annotations to stories or tasks whenever implementation work changes a specific document or should be reflected in that document later.
80
+
81
+ ### How provenance is expected to resolve
82
+
83
+ 1. Look for completed board items whose `docs` list includes the target path exactly.
84
+ 2. Prefer the most recent qualifying item.
85
+ 3. Use that item as the basis for the document's `last_update` value.
86
+
87
+ ### Fallback behavior
88
+
89
+ If provenance cannot be resolved, `/doc` should follow the fallback defined by E24_S05:
90
+ - omit `last_update`, or
91
+ - mark it as `unknown`
92
+
93
+ Typical failure modes:
94
+ - the relevant board item never declared `docs: [...]`
95
+ - the target path in the board item does not exactly match the generated path
96
+ - the board item exists but is not yet in a completed/passed state
97
+
98
+ ## Ambiguity Gate
99
+
100
+ If the resolved target path is not present in `skills/doc/assets/path-objectives.yaml`, `/doc` must not guess.
101
+
102
+ It should stop and ask exactly:
103
+
104
+ ```text
105
+ What should <target_path> document? Please describe the objective.
106
+ ```
107
+
108
+ ### Example
109
+
110
+ ```text
111
+ /doc update: docs/UNKNOWN.md
112
+ ```
113
+
114
+ Expected behavior:
115
+ - do not generate a file yet
116
+ - do not invent a target objective
117
+ - ask the user what `docs/UNKNOWN.md` is meant to document
118
+
119
+ Once the user clarifies the objective, surface the resolved contract and continue.
120
+
121
+ ## Target-Specific Notes
122
+
123
+ ### `README.md`
124
+ Use `/doc` with no arguments when you want to regenerate the project overview. The generated file should center on:
125
+ - project description
126
+ - getting started steps
127
+ - examples only when they are strongly supported by evidence
128
+
129
+ ### `docs/API.md`
130
+ Use `/doc docs/API.md` (or `/doc update: docs/API.md`) when you want an API reference document. The generated file should remain grounded in known interfaces, endpoints, parameters, return values, and errors.
131
+
132
+ ## Tips for Board Authors
133
+
134
+ Add `docs` annotations when board work affects documentation scope or provenance. Good examples:
135
+
136
+ ```yaml
137
+ docs:
138
+ - README.md
139
+ - docs/API.md
140
+ ```
141
+
142
+ Use annotations when:
143
+ - a task introduces or changes user-visible behavior that belongs in README
144
+ - a story adds or changes an endpoint, command, interface, or workflow doc
145
+ - you want `/doc` provenance to trace the work back to the board reliably
146
+
147
+ Avoid annotations when the work has no documentation impact.
148
+
149
+ ## Maintainer Checklist
150
+
151
+ Before relying on `/doc`, confirm that:
152
+ 1. the target path exists in `skills/doc/assets/path-objectives.yaml`, or you are prepared to answer the ambiguity prompt
153
+ 2. relevant board items include accurate `docs: [...]` annotations
154
+ 3. higher-priority evidence sources are up to date
155
+ 4. any existing target file content that should survive regeneration is genuinely still valid
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: doc
2
+ name: j:doc
3
3
  description: Generate or update a documentation file by resolving a target path to a clear documentation objective before writing.
4
4
  metadata:
5
5
  prefered_agent: developer
@@ -12,6 +12,7 @@ keywords:
12
12
  examples:
13
13
  - "/doc"
14
14
  - "/doc docs/API.md"
15
+ - "/doc update: docs/API.md"
15
16
  - "generate documentation for the CLI"
16
17
  - "update the contributing guide"
17
18
  ---
@@ -25,6 +26,7 @@ examples:
25
26
  ```
26
27
 
27
28
  - If `target-path` is omitted, default to `README.md`.
29
+ - If the remainder starts with `update:`, strip that prefix, then trim again before resolving the target path.
28
30
  - If `target-path` is provided, use it exactly as written after `/doc`.
29
31
  - Do not guess additional arguments or rewrite the requested path.
30
32
 
@@ -32,6 +34,8 @@ examples:
32
34
 
33
35
  Load `skills/doc/assets/path-objectives.yaml` before resolving the documentation objective. Treat it as the source of truth for the `default_target`, known target paths, and their structural requirements.
34
36
 
37
+ For extended usage guidance, provenance notes, and board-author tips, see `skills/doc/README.md`.
38
+
35
39
  ## Synthesis Context Contract
36
40
 
37
41
  After target resolution, all generation must operate on a synthesis context object. E24_S03 is responsible for producing the final implementation, but this story defines the field contract that downstream generation must consume.
@@ -47,6 +51,7 @@ board_items: []
47
51
  conflicts_resolved: []
48
52
  sources_used: []
49
53
  existing_intent: null
54
+ last_update: null
50
55
  ```
51
56
 
52
57
  Required fields from E24_S03:
@@ -60,8 +65,9 @@ Required fields from E24_S03:
60
65
  - `conflicts_resolved`
61
66
  - `sources_used`
62
67
  - `existing_intent`
68
+ - `last_update`
63
69
 
64
- If the shared collector from E24_S03 is not yet merged, construct a temporary context with the same field names so later steps remain compatible.
70
+ If the shared collector from E24_S03 is not yet merged, construct a temporary context with the same field names so later steps remain compatible. `last_update` is resolved during the provenance step below.
65
71
 
66
72
  ## Instructions
67
73
 
@@ -70,12 +76,14 @@ If the shared collector from E24_S03 is not yet merged, construct a temporary co
70
76
  1. Read `default_target` from `skills/doc/assets/path-objectives.yaml`. If it is missing, fall back to `README.md`.
71
77
  2. Remove the `/doc` command token from the invocation.
72
78
  3. Trim the remaining text.
73
- 4. If nothing remains, set `target_path` to `default_target`.
74
- 5. Otherwise, set `target_path` to the trimmed remainder.
79
+ 4. If the trimmed remainder starts with the exact prefix `update:`, remove that prefix and trim the remainder again.
80
+ 5. If nothing remains, set `target_path` to `default_target`.
81
+ 6. Otherwise, set `target_path` to the trimmed remainder.
75
82
 
76
83
  Examples:
77
84
  - `/doc` → `target_path = README.md`
78
85
  - `/doc docs/API.md` → `target_path = docs/API.md`
86
+ - `/doc update: docs/API.md` → `target_path = docs/API.md`
79
87
  - `/doc docs/CLI.md` → `target_path = docs/CLI.md`
80
88
 
81
89
  ### 2. Resolve the objective from the rule table
@@ -135,15 +143,37 @@ If `target_path` is not present in `skills/doc/assets/path-objectives.yaml`:
135
143
 
136
144
  If the target file does not exist, keep `existing_intent = null`.
137
145
 
138
- ### 7. Generate a complete replacement file
146
+ ### 7. Resolve `last_update` provenance before writing
147
+
148
+ 1. Run `python3 skills/doc/scripts/resolve_last_update.py <target_path>` from the repository root.
149
+ 2. The resolver must scan `project/board/epics/`, `project/board/stories/`, and `project/board/tasks/`.
150
+ 3. Treat a board item as provenance only when all of the following are true:
151
+ - `status` is exactly `Done` or `Passed`
152
+ - `docs` is a YAML list that contains `target_path` as an exact repo-relative string match
153
+ - `date_completed` is present and parses as `YYYY-MM-DD`
154
+ 4. If multiple board items match, select the most recent `date_completed` and store it in `synthesis_context.last_update`.
155
+ 5. If no matching provenance is found, set `synthesis_context.last_update = "unknown"`. This is the required fallback because it keeps the frontmatter shape stable while making the missing provenance explicit.
156
+ 6. Ignore board items in any other status, items missing `docs`, and items whose `docs` entry uses a non-matching path form.
157
+
158
+ ### 8. Generate a complete replacement file
139
159
 
140
160
  1. Build a **full file string** from the synthesis context and the resolved target objective.
141
- 2. Treat the generated output as the entire authoritative file.
142
- 3. Do **not** patch a single section, append new text to the end, or leave untouched legacy sections in place.
143
- 4. Keep the output valid Markdown.
144
- 5. When writing, replace the old file contents in one operation.
161
+ 2. Start the file with YAML frontmatter for provenance, even when provenance could not be resolved:
162
+
163
+ ```yaml
164
+ ---
165
+ last_update: <YYYY-MM-DD or unknown>
166
+ ---
167
+ ```
168
+
169
+ 3. Use the resolved `synthesis_context.last_update` value in that frontmatter. Emit `unknown` verbatim when no completed board item provides provenance.
170
+ 4. This fallback is mandatory: do not omit the `last_update` key when provenance is missing.
171
+ 5. Treat the generated output as the entire authoritative file.
172
+ 6. Do **not** patch a single section, append new text to the end, or leave untouched legacy sections in place.
173
+ 7. Keep the output valid Markdown.
174
+ 8. When writing, replace the old file contents in one operation.
145
175
 
146
- ### 8. Generate `README.md` for the project-overview objective
176
+ ### 9. Generate `README.md` for the project-overview objective
147
177
 
148
178
  When `target_path = README.md`, generate the full document around the resolved project-overview contract.
149
179
 
@@ -175,7 +205,7 @@ When `target_path = README.md`, generate the full document around the resolved p
175
205
  - Preserve useful setup warnings from `existing_intent` when they are still valid.
176
206
  - Output valid Markdown lists or numbered steps.
177
207
 
178
- ### 9. Conditionally include a README Examples section
208
+ ### 10. Conditionally include a README Examples section
179
209
 
180
210
  Only add `## Examples` to `README.md` when the synthesis context supports a grounded project-type inference.
181
211
 
@@ -212,7 +242,7 @@ Choose the strongest evidenced type in this priority order when multiple types a
212
242
  - Do **not** include placeholder examples, pseudo-commands, or guessed endpoints.
213
243
  - If you cannot produce two grounded examples, omit the section instead of improvising.
214
244
 
215
- ### 10. Generate non-README targets from the rule table
245
+ ### 11. Generate non-README targets from the rule table
216
246
 
217
247
  For every known non-README target, the path-to-objective rule table determines the file structure. Generate a full document that satisfies the matched rule.
218
248
 
@@ -309,6 +339,6 @@ Rules:
309
339
  - Summarize each entry from commit subjects and, when needed, nearby commit context.
310
340
  - Keep newest entries first.
311
341
 
312
- ### 11. Continue using the resolved objective
342
+ ### 12. Continue using the resolved objective
313
343
 
314
344
  After the target path and objective are resolved, use them as the contract for all subsequent `/doc` work. Known paths must bypass the ambiguity gate, and all later decisions about evidence gathering, scope, regeneration, and structure must honor the surfaced `target_path` and `objective` instead of inferring a different goal.
@@ -0,0 +1,72 @@
1
+ # `/doc` authoring notes
2
+
3
+ ## `last_update` provenance
4
+
5
+ `/doc` writes a `last_update` frontmatter field at the top of generated documentation files. That value is derived from completed scrum-board items that explicitly declare they affected the target document.
6
+
7
+ The resolver is `skills/doc/scripts/resolve_last_update.py`. It scans:
8
+
9
+ - `project/board/epics/`
10
+ - `project/board/stories/`
11
+ - `project/board/tasks/`
12
+
13
+ A board item counts as provenance only when all of the following are true:
14
+
15
+ 1. `status` is `Done` or `Passed`
16
+ 2. `docs` is a YAML list
17
+ 3. The `docs` list contains the target file path as an exact repo-relative match (for example `README.md` or `docs/API.md`)
18
+ 4. `date_completed` exists and parses as `YYYY-MM-DD`
19
+
20
+ If multiple board items match, `/doc` uses the most recent `date_completed` as `last_update`.
21
+
22
+ ## Required board annotations
23
+
24
+ For provenance to work, the scrum-board item that changed a documentation file must carry a matching `docs: [...]` annotation in its YAML frontmatter.
25
+
26
+ Examples:
27
+
28
+ ```yaml
29
+ docs:
30
+ - README.md
31
+ - docs/API.md
32
+ ```
33
+
34
+ Use repo-relative paths only. The resolver does not normalize absolute paths or `./`-prefixed variants.
35
+
36
+ ## Fallback behavior
37
+
38
+ When `/doc` cannot determine provenance, it still emits valid YAML frontmatter and sets:
39
+
40
+ ```yaml
41
+ last_update: unknown
42
+ ```
43
+
44
+ This fallback is intentional. It keeps the frontmatter shape stable while making the missing provenance explicit to both humans and downstream tooling.
45
+
46
+ ## Failure modes and assumptions
47
+
48
+ ### Board item completed without `docs` annotations
49
+
50
+ If a task, story, or epic reached `Done`/`Passed` but omitted the target file from `docs`, `/doc` cannot attribute that item to the document. The resolver will ignore it and may fall back to `unknown`.
51
+
52
+ ### Target path mismatch
53
+
54
+ Matching is exact and repo-relative. These examples do **not** match `README.md`:
55
+
56
+ - `/Users/sam/.../README.md`
57
+ - `./README.md`
58
+ - `docs/../README.md`
59
+
60
+ Authors should record the canonical repo-relative path that `/doc` was invoked with.
61
+
62
+ ### Item not in a completed status
63
+
64
+ Items in statuses such as `Pending`, `In Progress`, `Blocked`, or `Failed` do not count as provenance even if they include the right `docs` annotation. Only completed work is eligible.
65
+
66
+ ### Missing or invalid `date_completed`
67
+
68
+ A matching board item without a valid `date_completed` cannot contribute a `last_update` value. The resolver skips it and logs a warning to stderr.
69
+
70
+ ### Malformed legacy board files
71
+
72
+ Some older board artifacts may not follow the current YAML-frontmatter schema. The resolver skips unparseable files instead of failing the whole `/doc` run. This is a degradation path, not successful provenance.
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env python3
2
+ """Resolve /doc last_update provenance from scrum board annotations."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ import sys
9
+ from datetime import date
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ COMPLETED_STATUSES = {"Done", "Passed"}
14
+ BOARD_DIRS = (
15
+ ("epic", Path("project/board/epics")),
16
+ ("story", Path("project/board/stories")),
17
+ ("task", Path("project/board/tasks")),
18
+ )
19
+
20
+
21
+ def parse_args() -> argparse.Namespace:
22
+ parser = argparse.ArgumentParser(
23
+ description="Resolve the latest completed board date for a documentation target.",
24
+ )
25
+ parser.add_argument("target_path", help="Repo-relative documentation target path, e.g. README.md")
26
+ parser.add_argument(
27
+ "--root",
28
+ default=Path(__file__).resolve().parents[3],
29
+ type=Path,
30
+ help="Repository root containing project/board/",
31
+ )
32
+ return parser.parse_args()
33
+
34
+
35
+ def parse_scalar(value: str) -> Any:
36
+ text = value.strip()
37
+ if text in {"", "null", "~"}:
38
+ return ""
39
+ if text.startswith("[") and text.endswith("]"):
40
+ inner = text[1:-1].strip()
41
+ if not inner:
42
+ return []
43
+ return [item.strip().strip("\"'") for item in inner.split(",") if item.strip()]
44
+ return text.strip("\"'")
45
+
46
+
47
+ def parse_frontmatter(path: Path) -> dict[str, Any]:
48
+ text = path.read_text(encoding="utf-8")
49
+ if not text.startswith("---\n"):
50
+ raise ValueError("missing opening frontmatter delimiter")
51
+ parts = text.split("\n---\n", 1)
52
+ if len(parts) != 2:
53
+ raise ValueError("missing closing frontmatter delimiter")
54
+
55
+ lines = parts[0].splitlines()[1:]
56
+ data: dict[str, Any] = {}
57
+ current_key: str | None = None
58
+
59
+ for line in lines:
60
+ if not line.strip():
61
+ continue
62
+ if line.startswith(" - "):
63
+ if current_key is None:
64
+ raise ValueError(f"orphaned list item: {line.strip()}")
65
+ existing = data.get(current_key, "")
66
+ if existing == "":
67
+ existing = []
68
+ data[current_key] = existing
69
+ if not isinstance(existing, list):
70
+ raise ValueError(f"frontmatter key {current_key!r} is not a list")
71
+ existing.append(line[4:].strip().strip("\"'"))
72
+ continue
73
+ if ":" not in line:
74
+ raise ValueError(f"invalid frontmatter line: {line}")
75
+ key, raw_value = line.split(":", 1)
76
+ key = key.strip()
77
+ value = parse_scalar(raw_value)
78
+ data[key] = value
79
+ current_key = key if value == "" else None
80
+
81
+ return data
82
+
83
+
84
+ def iter_matches(root: Path, target_path: str):
85
+ for item_type, relative_dir in BOARD_DIRS:
86
+ board_dir = root / relative_dir
87
+ if not board_dir.exists():
88
+ continue
89
+ for path in sorted(board_dir.glob("*.md")):
90
+ try:
91
+ frontmatter = parse_frontmatter(path)
92
+ except Exception as exc: # pragma: no cover - defensive degradation
93
+ print(f"warning: skipping {path}: {exc}", file=sys.stderr)
94
+ continue
95
+
96
+ if frontmatter.get("status") not in COMPLETED_STATUSES:
97
+ continue
98
+
99
+ docs = frontmatter.get("docs")
100
+ if not isinstance(docs, list) or target_path not in docs:
101
+ continue
102
+
103
+ completed_raw = str(frontmatter.get("date_completed", "")).strip()
104
+ if not completed_raw:
105
+ print(
106
+ f"warning: skipping {path}: matching docs annotation without date_completed",
107
+ file=sys.stderr,
108
+ )
109
+ continue
110
+
111
+ try:
112
+ completed_on = date.fromisoformat(completed_raw)
113
+ except ValueError:
114
+ print(
115
+ f"warning: skipping {path}: invalid date_completed {completed_raw!r}",
116
+ file=sys.stderr,
117
+ )
118
+ continue
119
+
120
+ yield {
121
+ "id": frontmatter.get("id") or path.stem,
122
+ "type": item_type,
123
+ "status": frontmatter.get("status"),
124
+ "date_completed": completed_on.isoformat(),
125
+ "path": path.relative_to(root).as_posix(),
126
+ }
127
+
128
+
129
+ def main() -> int:
130
+ args = parse_args()
131
+ root = args.root.resolve()
132
+ matches = sorted(
133
+ iter_matches(root, args.target_path),
134
+ key=lambda item: (item["date_completed"], item["id"]),
135
+ )
136
+ last_update = matches[-1]["date_completed"] if matches else "unknown"
137
+ payload = {
138
+ "target_path": args.target_path,
139
+ "last_update": last_update,
140
+ "provenance_found": bool(matches),
141
+ "fallback": "unknown",
142
+ "matched_items": matches,
143
+ }
144
+ print(json.dumps(payload, ensure_ascii=False))
145
+ return 0
146
+
147
+
148
+ if __name__ == "__main__":
149
+ raise SystemExit(main())
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: doc-sync
2
+ name: j:doc-sync
3
3
  description: Compare the current state of a project with its documentation and update documentation to reflect changes. Accepts `update:`, `source:`, `exclude:`, and `minify:` arguments to control scope. Use when documentation may be out of date with implementation, or when the user asks to sync, refresh, update, or shrink docs.
4
4
  keywords:
5
5
  - doc-sync
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: dooo
2
+ name: j:dooo
3
3
  description: Parallel execution orchestrator. Calls /do to start implementations via sub-agents, then loops back to the board to identify and offer parallelisable tasks until the user selects "Done".
4
4
  keywords:
5
5
  - dooo
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: error
2
+ name: j:error
3
3
  description: Guided troubleshooting flow that gathers context about an error — where it occurs, what was attempted, what went wrong, and what was expected.
4
4
  keywords:
5
5
  - error
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: evaluate
2
+ name: j:evaluate
3
3
  description: Analyzes example files against a target goal and produces a structured evaluation rapport.
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: examplify
2
+ name: j:examplify
3
3
  description: Explains concepts, features, use cases, and patterns based on provided context — a description, scenario, code snippet, or file. Use when the user wants to understand what something is, how it works, when to use it, or wants a concrete example.
4
4
  keywords:
5
5
  - examplify
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: help
2
+ name: j:help
3
3
  description: List all available skills with a short description of what each one does. Also use this skill when the user wants to know what commands or skills are available in the project.
4
4
  keywords:
5
5
  - help
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: idea
2
+ name: j:idea
3
3
  description: Capture a loosely-defined idea to project/ideas.md — a lightweight, "maybe someday" log with no board or promotion overhead.
4
4
  keywords:
5
5
  - idea
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: improve
2
+ name: j:improve
3
3
  description: A skill for analyzing a codebase and producing a structured improvement plan toward a defined goal.
4
4
  ---
5
5
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: init
2
+ name: j:init
3
3
  description: Initialize a new project with the standard directory structure, PROJECT_SUMMARY.md, workflow.json, git repo, and gitignore. Follows a defined ordered onboarding sequence. Use when setting up a new or empty project.
4
4
  keywords:
5
5
  - init
@@ -1,7 +1,7 @@
1
1
  {
2
- "threshold_version": 1,
3
- "inline_max_files": 1,
4
- "inline_max_lines": 20,
2
+ "threshold_version": 2,
3
+ "inline_max_files": 3,
4
+ "inline_max_lines": 75,
5
5
  "story_max_files": 5,
6
6
  "bundle_lock_ttl_minutes": 30
7
7
  }