Skip to content

Commit 86e1d5a

Browse files
committed
bump to v3.4.0-beta
Signed-off-by: ainetx <viator@via-net.org>
1 parent 62fa7b6 commit 86e1d5a

File tree

33 files changed

+476
-235
lines changed

33 files changed

+476
-235
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: cypilot-analyze
3+
description: "Analyze Cypilot artifacts against templates or code against design requirements with traceability verification (tool invocation is validate-only)"
4+
---
5+
6+
ALWAYS open and follow `{cypilot_path}/.core/workflows/analyze.md`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: cypilot-generate
3+
description: "Create/update artifacts or implement code"
4+
---
5+
6+
ALWAYS open and follow `{cypilot_path}/.core/workflows/generate.md`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: cypilot-plan
3+
description: "Decompose large tasks into self-contained phase files"
4+
---
5+
6+
ALWAYS open and follow `{cypilot_path}/.core/workflows/plan.md`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
name: cypilot-workspace
3+
description: "Multi-repo workspace setup — discover repos, configure sources, generate workspace config, validate"
4+
---
5+
6+
ALWAYS open and follow `{cypilot_path}/.core/workflows/workspace.md`

.bootstrap/.core/skills/cypilot/agents.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@
55
#
66
# Semantic fields (mode, isolation, model) are mapped to per-tool
77
# frontmatter by the agents command — kits never need tool-specific knowledge.
8+
#
9+
# Field mappings by tool:
10+
#
11+
# isolation (bool):
12+
# Claude Code → true = worktree-isolated agent, false = main-context agent
13+
# Cursor → true = "agent" mode (background), false = inline composer
14+
# Copilot → true = separate workspace context, false = shared context
15+
# Codex → true = sandboxed execution, false = shared session
16+
#
17+
# model (string):
18+
# "inherit" → all tools: use the model selected by the user/session
19+
# "fast" → Claude Code: maps to "sonnet"; Cursor: kept as "fast";
20+
# Copilot/Codex: maps to the tool's fast-tier model
21+
# Prefer "inherit" unless the agent explicitly needs a cheaper/faster tier.
22+
# Use "fast" only for high-volume, low-complexity tasks (e.g. PR review).
823

