cadence-skill-installer 0.2.18 → 0.2.19
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/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -15,11 +15,19 @@ description: Structured project operating system for end-to-end greenfield or br
|
|
|
15
15
|
- skill routing chains
|
|
16
16
|
- gate-by-gate status narration
|
|
17
17
|
- raw commands, terminal traces, or timing metadata
|
|
18
|
+
3. When internal gates/checks succeed, continue directly with the user task and do not announce that checks were run.
|
|
18
19
|
|
|
19
20
|
## Repo Status Gate
|
|
20
|
-
1. At
|
|
21
|
-
2.
|
|
22
|
-
3.
|
|
21
|
+
1. At Cadence entry (first assistant response in the conversation), resolve `PROJECT_ROOT` with `python3 scripts/resolve-project-root.py --project-root "$PWD"` (resolve script paths from this skill directory but keep command cwd at the active project).
|
|
22
|
+
2. Run `python3 scripts/check-project-repo-status.py --project-root "$PROJECT_ROOT"`.
|
|
23
|
+
3. Read `repo_enabled` from script output and treat it as the authoritative push mode for the active subskill conversation.
|
|
24
|
+
4. If `repo_enabled` is false, continue with local commits only until a GitHub remote is configured.
|
|
25
|
+
5. Do not rerun this gate between normal user replies inside the same active subskill conversation.
|
|
26
|
+
6. Rerun this gate only when:
|
|
27
|
+
- starting a new Cadence conversation
|
|
28
|
+
- transitioning to a different subskill after a completed checkpoint
|
|
29
|
+
- handling explicit resume/status/reroute requests
|
|
30
|
+
- recovering from a gate/assertion failure
|
|
23
31
|
|
|
24
32
|
## Git Checkpoints
|
|
25
33
|
1. Enforce Cadence commit convention from `config/commit-conventions.json`.
|
|
@@ -37,10 +45,15 @@ description: Structured project operating system for end-to-end greenfield or br
|
|
|
37
45
|
3. Scaffold initializes and persists `state.cadence-scripts-dir` for later subskill commands.
|
|
38
46
|
4. If `.cadence` exists, skip scaffold.
|
|
39
47
|
|
|
40
|
-
## Workflow Route Gate (Mandatory
|
|
41
|
-
1. After scaffold handling, run `python3 scripts/read-workflow-state.py` and parse the JSON response.
|
|
48
|
+
## Workflow Route Gate (Mandatory At Entry And Transitions)
|
|
49
|
+
1. After scaffold handling on Cadence entry, run `python3 scripts/read-workflow-state.py --project-root "$PROJECT_ROOT"` and parse the JSON response.
|
|
42
50
|
2. Treat `next_item` and `route.skill_name` from that response as the authoritative workflow route.
|
|
43
51
|
3. Do not invoke a state-changing subskill unless it matches `route.skill_name`.
|
|
52
|
+
4. Keep the active route stable during normal multi-turn ideation/research conversation flow; do not rerun route reads between ordinary user answers.
|
|
53
|
+
5. Rerun `read-workflow-state.py` only when:
|
|
54
|
+
- a subskill checkpoint completed and Cadence needs the next route
|
|
55
|
+
- user explicitly asks to continue/resume/status/reroute
|
|
56
|
+
- a route assertion failed and recovery is required
|
|
44
57
|
|
|
45
58
|
## Prerequisite Gate (Conditional)
|
|
46
59
|
1. Invoke `skills/prerequisite-gate/SKILL.md` only when `route.skill_name` is `prerequisite-gate`.
|
|
@@ -51,7 +64,7 @@ description: Structured project operating system for end-to-end greenfield or br
|
|
|
51
64
|
2. Use that skill's state-based routing result to continue from the correct next phase.
|
|
52
65
|
|
|
53
66
|
## Manual Subskill Safety Gate
|
|
54
|
-
1. If the user manually requests a Cadence subskill, first resolve `PROJECT_ROOT` with `python3 scripts/resolve-project-root.py`.
|
|
67
|
+
1. If the user manually requests a Cadence subskill, first resolve `PROJECT_ROOT` with `python3 scripts/resolve-project-root.py --project-root "$PWD"`.
|
|
55
68
|
2. Run `python3 scripts/assert-workflow-route.py --skill-name <subskill> --project-root "$PROJECT_ROOT"` before executing that subskill.
|
|
56
69
|
3. Ensure that direct subskill execution still applies this skill's Repo Status Gate and Git Checkpoints rules.
|
|
57
70
|
4. If route assertion fails, stop and surface the exact script error.
|
package/skill/agents/openai.yaml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: "Cadence"
|
|
3
3
|
short_description: "Lifecycle + delivery system for structured project execution"
|
|
4
|
-
default_prompt: "Use Cadence to guide this project from lifecycle setup through phased execution, traceability, audit, and milestone completion. Always read and apply the active SOUL persona from .cadence/SOUL.json (fallback: SOUL.json). Keep user-facing responses concise and outcome-focused, and never expose internal skill-routing or command-execution traces unless the user explicitly asks.
|
|
4
|
+
default_prompt: "Use Cadence to guide this project from lifecycle setup through phased execution, traceability, audit, and milestone completion. Always read and apply the active SOUL persona from .cadence/SOUL.json (fallback: SOUL.json). Keep user-facing responses concise and outcome-focused, and never expose internal skill-routing or command-execution traces unless the user explicitly asks. Do not announce successful internal checks; only surface them when a check fails and blocks progress. At Cadence entry (first assistant response in a conversation), first resolve PROJECT_ROOT with scripts/resolve-project-root.py --project-root \"$PWD\", run scripts/check-project-repo-status.py --project-root \"$PROJECT_ROOT\" and treat repo_enabled as the authoritative push mode (if false, keep commits local-only), run scaffold only when \"$PROJECT_ROOT/.cadence\" is missing, then run scripts/read-workflow-state.py --project-root \"$PROJECT_ROOT\" and treat route.skill_name as authoritative for the next state-changing skill. During normal multi-turn subskill conversation flow, do not rerun repo/route gates between each user reply; rerun them only when checkpointing into a new subskill, handling explicit resume/status/reroute requests, or recovering from assertion/gate failures. Invoke skills/prerequisite-gate/SKILL.md only when route.skill_name is prerequisite-gate. If scaffold and prerequisite complete in-thread and route advances to ideator, force subskill handoff with: Start a new chat and either say \"help me define my project\" or share your project brief. In later chats, if route.skill_name is ideator, do not rerun prerequisite; invoke skills/ideator/SKILL.md in the same chat, and if the user has not provided ideation input yet, ask one kickoff ideation question in-thread instead of handing off again. Do not force a new-chat handoff when route advances from ideator to researcher; on the next cadence invocation, route directly from workflow state. If route.skill_name is researcher, invoke skills/researcher/SKILL.md and enforce one pass per conversation; when more passes remain, end with: Start a new chat and say \"continue research\". If user intent indicates resuming/continuing work or asking progress, invoke skills/project-progress/SKILL.md first, report current phase, then route to the next step. If the user manually requests a Cadence subskill, resolve PROJECT_ROOT with scripts/resolve-project-root.py --project-root \"$PWD\" and then run scripts/assert-workflow-route.py --skill-name <subskill> --project-root \"$PROJECT_ROOT\" before any state-changing actions. Ensure direct subskill execution follows the same Git Checkpoints policy from this main skill: run scripts/finalize-skill-checkpoint.py with each subskill's configured --scope/--checkpoint and --paths ., allow status=no_changes without failure, and treat checkpoint or push failures as blocking errors surfaced verbatim."
|
|
@@ -11,7 +11,7 @@ import sys
|
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
from typing import Any
|
|
13
13
|
|
|
14
|
-
from project_root import write_project_root_hint
|
|
14
|
+
from project_root import read_oldpwd_hint, resolve_project_root, write_project_root_hint
|
|
15
15
|
from workflow_state import default_data, reconcile_workflow_state
|
|
16
16
|
|
|
17
17
|
|
|
@@ -36,8 +36,8 @@ def parse_args() -> argparse.Namespace:
|
|
|
36
36
|
)
|
|
37
37
|
parser.add_argument(
|
|
38
38
|
"--project-root",
|
|
39
|
-
default="
|
|
40
|
-
help="
|
|
39
|
+
default="",
|
|
40
|
+
help="Explicit project root override. If omitted, resolve via Cadence root resolver.",
|
|
41
41
|
)
|
|
42
42
|
parser.add_argument(
|
|
43
43
|
"--set-local-only",
|
|
@@ -141,7 +141,34 @@ def ensure_default_state(data: dict[str, Any]) -> dict[str, Any]:
|
|
|
141
141
|
|
|
142
142
|
def main() -> int:
|
|
143
143
|
args = parse_args()
|
|
144
|
-
|
|
144
|
+
explicit_project_root = args.project_root.strip() or None
|
|
145
|
+
try:
|
|
146
|
+
project_root, project_root_source = resolve_project_root(
|
|
147
|
+
script_dir=SCRIPT_DIR,
|
|
148
|
+
explicit_project_root=explicit_project_root,
|
|
149
|
+
require_cadence=False,
|
|
150
|
+
allow_hint=False,
|
|
151
|
+
)
|
|
152
|
+
except ValueError as exc:
|
|
153
|
+
print(str(exc), file=sys.stderr)
|
|
154
|
+
return 1
|
|
155
|
+
|
|
156
|
+
if (
|
|
157
|
+
explicit_project_root is None
|
|
158
|
+
and project_root_source == "cwd-fallback"
|
|
159
|
+
and project_root == SCRIPT_DIR.parent
|
|
160
|
+
):
|
|
161
|
+
oldpwd_root = read_oldpwd_hint(require_cadence=False)
|
|
162
|
+
if oldpwd_root is not None and oldpwd_root != project_root:
|
|
163
|
+
project_root = oldpwd_root
|
|
164
|
+
project_root_source = "oldpwd"
|
|
165
|
+
else:
|
|
166
|
+
print(
|
|
167
|
+
"AMBIGUOUS_PROJECT_ROOT: use --project-root when invoking from the Cadence skill directory.",
|
|
168
|
+
file=sys.stderr,
|
|
169
|
+
)
|
|
170
|
+
return 1
|
|
171
|
+
|
|
145
172
|
write_project_root_hint(SCRIPT_DIR, project_root)
|
|
146
173
|
|
|
147
174
|
repo_status = detect_git_repo(project_root)
|
|
@@ -174,6 +201,7 @@ def main() -> int:
|
|
|
174
201
|
response = {
|
|
175
202
|
"status": "ok",
|
|
176
203
|
"project_root": str(project_root),
|
|
204
|
+
"project_root_source": project_root_source,
|
|
177
205
|
"cadence_state_path": str(project_root / CADENCE_JSON_PATH),
|
|
178
206
|
"cadence_state_available": data is not None,
|
|
179
207
|
"state_updated": state_updated,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
+
import os
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
8
9
|
|
|
@@ -34,11 +35,26 @@ def read_project_root_hint(script_dir: Path) -> Path | None:
|
|
|
34
35
|
return None
|
|
35
36
|
|
|
36
37
|
candidate = Path(raw).expanduser().resolve()
|
|
37
|
-
if (candidate / ".cadence").is_dir():
|
|
38
|
+
if candidate.is_dir() and (candidate / ".cadence").is_dir():
|
|
38
39
|
return candidate
|
|
39
40
|
return None
|
|
40
41
|
|
|
41
42
|
|
|
43
|
+
def read_oldpwd_hint(*, require_cadence: bool = False) -> Path | None:
|
|
44
|
+
raw = os.environ.get("OLDPWD", "").strip()
|
|
45
|
+
if not raw:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
candidate = Path(raw).expanduser().resolve()
|
|
49
|
+
if not candidate.exists() or not candidate.is_dir():
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
if require_cadence and not (candidate / ".cadence").is_dir():
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
return candidate
|
|
56
|
+
|
|
57
|
+
|
|
42
58
|
def find_cadence_project_root(start: Path) -> Path | None:
|
|
43
59
|
current = start.resolve()
|
|
44
60
|
for candidate in [current, *current.parents]:
|
|
@@ -59,8 +75,9 @@ def resolve_project_root(
|
|
|
59
75
|
Resolution order:
|
|
60
76
|
1) Explicit `--project-root`
|
|
61
77
|
2) Nearest ancestor of cwd containing `.cadence`
|
|
62
|
-
3)
|
|
63
|
-
4)
|
|
78
|
+
3) `OLDPWD` when invoked from the skill root (if enabled)
|
|
79
|
+
4) Most recent persisted hint (if enabled)
|
|
80
|
+
5) cwd fallback
|
|
64
81
|
"""
|
|
65
82
|
|
|
66
83
|
source = "cwd"
|
|
@@ -68,16 +85,30 @@ def resolve_project_root(
|
|
|
68
85
|
project_root = Path(explicit_project_root).expanduser().resolve()
|
|
69
86
|
source = "explicit"
|
|
70
87
|
else:
|
|
71
|
-
|
|
88
|
+
cwd = Path.cwd().resolve()
|
|
89
|
+
project_root = find_cadence_project_root(cwd) or cwd
|
|
72
90
|
if (project_root / ".cadence").is_dir():
|
|
73
91
|
source = "cwd"
|
|
74
92
|
elif allow_hint:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
if cwd == script_dir.resolve().parent:
|
|
94
|
+
oldpwd_root = read_oldpwd_hint(require_cadence=require_cadence)
|
|
95
|
+
if oldpwd_root is not None and oldpwd_root != cwd:
|
|
96
|
+
project_root = oldpwd_root
|
|
97
|
+
source = "oldpwd"
|
|
98
|
+
else:
|
|
99
|
+
hinted_root = read_project_root_hint(script_dir)
|
|
100
|
+
if hinted_root is not None:
|
|
101
|
+
project_root = hinted_root
|
|
102
|
+
source = "hint"
|
|
103
|
+
else:
|
|
104
|
+
source = "cwd-fallback"
|
|
79
105
|
else:
|
|
80
|
-
|
|
106
|
+
hinted_root = read_project_root_hint(script_dir)
|
|
107
|
+
if hinted_root is not None:
|
|
108
|
+
project_root = hinted_root
|
|
109
|
+
source = "hint"
|
|
110
|
+
else:
|
|
111
|
+
source = "cwd-fallback"
|
|
81
112
|
else:
|
|
82
113
|
source = "cwd-fallback"
|
|
83
114
|
|
|
@@ -11,25 +11,26 @@ description: Guide users from a rough concept to a fully defined project idea th
|
|
|
11
11
|
4. Run `python3 "$CADENCE_SCRIPTS_DIR/check-project-repo-status.py" --project-root "$PROJECT_ROOT"` and parse the JSON output. Treat `repo_enabled` as the authoritative push mode (`false` means local-only commits).
|
|
12
12
|
5. Run `cd "$PROJECT_ROOT" && python3 "$CADENCE_SCRIPTS_DIR/assert-workflow-route.py" --skill-name ideator --project-root "$PROJECT_ROOT"` and parse the JSON response.
|
|
13
13
|
6. If route assertion fails, stop and surface the exact error to the user.
|
|
14
|
-
7.
|
|
15
|
-
8.
|
|
14
|
+
7. Run steps 2-6 once when entering this ideator conversation. Do not rerun those gate commands between normal ideation Q/A turns.
|
|
15
|
+
8. Start from the user's input and briefly restate your understanding.
|
|
16
|
+
9. Accept two input modes:
|
|
16
17
|
- Conversational discovery from a rough idea.
|
|
17
18
|
- Project brief or project document provided up front.
|
|
18
|
-
|
|
19
|
+
10. If the user provides a project brief or document:
|
|
19
20
|
- Extract the explicit requirements into a working ideation object.
|
|
20
21
|
- Judge whether the brief is execution-ready across the relevant dimensions below.
|
|
21
22
|
- If information is sufficient, present the final ideation summary and ask for confirmation.
|
|
22
23
|
- If information is missing or ambiguous, ask exactly one highest-leverage follow-up question.
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
11. Ask exactly one question at a time. Never ask a batch of questions in a single turn.
|
|
25
|
+
12. After each user answer:
|
|
25
26
|
- Summarize what changed in one short sentence.
|
|
26
27
|
- Decide the next highest-leverage unknown.
|
|
27
28
|
- Ask one natural follow-up question.
|
|
28
|
-
|
|
29
|
+
13. Keep discovery domain-agnostic and adaptive:
|
|
29
30
|
- Derive the question path from the user's domain, any provided document, and prior answers.
|
|
30
31
|
- Do not force fixed templates or hard-coded checklists during discovery.
|
|
31
32
|
- Drill deep where ambiguity remains; move on when the topic is clear.
|
|
32
|
-
|
|
33
|
+
14. Build understanding until the idea is execution-ready. Cover the relevant dimensions for the domain, including:
|
|
33
34
|
- objective and core outcome
|
|
34
35
|
- target audience or user
|
|
35
36
|
- core experience or structure (for example mechanics, flow, chapters, systems)
|
|
@@ -38,15 +39,15 @@ description: Guide users from a rough concept to a fully defined project idea th
|
|
|
38
39
|
- delivery shape (milestones, sequencing, constraints, risks, success signals)
|
|
39
40
|
- assume execution is AI-driven by default; if timeline expectations are discussed, calibrate estimates to roughly 10-100x faster than human-only delivery.
|
|
40
41
|
- do not force timeline-specific prompts just to apply this assumption.
|
|
41
|
-
|
|
42
|
+
15. Build a complete later-phase research agenda from the ideation conversation:
|
|
42
43
|
- Infer all relevant research topics that should be explored in later phases.
|
|
43
44
|
- Keep the agenda domain-agnostic and driven by what the user discussed.
|
|
44
45
|
- Group topics into coherent `research_agenda.blocks`.
|
|
45
46
|
- Track concrete entities (for example technologies, methods, standards, regulations, tools, audiences, channels) in `research_agenda.entity_registry`.
|
|
46
47
|
- Ensure entity relationships are block-consistent: if a topic references an entity, that topic must be in the entity's owner block.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
16. Do not hard-code assumptions. If you infer something, label it explicitly and ask for confirmation.
|
|
49
|
+
17. When coverage is deep enough, present a final ideation summary and ask for confirmation.
|
|
50
|
+
18. Use this canonical ideation payload contract and do not inspect Cadence scripts to infer shape during normal operation:
|
|
50
51
|
- Payload root must be a JSON object representing the full `ideation` object.
|
|
51
52
|
- Include execution-ready core fields from discovery. Preferred keys:
|
|
52
53
|
- `objective` (string)
|
|
@@ -69,15 +70,18 @@ description: Guide users from a rough concept to a fully defined project idea th
|
|
|
69
70
|
- Each `topics[]` item should include `topic_id`, `title`, `category`, `priority` (`low|medium|high`), `why_it_matters`, `research_questions`, `keywords`, `tags`, and `related_entities`.
|
|
70
71
|
- Each `entity_registry[]` item should include `entity_id`, `label`, `kind`, `aliases`, and `owner_block_id`.
|
|
71
72
|
- Relationship rule: every id listed in topic `related_entities` must exist in `entity_registry`, and that entity's `owner_block_id` must match the topic's block.
|
|
72
|
-
|
|
73
|
+
19. After confirmation, rerun route assertion once before persistence:
|
|
74
|
+
- Run `cd "$PROJECT_ROOT" && python3 "$CADENCE_SCRIPTS_DIR/assert-workflow-route.py" --skill-name ideator --project-root "$PROJECT_ROOT"`.
|
|
75
|
+
- If assertion fails, stop and surface the exact error.
|
|
76
|
+
20. After confirmation, persist ideation programmatically:
|
|
73
77
|
- Create a JSON payload file at `"$PROJECT_ROOT/.cadence/ideation_payload.json"`.
|
|
74
78
|
- Write the full finalized ideation object to that file using the contract above.
|
|
75
79
|
- Run `python3 "$CADENCE_SCRIPTS_DIR/prepare-ideation-research.py" --file "$PROJECT_ROOT/.cadence/ideation_payload.json"`.
|
|
76
80
|
- Run `cd "$PROJECT_ROOT" && python3 "$CADENCE_SCRIPTS_DIR/inject-ideation.py" --file "$PROJECT_ROOT/.cadence/ideation_payload.json" --completion-state complete` (this injects ideation and deletes the payload file on success).
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
21. Verify persistence by running `cd "$PROJECT_ROOT" && python3 "$CADENCE_SCRIPTS_DIR/get-ideation.py"`.
|
|
82
|
+
22. Mention that granular research queries are available via `cd "$PROJECT_ROOT" && python3 "$CADENCE_SCRIPTS_DIR/query-ideation-research.py"`.
|
|
83
|
+
23. Mention that research execution runs in a separate `researcher` phase.
|
|
84
|
+
24. At end of this successful skill conversation, run `cd "$PROJECT_ROOT" && python3 "$CADENCE_SCRIPTS_DIR/finalize-skill-checkpoint.py" --scope ideator --checkpoint ideation-completed --paths .`.
|
|
85
|
+
25. If `finalize-skill-checkpoint.py` returns `status=no_changes`, continue without failure.
|
|
86
|
+
26. If `finalize-skill-checkpoint.py` reports an error, stop and surface it verbatim.
|
|
87
|
+
27. If the user requests revisions later, regenerate the payload, rerun `prepare-ideation-research.py`, and rerun `inject-ideation.py` from `PROJECT_ROOT`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: "Ideator"
|
|
3
3
|
short_description: "Step-by-step domain-agnostic ideation"
|
|
4
|
-
default_prompt: "Guide the user from a rough concept or provided project brief to a fully defined idea.
|
|
4
|
+
default_prompt: "Guide the user from a rough concept or provided project brief to a fully defined idea. On ideator entry, resolve PROJECT_ROOT with scripts/resolve-project-root.py --require-cadence, then resolve CADENCE_SCRIPTS_DIR with scripts/resolve-project-scripts-dir.py --project-root \"$PROJECT_ROOT\". Run scripts/check-project-repo-status.py --project-root \"$PROJECT_ROOT\" and treat repo_enabled as the authoritative push mode (false means local-only commits). Before ideation steps, assert route with scripts/assert-workflow-route.py --skill-name ideator --project-root \"$PROJECT_ROOT\" and stop on mismatch. Do not rerun those gate scripts between normal ideation question/answer turns in the same conversation. Execute state-changing ideation persistence commands from PROJECT_ROOT so .cadence writes and checkpoint commits target the correct project. Ask one follow-up question at a time for missing critical details, then produce a complete domain-agnostic research agenda inferred from the ideation discussion with blocks, topics, and entity relationships. Use the canonical ideation payload contract documented in this skill (including objective/core_outcome/in_scope/out_of_scope plus research_agenda blocks/entity_registry/topic_index) and do not read script sources just to infer payload shape. Immediately before persistence, rerun scripts/assert-workflow-route.py --skill-name ideator --project-root \"$PROJECT_ROOT\", then run scripts/prepare-ideation-research.py to normalize and validate the research agenda, then inject via scripts/inject-ideation.py. At end of a successful ideator conversation, run scripts/finalize-skill-checkpoint.py from PROJECT_ROOT with --scope ideator --checkpoint ideation-completed --paths .; allow status=no_changes and treat checkpoint or push failures as blocking errors surfaced verbatim. Keep user-facing responses focused on ideation outcomes and do not expose internal skill-routing or command traces unless explicitly requested."
|