Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .opencode/commands/sync-cep.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,80 @@ The **only** acceptable dry-run output is the literal template above with `<summ
- If `--dry-run` is set: do not invoke `convert-cc-defs`, do not edit files, do not run conversions, and do not proceed to live sync. Only report what would happen using the pre-check summary (which was already obtained as a prerequisite) and then stop.
- Otherwise: invoke the `convert-cc-defs` skill for the selected target scope and apply the re-sync workflow steps in that skill (mechanical conversion + intelligent rewrite + merge).

## Feature: Mandatory Post-Conversion Fixup

**This step is NON-NEGOTIABLE.** After every conversion run (mechanical converter + LLM rewrite), run the batch sed fixup defined in `convert-cc-defs` Phase 2c. LLMs consistently fail at simple string replacement — the sed pass is the only reliable way to catch all remaining CC/CEP references.

### Why This Exists

In every sync run to date, the LLM rewrite pass has left behind:
- `compound-engineering:` prefixes that should be `systematic:`
- `.claude/` paths that should be `.opencode/`
- `Claude Code` product references that should be `OpenCode`
- `AskUserQuestion` tool names that should be `question`
- `CLAUDE.md` references that should be `AGENTS.md`

These are simple string replacements. The LLM does not need to do them — and repeatedly fails to. The batch sed catches them deterministically.

### Execution Steps

1. **Run the ordered sed** from `convert-cc-defs` Phase 2c on all converted `.md` files
2. **Exclude** `sync-manifest.json` (upstream paths are correct) and `claude-permissions-optimizer/SKILL.md` (CC refs are intentional — only convert prefix and tool names)
3. **Fix edge cases manually**: badge URLs, `EveryInc/systematic`, `claude.com/opencode`, `Task()` → `task()` (see Phase 2c edge cases table)
4. **Run verification grep** (both CHECK 1 and CHECK 2 from Phase 2c) — zero hits required on non-exception files
5. **Fail the run** if CHECK 2 (over-conversions) returns any hits — this means a double-conversion bug

### File Loop Pattern

```bash
{
git diff --name-only HEAD -- '*.md'
git ls-files --others --exclude-standard -- '*.md'
} | sort -u | grep -v '^skills/claude-permissions-optimizer/SKILL\.md$' | while IFS= read -r f; do
if [ -f "$f" ]; then
sed -i '' \
-e 's/compound-engineering\.local\.md/systematic.local.md/g' \
-e 's/compound-engineering-plugin/systematic/g' \
-e 's/compound-engineering pipeline artifacts/systematic pipeline artifacts/g' \
-e 's|\.context/compound-engineering/|.context/systematic/|g' \
-e 's|plugins/compound-engineering/|plugins/systematic/|g' \
-e 's/compound-engineering:/systematic:/g' \
-e 's/Compound_Engineering/Systematic/g' \
-e 's/Compound Engineering/Systematic/g' \
-e 's/compound-engineering/systematic/g' \
-e 's|~/\.claude/skills/|~/.config/opencode/skills/|g' \
-e 's|~/\.claude/settings\.json|~/.config/opencode/settings.json|g' \
-e 's|~/\.claude/|~/.config/opencode/|g' \
-e 's|`\.claude/skills/|`.opencode/skills/|g' \
-e 's|`\.claude/settings\.json|`.opencode/settings.json|g' \
-e 's| \.claude/skills/| .opencode/skills/|g' \
-e 's| \.claude/settings\.json| .opencode/settings.json|g' \
-e 's|(\.claude/|(\.opencode/|g' \
-e 's|`\.claude/|`.opencode/|g' \
-e 's| \.claude/| .opencode/|g' \
-e 's|"\.claude/|".opencode/|g' \
-e 's|CLAUDE\.md|AGENTS.md|g' \
-e 's/Claude Code/OpenCode/g' \
-e 's/claude-code/opencode/g' \
-e 's/AskUserQuestion/question/g' \
-e 's/TaskCreate/todowrite/g' \
"$f"
fi
done
```

Then apply targeted fixes to `claude-permissions-optimizer/SKILL.md`:

```bash
sed -i '' \
-e 's/compound-engineering-plugin/systematic/g' \
-e 's/compound-engineering:/systematic:/g' \
-e 's/compound-engineering/systematic/g' \
-e 's/Compound Engineering/Systematic/g' \
-e 's/AskUserQuestion/question/g' \
skills/claude-permissions-optimizer/SKILL.md
```

## Tooling and Command Safety

- Never use `gh` or other external CLI tools in dry-run mode (exception: the pre-check script must run in interactive mode to obtain summary data).
Expand Down
86 changes: 83 additions & 3 deletions .opencode/skills/convert-cc-defs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,86 @@ const converted = convertContent(upstreamContent, 'agent')
- **CC-specific exclusion rules** — some agents reference `compound-engineering pipeline artifacts` or other CC-specific content (e.g., `docs/plans/*.md` exclusions) that should be removed as they're not applicable to Systematic
- **Frontmatter quoting normalization** — the converter may change double quotes to single quotes in `argument-hint` and other frontmatter string values. This is cosmetic but verify quoting consistency after conversion.

### 2c. Mandatory Post-Conversion Fixup (Batch sed)

**LLMs consistently fail at simple string replacement.** The mechanical converter catches some patterns, but many remain — particularly inside code blocks, multi-platform tool lists, and contextual references. After every conversion (both mechanical converter AND LLM rewrite), run these deterministic sed replacements as a mandatory safety net.

**Replacement order matters.** Apply more-specific patterns before general ones to avoid double-conversion. Run all phases in sequence on each file:

```bash
# Target: all converted .md files EXCEPT exclusions (see below)
# PHASE A: compound-engineering → systematic (most specific first)
sed -i '' \
-e 's/compound-engineering\.local\.md/systematic.local.md/g' \
-e 's/compound-engineering-plugin/systematic/g' \
-e 's/compound-engineering pipeline artifacts/systematic pipeline artifacts/g' \
-e 's|\.context/compound-engineering/|.context/systematic/|g' \
-e 's|plugins/compound-engineering/|plugins/systematic/|g' \
-e 's/compound-engineering:/systematic:/g' \
-e 's/Compound_Engineering/Systematic/g' \
-e 's/Compound Engineering/Systematic/g' \
-e 's/compound-engineering/systematic/g' \
"$FILE"

# PHASE B: Path conversions (most specific first)
sed -i '' \
-e 's|~/\.claude/skills/|~/.config/opencode/skills/|g' \
-e 's|~/\.claude/settings\.json|~/.config/opencode/settings.json|g' \
-e 's|~/\.claude/|~/.config/opencode/|g' \
-e 's|`\.claude/skills/|`.opencode/skills/|g' \
-e 's|`\.claude/settings\.json|`.opencode/settings.json|g' \
-e 's| \.claude/skills/| .opencode/skills/|g' \
-e 's| \.claude/settings\.json| .opencode/settings.json|g' \
-e 's|(\.claude/|(\.opencode/|g' \
-e 's|`\.claude/|`.opencode/|g' \
-e 's| \.claude/| .opencode/|g' \
-e 's|"\.claude/|".opencode/|g' \
-e 's|CLAUDE\.md|AGENTS.md|g' \
"$FILE"

# PHASE C: Branding and tool names
sed -i '' \
-e 's/Claude Code/OpenCode/g' \
-e 's/claude-code/opencode/g' \
-e 's/AskUserQuestion/question/g' \
-e 's/TaskCreate/todowrite/g' \
"$FILE"
```

#### File Exclusions

| File/Pattern | Reason | What to convert instead |
|---|---|---|
| `sync-manifest.json` | Upstream paths (`plugins/compound-engineering/...`) are correct source references | Never run sed on manifest upstream paths |
| `claude-permissions-optimizer/SKILL.md` | Skill targets Claude Code settings files — CC refs and `.claude/` paths are intentional | Only convert: prefix (`compound-engineering:` → `systematic:`), tool names (`AskUserQuestion` → `question`), product name (`Compound Engineering` → `Systematic`) |

#### Edge Cases Requiring Manual Review After sed

These patterns recur across every sync and need manual attention:

| Pattern | Problem | Fix |
|---|---|---|
| `EveryInc/systematic` in URLs | Over-conversion of `EveryInc/compound-engineering-plugin` | Use generic example (`acme/my-app`) or remove entirely |
| `claude.com/opencode` | `Claude Code` → `OpenCode` mangles URLs like `claude.com/claude-code` | Replace with `opencode.ai` |
| CEP version attribution badges | `[![Compound Engineering v[VERSION]]...]` becomes `[![Systematic v[VERSION]]...]` with dead URL | Remove the entire badge line |
| `Task()` in code blocks | Uppercase `Task()` in code examples not caught by branding sed | Manually fix to `task()` |
| `https://github.com/EveryInc/systematic` | Non-existent URL from catch-all sed | Context-dependent: remove, genericize, or update to actual Systematic repo URL |
| Multi-platform tool lists | `(question in OpenCode, ...)` after conversion — verify the list is coherent | Should read naturally with OpenCode as the primary platform |

#### Post-Fixup Verification (MANDATORY)

After running the batch sed fixup, verify with grep. Both checks MUST pass:

```bash
# CHECK 1: Remaining CC/CEP refs (should be zero for non-exception files)
grep -rnE 'Claude Code|claude-code|\.claude/|CLAUDE\.md|~/\.claude|AskUserQuestion|TaskCreate|compound-engineering|Compound Engineering|Compound_Engineering|EveryInc/systematic|claude\.com/opencode' <files>

# CHECK 2: Over-conversions (should ALWAYS be zero across ALL files)
grep -rnE '\.opencode/\.opencode/|config/opencode/\.config/|systematic\.systematic|systematic:systematic:|opencode\.ai/opencode' <files>
```

If CHECK 1 returns hits on non-exception files, fix them. If CHECK 2 returns any hits, you have a double-conversion bug — investigate immediately.

## Phase 3: Intelligent Rewrite

This is the critical step that distinguishes a good import from a broken one. Every converted definition MUST go through intelligent rewrite.
Expand Down Expand Up @@ -394,6 +474,9 @@ Before writing the file, verify:
- [ ] Content matches Systematic's style (structured phases, explicit deliverables)
- [ ] Agent `mode` field is set (`subagent`, `primary`, or `all`)
- [ ] Agent `temperature` is appropriate for the agent's purpose
- [ ] **Batch sed fixup ran** — Phase 2c sed commands executed on all converted files
- [ ] **Grep verification passed** — Phase 2c CHECK 1 (remaining refs) and CHECK 2 (over-conversions) both clean
- [ ] **Edge cases reviewed** — Checked for mangled URLs, dead badge links, uppercase `Task()` in code blocks (see Phase 2c edge cases table)

### 3g. Discrepancy Reporting

Expand All @@ -412,9 +495,6 @@ Example discrepancy report:
| skills/foo/SKILL.md | 42 | Uses `~/.opencode/` path | Verify if intentional, fix to `~/.config/opencode/` if not |
| commands/bar.md | 15 | Uses `AskUserQuestion` | Convert to `question` tool |
```
- [ ] Content matches Systematic's style (structured phases, explicit deliverables)
- [ ] Agent `mode` field is set (`subagent`, `primary`, or `all`)
- [ ] Agent `temperature` is appropriate for the agent's purpose

## Phase 4: Write and Register

Expand Down
Loading