924
[agents.cypilot-codegen]
1025
description = """\

.bootstrap/.core/skills/cypilot/agents/cypilot-phase-runner.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ Execution rules:
1717
- Treat `plan.toml` on disk as the sole source of truth.
1818
- When the user asks to execute a phase, read `plan.toml` first and determine the
1919
target phase from manifest state unless the user explicitly names a phase.
20-
- Audit dependencies, declared `output_files`, declared `outputs`, downstream
20+
- Verify dependencies, declared `output_files`, declared `outputs`, downstream
2121
`inputs`, and lifecycle-state exceptions exactly as defined in `plan.md`.
22+
Verification means: confirm each declared dependency file exists and is
23+
non-empty, confirm each declared output path is writable, and confirm
24+
downstream `inputs` reference existing or to-be-created outputs.
2225
- Repair stale lifecycle state exactly when the manifest rules require it before
2326
continuing execution.
2427
- Update the selected phase to `in_progress` before execution when the runtime

.bootstrap/.core/skills/cypilot/agents/cypilot-ralphex.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [CLI Entrypoint](#cli-entrypoint)
66
- [Library Entrypoint](#library-entrypoint)
77
- [Post-Run Handoff](#post-run-handoff)
8+
- [Response Completion Gate](#response-completion-gate)
89

910
<!-- /toc -->
1011

@@ -69,6 +70,16 @@ build command → track lifecycle. It returns a structured dict with keys:
6970
- `"delegated"` — command assembled and ready for invocation
7071
- `"error"` — a precondition failed; check the `error` field
7172

73+
**Error handling:** When `result["status"] == "error"`, inspect `result["error"]`
74+
for the failure reason and `result["lifecycle_state"]` for the lifecycle position.
75+
Do NOT proceed to Post-Run Handoff. Instead:
76+
- If `result["bootstrap"]["needed"]` is `True`: inform the user that `ralphex --init`
77+
is required and request explicit approval before running it.
78+
- If `result["error"]` references review precondition failure: report the
79+
precondition (e.g. no commits ahead of default branch) and suggest resolution.
80+
- For all other errors: report the error message, the lifecycle state at failure,
81+
and offer retry or abort options.
82+
7283
**Mode selection:**
7384

7485
| Mode | Command | Notes |
@@ -120,9 +131,28 @@ from cypilot.ralphex_export import (
120131

121132
1. Call `read_handoff_status(exit_code, output_refs, partial)` to classify the delegation outcome (success/partial/failed).
122133
2. Call `check_completed_plans(plans_dir, task_slug)` to inspect the ralphex-managed `completed/` subdirectory for lifecycle artifacts.
123-
3. Call `run_validation_commands(commands, cwd=repo_root)` with the validation commands from the original Cypilot plan to verify execution correctness independently of ralphex. Pass the delegated repository root as `cwd` so repo-relative commands resolve correctly.
134+
3. Call `run_validation_commands(commands, cwd=repo_root)` with validation commands
135+
extracted from the `## Validation Commands` section of the compiled plan file
136+
(`result["plan_file"]`). Each non-empty, non-heading line in that section is one
137+
command. Pass the delegated repository root as `cwd` so repo-relative commands
138+
resolve correctly.
124139
4. Call `report_handoff(...)` to assemble the delegation summary.
125-
5. Return the handoff report to the main conversation with status, output refs, validation outcome, and next-step options.
140+
5. Return the handoff report to the main conversation using this structured format:
141+
142+
```markdown
143+
## Delegation Handoff Report
144+
- **Status**: {report["status"]} (success | partial | failed)
145+
- **Plan file**: `{report["plan_file"]}`
146+
- **Mode**: {report["mode"]}
147+
- **Validation passed**: {report["validation_passed"]}
148+
- **Completed plan**: `{report["completed_plan_path"]}` or none
149+
- **Output refs**: {report["output_refs"] as bulleted list, or "none"}
150+
151+
### Next Steps
152+
1. Review output artifacts listed above
153+
2. Run `/cypilot-analyze` on changed files if validation passed
154+
3. If failed: inspect error output, fix issues, and re-delegate
155+
```
126156

127157
**Bootstrap gate:**
128158

@@ -131,3 +161,16 @@ with `bootstrap.needed = True` and a message directing the user to run
131161
`ralphex --init`. If the user wants to proceed, request explicit approval before
132162
running `ralphex --init`. NEVER run `ralphex --init` automatically — it is
133163
always an opt-in action.
164+
165+
## Response Completion Gate
166+
167+
This agent's response is complete only when ALL of the following are true:
168+
- `run_delegation()` has been called and the result dict is available
169+
- If `status == "error"`: the error has been reported with lifecycle state,
170+
failure reason, and recovery options (retry/abort/bootstrap)
171+
- If `status != "error"`: Post-Run Handoff steps 1–5 have been executed and
172+
the structured Delegation Handoff Report has been emitted
173+
- The SKILL.md invariant has been satisfied (Cypilot mode was loaded)
174+
175+
Do NOT end the response with only a summary or status update. The handoff
176+
report (or error report with recovery options) is the mandatory terminal block.

.bootstrap/.core/skills/cypilot/scripts/cypilot/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def main(argv: Optional[List[str]] = None) -> int:
1717
from .cli import main as _main
1818
return _main(argv)
1919

20-
__version__ = "v3.3.0-beta"
20+
__version__ = "v3.4.0-beta"
2121

2222
__all__ = [
2323
# Main entry point

.bootstrap/.core/skills/cypilot/scripts/cypilot/commands/_core_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
logger = logging.getLogger(__name__)
1313

1414
# @cpt-begin:cpt-cypilot-algo-ralphex-delegation-discover:p1:inst-read-config
15-
_ADAPTER_DIRS = (".bootstrap", "cypilot")
15+
_ADAPTER_DIRS = (".bootstrap", "cypilot", ".cypilot", ".cpt")
1616

1717

1818
def load_core_config(project_root: Path) -> dict:

.bootstrap/.core/skills/cypilot/scripts/cypilot/commands/agents.py

Lines changed: 95 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -381,32 +381,31 @@ def _agent_template_copilot(agent: Dict[str, Any]) -> List[str]:
381381
}
382382

383383

384-
def _render_toml_agents(agents: List[Dict[str, Any]], target_agent_paths: Dict[str, str]) -> str:
385-
"""Render one OpenAI Codex TOML role-definition file per agent.
384+
def _render_toml_agent(agent: Dict[str, Any], target_agent_path: str) -> str:
385+
"""Render a single OpenAI Codex TOML agent role file.
386386
387-
Codex treats each ``.toml`` file in ``.codex/agents/`` as a single role
388-
definition, so the generated file must expose top-level
389-
``description``/``developer_instructions`` keys rather than nested
390-
``[agents.*]`` tables.
391-
392-
*agents* must contain exactly one semantic agent dict and *target_agent_paths*
393-
must contain its resolved prompt target.
387+
Each agent becomes its own ``.toml`` file with top-level ``name``,
388+
``description``, and ``developer_instructions`` — the fields required
389+
by the Codex CLI agent-role schema.
394390
"""
395-
if len(agents) != 1:
396-
raise ValueError("_render_toml_agents() expects exactly one agent for Codex TOML output")
397-
agent = agents[0]
398391
name = agent["name"]
399-
desc = " ".join(agent.get("description", "").split())
400-
agent_path = target_agent_paths.get(name, "")
401-
prompt = f"ALWAYS open and follow `{agent_path}`"
392+
raw_desc = agent.get("description", "")
393+
if not isinstance(raw_desc, str):
394+
raw_desc = str(raw_desc) if raw_desc is not None else ""
395+
desc = " ".join(raw_desc.split())
402396
desc_escaped = desc.replace("\\", "\\\\").replace('"', '\\"')
403-
lines: List[str] = [f"# Cypilot subagent definition for OpenAI Codex: {name}", ""]
404-
lines.append(f'name = "{name}"')
405-
lines.append(f'description = "{desc_escaped}"')
406-
lines.append('developer_instructions = """')
407-
lines.append(prompt)
408-
lines.append('"""')
409-
return "\n".join(lines).rstrip() + "\n"
397+
prompt = f"ALWAYS open and follow `{target_agent_path}`"
398+
lines: List[str] = [
399+
f'name = "{name}"',
400+
f'description = "{desc_escaped}"',
401+
'developer_instructions = """',
402+
prompt,
403+
'"""',
404+
]
405+
return "\n".join(lines) + "\n"
406+
407+
408+
410409
# @cpt-end:cpt-cypilot-algo-agent-integration-generate-shims:p1:inst-create-proxy-templates
411410

412411

@@ -630,14 +629,62 @@ def _default_agents_config() -> dict:
630629
"path": ".agents/skills/cypilot/SKILL.md",
631630
"template": [
632631
"---",
633-
_TMPL_NAME,
632+
"name: cypilot",
634633
_TMPL_DESCRIPTION,
635634
"---",
636635
"",
637636
"{custom_content}",
638637
"ALWAYS open and follow `{target_skill_path}`",
639638
],
640-
}
639+
},
640+
{
641+
"path": ".agents/skills/cypilot-generate/SKILL.md",
642+
"target": "workflows/generate.md",
643+
"template": [
644+
"---",
645+
"name: cypilot-generate",
646+
_TMPL_DESCRIPTION,
647+
"---",
648+
"",
649+
_ALWAYS_FOLLOW_TARGET_PATH,
650+
],
651+
},
652+
{
653+
"path": ".agents/skills/cypilot-analyze/SKILL.md",
654+
"target": "workflows/analyze.md",
655+
"template": [
656+
"---",
657+
"name: cypilot-analyze",
658+
_TMPL_DESCRIPTION,
659+
"---",
660+
"",
661+
_ALWAYS_FOLLOW_TARGET_PATH,
662+
],
663+
},
664+
{
665+
"path": ".agents/skills/cypilot-plan/SKILL.md",
666+
"target": "workflows/plan.md",
667+
"template": [
668+
"---",
669+
"name: cypilot-plan",
670+
_TMPL_DESCRIPTION,
671+
"---",
672+
"",
673+
_ALWAYS_FOLLOW_TARGET_PATH,
674+
],
675+
},
676+
{
677+
"path": ".agents/skills/cypilot-workspace/SKILL.md",
678+
"target": "workflows/workspace.md",
679+
"template": [
680+
"---",
681+
"name: cypilot-workspace",
682+
_TMPL_DESCRIPTION,
683+
"---",
684+
"",
685+
_ALWAYS_FOLLOW_TARGET_PATH,
686+
],
687+
},
641688
],
642689
},
643690
},
@@ -1255,50 +1302,36 @@ def _process_single_agent(
12551302
)
12561303

12571304
if output_format == "toml":
1258-
filtered_kit_agents = [ka for ka in kit_agents if ka.get("prompt_file_abs")]
1259-
1260-
legacy_toml_path = (output_dir / "cypilot-agents.toml").resolve()
1261-
if legacy_toml_path.is_file():
1262-
if dry_run:
1263-
subagents_result["deleted"].append(legacy_toml_path.as_posix())
1264-
subagents_result["outputs"].append({
1265-
"path": _safe_relpath(legacy_toml_path, project_root),
1266-
"action": "deleted",
1267-
})
1268-
else:
1269-
try:
1270-
legacy_toml_path.unlink()
1271-
subagents_result["deleted"].append(legacy_toml_path.as_posix())
1272-
subagents_result["outputs"].append({
1273-
"path": _safe_relpath(legacy_toml_path, project_root),
1274-
"action": "deleted",
1275-
})
1276-
except OSError:
1277-
subagents_result["errors"].append(
1278-
f"failed to delete legacy OpenAI agent config: {_safe_relpath(legacy_toml_path, project_root)}"
1279-
)
1280-
1281-
for ka in filtered_kit_agents:
1305+
# Render one TOML file per agent (Codex CLI expects top-level fields per file)
1306+
for ka in kit_agents:
12821307
name = ka["name"]
1283-
target_agent_rel = target_agent_paths.get(name, "")
1284-
if not target_agent_rel:
1308+
agent_path = target_agent_paths.get(name, "")
1309+
if not agent_path:
12851310
sys.stderr.write(
12861311
f"WARNING: agent {name!r} has no resolved prompt target, skipping subagent proxy\n"
12871312
)
12881313
subagents_result["skipped"] = True
12891314
subagents_result["skip_reason"] = subagents_result.get("skip_reason", "") or "one or more agents missing prompt target"
12901315
continue
1291-
content = _render_toml_agents([ka], {name: target_agent_rel})
1292-
filename = filename_fmt.format(name=name)
1293-
out_path = (output_dir / filename).resolve()
1316+
toml_path = (output_dir / f"{name}.toml").resolve()
1317+
content = _render_toml_agent(ka, agent_path)
1318+
_write_or_skip(toml_path, content, subagents_result, project_root, dry_run)
1319+
# Clean up stale TOML files: legacy combined file and renamed/removed agents
1320+
desired_toml_names = {f"{ka['name']}.toml" for ka in kit_agents if target_agent_paths.get(ka["name"])}
1321+
if output_dir.is_dir():
12941322
try:
1295-
out_path.relative_to(output_dir)
1296-
except ValueError:
1297-
subagents_result["errors"].append(
1298-
f"agent {name!r} would write outside {output_dir_rel}, skipped"
1299-
)
1300-
continue
1301-
_write_or_skip(out_path, content, subagents_result, project_root, dry_run)
1323+
for toml_file in output_dir.glob("cypilot*.toml"):
1324+
if toml_file.name in desired_toml_names:
1325+
continue
1326+
rel = _safe_relpath(toml_file, project_root)
1327+
subagents_result["outputs"].append({"path": rel, "action": "deleted"})
1328+
if not dry_run:
1329+
try:
1330+
toml_file.unlink()
1331+
except OSError:
1332+
pass
1333+
except OSError:
1334+
pass
13021335
else:
13031336
# Markdown + YAML frontmatter (claude, cursor, copilot)
13041337
template_fn = tool_cfg.get("template_fn")
@@ -1806,6 +1839,8 @@ def _render_agent_file_actions(
18061839
ui.file_action(path, "created")
18071840
for path in sub.get("updated", []):
18081841
ui.file_action(path, "updated")
1842+
for path in sub.get("deleted", []):
1843+
ui.file_action(path, "deleted")
18091844
if sub.get("skipped") and sub.get("skip_reason"):
18101845
ui.substep(f"subagents skipped: {sub.get('skip_reason')}")
18111846

0 commit comments

Comments
 (0)