@event4u/agent-config 1.39.0 → 1.40.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.
- package/.agent-src/commands/orchestrate.md +123 -0
- package/.agent-src/commands/sync-gitignore/fix.md +135 -0
- package/.agent-src/commands/sync-gitignore.md +31 -5
- package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +30 -2
- package/.agent-src/skills/subagent-orchestration/SKILL.md +9 -0
- package/.agent-src/skills/using-git-worktrees/SKILL.md +25 -0
- package/.agent-src/templates/agent-settings.md +9 -0
- package/.agent-src/templates/scripts/work_engine/orchestration.py +168 -0
- package/.claude-plugin/marketplace.json +3 -1
- package/CHANGELOG.md +42 -0
- package/README.md +5 -5
- package/bin/install.php +13 -6
- package/config/agent-settings.template.yml +21 -0
- package/docs/DISTRIBUTION_CHECKLIST.md +169 -0
- package/docs/architecture.md +1 -1
- package/docs/catalog.md +3 -2
- package/docs/contracts/audit-log-v1.md +142 -0
- package/docs/contracts/command-clusters.md +2 -0
- package/docs/contracts/file-ownership-matrix.json +20 -0
- package/docs/contracts/orchestration-dsl-v1.md +152 -0
- package/docs/getting-started.md +1 -1
- package/docs/installation.md +132 -0
- package/docs/setup/per-ide/aider.md +48 -0
- package/docs/setup/per-ide/claude-code.md +108 -0
- package/docs/setup/per-ide/claude-desktop.md +148 -0
- package/docs/setup/per-ide/cline.md +43 -0
- package/docs/setup/per-ide/codex.md +46 -0
- package/docs/setup/per-ide/copilot.md +80 -0
- package/docs/setup/per-ide/cursor.md +125 -0
- package/docs/setup/per-ide/gemini-cli.md +45 -0
- package/docs/setup/per-ide/windsurf.md +120 -0
- package/package.json +1 -1
- package/scripts/compress.py +153 -1
- package/scripts/extract_audit_patterns.py +202 -0
- package/scripts/install +156 -1
- package/scripts/install.py +270 -10
- package/scripts/install.sh +52 -7
- package/scripts/lint_orchestration_dsl.py +214 -0
- package/scripts/skill_linter.py +9 -0
- package/scripts/sync_gitignore.py +56 -1
- package/templates/claude_desktop_config.json.template +21 -0
- package/templates/cursor-rule.mdc.j2 +7 -0
- package/templates/global-install-manifest.yml +91 -0
- package/templates/marketing-copy.yml +64 -0
- package/templates/windsurf-rule.md.j2 +7 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# OpenAI Codex CLI Setup
|
|
2
|
+
|
|
3
|
+
OpenAI's Codex CLI (the `codex` command) reads `AGENTS.md` from the
|
|
4
|
+
repo root for project context.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
- Codex CLI installed: <https://github.com/openai/codex>.
|
|
9
|
+
- Node.js ≥ 18 (for the install entrypoints).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @event4u/create-agent-config init --tools=codex
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Populates:
|
|
18
|
+
|
|
19
|
+
- `AGENTS.md` — agent self-orientation (Codex auto-loads)
|
|
20
|
+
- `.agent-settings.yml` — per-project knobs
|
|
21
|
+
|
|
22
|
+
Codex CLI reads `AGENTS.md` automatically when invoked from the repo
|
|
23
|
+
root. No additional configuration needed.
|
|
24
|
+
|
|
25
|
+
## Verification
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
test -f AGENTS.md
|
|
29
|
+
codex --help # confirm CLI installed
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
In a Codex CLI session, the loaded `AGENTS.md` content informs every
|
|
33
|
+
turn — verify by asking *"what is this repo?"* and confirming the
|
|
34
|
+
answer matches `AGENTS.md`'s emergency-triage block.
|
|
35
|
+
|
|
36
|
+
## Troubleshooting
|
|
37
|
+
|
|
38
|
+
| Symptom | Fix |
|
|
39
|
+
|---|---|
|
|
40
|
+
| Codex ignores `AGENTS.md` | Run from repo root, not a subdirectory. |
|
|
41
|
+
| Out-of-date context | `codex` re-reads on each session start — quit and restart. |
|
|
42
|
+
|
|
43
|
+
## Cross-references
|
|
44
|
+
|
|
45
|
+
- [`AGENTS.md`](../../../AGENTS.md) — canonical agent self-orientation.
|
|
46
|
+
- [`docs/installation.md`](../../installation.md) — install matrix index.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# GitHub Copilot Setup
|
|
2
|
+
|
|
3
|
+
GitHub Copilot Chat (VS Code, JetBrains, Neovim, `gh copilot` CLI)
|
|
4
|
+
reads `.github/copilot-instructions.md` for project-level guidance and
|
|
5
|
+
falls back to `AGENTS.md` where supported.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- GitHub Copilot subscription (Individual, Business, or Enterprise).
|
|
10
|
+
- Copilot Chat enabled in your IDE.
|
|
11
|
+
- Node.js ≥ 18 for the install entrypoints.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx @event4u/create-agent-config init --tools=copilot
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Populates:
|
|
20
|
+
|
|
21
|
+
- `.github/copilot-instructions.md` — Copilot's project-level prompt
|
|
22
|
+
- `AGENTS.md` — canonical agent self-orientation
|
|
23
|
+
- `.agent-settings.yml` — per-project knobs
|
|
24
|
+
|
|
25
|
+
The package keeps `.github/copilot-instructions.md` deliberately thin
|
|
26
|
+
(it points back to `AGENTS.md`) so all surfaces share a single source
|
|
27
|
+
of truth.
|
|
28
|
+
|
|
29
|
+
## VS Code Copilot Chat
|
|
30
|
+
|
|
31
|
+
Auto-loads `.github/copilot-instructions.md` once you reload the VS
|
|
32
|
+
Code window after install. Verify in the Copilot Chat panel —
|
|
33
|
+
*"What is this repo?"* should answer using the AGENTS.md emergency
|
|
34
|
+
triage block.
|
|
35
|
+
|
|
36
|
+
## JetBrains Copilot
|
|
37
|
+
|
|
38
|
+
JetBrains Copilot 1.5+ reads the same `.github/copilot-instructions.md`
|
|
39
|
+
file. No extra steps; reload the project after install.
|
|
40
|
+
|
|
41
|
+
## Neovim Copilot
|
|
42
|
+
|
|
43
|
+
`copilot.lua` and `CopilotChat.nvim` honor
|
|
44
|
+
`.github/copilot-instructions.md`. No extra config needed.
|
|
45
|
+
|
|
46
|
+
## `gh copilot` CLI
|
|
47
|
+
|
|
48
|
+
The `gh copilot` plugin (`gh extension install github/gh-copilot`)
|
|
49
|
+
reads the repo context including `AGENTS.md` and
|
|
50
|
+
`.github/copilot-instructions.md` when invoked from the repo root.
|
|
51
|
+
|
|
52
|
+
## Suppressing Copilot PR review noise
|
|
53
|
+
|
|
54
|
+
Copilot's PR auto-review can flag the package's own kernel rules as
|
|
55
|
+
"unusual phrasing". The package ships a Copilot-suppression rule
|
|
56
|
+
([`augment-portability`](../../../.augment/rules/augment-portability.md))
|
|
57
|
+
that documents this trade-off.
|
|
58
|
+
|
|
59
|
+
## Verification
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
test -f .github/copilot-instructions.md
|
|
63
|
+
test -f AGENTS.md
|
|
64
|
+
gh copilot --version # if you want CLI plugin
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Troubleshooting
|
|
68
|
+
|
|
69
|
+
| Symptom | Fix |
|
|
70
|
+
|---|---|
|
|
71
|
+
| Copilot ignores the file | Reload the IDE window after install. |
|
|
72
|
+
| File missing after install | Re-run `npx @event4u/create-agent-config init --tools=copilot`. |
|
|
73
|
+
| Copilot PR review too noisy | See the `copilot-config` skill for suppression patterns. |
|
|
74
|
+
|
|
75
|
+
## Cross-references
|
|
76
|
+
|
|
77
|
+
- [`AGENTS.md`](../../../AGENTS.md) — canonical agent self-orientation.
|
|
78
|
+
- [`.augment/skills/copilot-config/SKILL.md`](../../../.augment/skills/copilot-config/SKILL.md)
|
|
79
|
+
— tuning Copilot output and suppressing review noise.
|
|
80
|
+
- [`docs/installation.md`](../../installation.md) — install matrix index.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Cursor Setup
|
|
2
|
+
|
|
3
|
+
Cursor reads two rule formats:
|
|
4
|
+
|
|
5
|
+
- **Modern (`.mdc`)** — `.cursor/rules/<rule>.mdc` with YAML frontmatter
|
|
6
|
+
(`description`, `globs`, `alwaysApply`). Preferred for any 2025+
|
|
7
|
+
Cursor build.
|
|
8
|
+
- **Legacy (`.cursorrules`)** — single-file aggregate at the repo root.
|
|
9
|
+
Still read by older Cursor versions; the package keeps it for
|
|
10
|
+
backward compatibility.
|
|
11
|
+
|
|
12
|
+
The package ships **both** so you don't have to pick.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- Cursor 0.45+ (any 2025/2026 build): <https://cursor.com>.
|
|
17
|
+
- Node.js ≥ 18.
|
|
18
|
+
|
|
19
|
+
## Project install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx @event4u/create-agent-config init --tools=cursor
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This populates:
|
|
26
|
+
|
|
27
|
+
- `.cursor/rules/*.mdc` — one file per rule, modern frontmatter format
|
|
28
|
+
- `.cursor/commands/*.md` — slash commands mirrored from `.agent-src/commands/`
|
|
29
|
+
- `.cursorrules` — legacy single-file aggregate
|
|
30
|
+
- `.agent-settings.yml` — per-project knobs
|
|
31
|
+
|
|
32
|
+
Combine surfaces if you use both Cursor and Claude Code:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx @event4u/create-agent-config init --tools=cursor,claude-code
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Global install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx @event4u/agent-config global --tools=cursor
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Seeds `~/.cursor/rules/imported/event4u/` with the curated kernel +
|
|
45
|
+
top-N skills. Cursor merges global + workspace rules — workspace wins
|
|
46
|
+
on conflicts.
|
|
47
|
+
|
|
48
|
+
## Modern `.mdc` frontmatter
|
|
49
|
+
|
|
50
|
+
Each `.mdc` file has the Cursor-shaped header:
|
|
51
|
+
|
|
52
|
+
```mdc
|
|
53
|
+
---
|
|
54
|
+
description: Scope control — no unsolicited architectural changes
|
|
55
|
+
globs:
|
|
56
|
+
alwaysApply: true
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
# Scope Control
|
|
60
|
+
...
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- `alwaysApply: true` ↔ source `type: "always"` (kernel rules).
|
|
64
|
+
- `alwaysApply: false` ↔ Cursor model decides per turn (auto rules).
|
|
65
|
+
- `globs:` is intentionally empty in the package's projection — apply
|
|
66
|
+
per-rule if you need path-scoped rules in your fork.
|
|
67
|
+
|
|
68
|
+
## Cursor commands
|
|
69
|
+
|
|
70
|
+
`.cursor/commands/<slug>.md` mirrors `.claude/commands/`. Nested
|
|
71
|
+
clusters (e.g. `council/default.md`) flatten to `council-default.md` so
|
|
72
|
+
Cursor's command palette stays flat.
|
|
73
|
+
|
|
74
|
+
## Marketplace install (planned — Phase 7 / S35)
|
|
75
|
+
|
|
76
|
+
The Cursor marketplace listing is filed in
|
|
77
|
+
`road-to-simplicity-and-everywhere.md` Phase 7. Once accepted you'll
|
|
78
|
+
be able to install via Cursor's Extensions panel without `npx`.
|
|
79
|
+
|
|
80
|
+
## MCP block (when MCP Phase 3 ships)
|
|
81
|
+
|
|
82
|
+
Add to `.cursor/mcp.json` (Cursor's project-scoped MCP config):
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"mcpServers": {
|
|
87
|
+
"event4u-agent-config": {
|
|
88
|
+
"command": "npx",
|
|
89
|
+
"args": ["-y", "@event4u/agent-config-mcp"]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Track <https://github.com/event4u-app/agent-config> for the actual
|
|
96
|
+
release tag — until `road-to-mcp-full-coverage` Phase 3 ships, this
|
|
97
|
+
block is informational.
|
|
98
|
+
|
|
99
|
+
## Verification
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
ls -la .cursor/rules/ | head -5 # *.mdc files exist
|
|
103
|
+
ls -la .cursor/commands/| head -5 # *.md command files exist
|
|
104
|
+
test -f .cursorrules # legacy aggregate exists
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
In Cursor itself: open the chat panel — settings should show the rules
|
|
108
|
+
under **Project Rules**.
|
|
109
|
+
|
|
110
|
+
## Troubleshooting
|
|
111
|
+
|
|
112
|
+
| Symptom | Fix |
|
|
113
|
+
|---|---|
|
|
114
|
+
| Rules not picked up | Cursor < 0.45 — upgrade or rely on `.cursorrules`. |
|
|
115
|
+
| Modern + legacy duplicate triggers | Disable `.cursorrules` in Cursor settings. |
|
|
116
|
+
| Command missing in palette | `task generate-tools` then reload Cursor window. |
|
|
117
|
+
| Global rules ignored | Cursor needs `~/.cursor/rules/` — check OS path expansion. |
|
|
118
|
+
|
|
119
|
+
## Cross-references
|
|
120
|
+
|
|
121
|
+
- [`docs/installation.md`](../../installation.md) — install matrix index.
|
|
122
|
+
- [`AGENTS.md`](../../../AGENTS.md) — package self-orientation; Cursor
|
|
123
|
+
reads it via the projected rules.
|
|
124
|
+
- [`templates/cursor-rule.mdc.j2`](../../../templates/cursor-rule.mdc.j2) —
|
|
125
|
+
template used by the projection generator.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Gemini CLI Setup
|
|
2
|
+
|
|
3
|
+
Google's Gemini CLI reads `GEMINI.md` (which is a symlink to `AGENTS.md`
|
|
4
|
+
in the package's projection) for project context.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
- Gemini CLI installed: <https://github.com/google-gemini/gemini-cli>.
|
|
9
|
+
- Node.js ≥ 18 (for the install entrypoints).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @event4u/create-agent-config init --tools=gemini
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Populates:
|
|
18
|
+
|
|
19
|
+
- `GEMINI.md` → `AGENTS.md` — symlink so Gemini CLI loads the same
|
|
20
|
+
self-orientation as Codex / Aider / Augment.
|
|
21
|
+
- `AGENTS.md` — canonical content (single source of truth).
|
|
22
|
+
- `.agent-settings.yml` — per-project knobs.
|
|
23
|
+
|
|
24
|
+
## Verification
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
test -L GEMINI.md && readlink GEMINI.md # → AGENTS.md
|
|
28
|
+
gemini --version # confirm CLI installed
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
In a Gemini CLI session: `GEMINI.md` informs every turn — verify by
|
|
32
|
+
asking *"what is this repo?"* and confirming the answer matches
|
|
33
|
+
`AGENTS.md`'s emergency-triage block.
|
|
34
|
+
|
|
35
|
+
## Troubleshooting
|
|
36
|
+
|
|
37
|
+
| Symptom | Fix |
|
|
38
|
+
|---|---|
|
|
39
|
+
| Gemini CLI doesn't see `GEMINI.md` | Some Gemini versions require absolute paths — `gemini --context $(pwd)/GEMINI.md`. |
|
|
40
|
+
| Symlink broken on Windows | Re-run installer; on Windows the projection may emit a copy instead of a symlink. |
|
|
41
|
+
|
|
42
|
+
## Cross-references
|
|
43
|
+
|
|
44
|
+
- [`AGENTS.md`](../../../AGENTS.md) — canonical agent self-orientation.
|
|
45
|
+
- [`docs/installation.md`](../../installation.md) — install matrix index.
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Windsurf Setup
|
|
2
|
+
|
|
3
|
+
Windsurf reads two rule formats:
|
|
4
|
+
|
|
5
|
+
- **Wave-8 (`.windsurf/rules/`)** — per-rule `.md` files with
|
|
6
|
+
`trigger`, `description`, `globs` frontmatter. Preferred for
|
|
7
|
+
Windsurf 1.5+.
|
|
8
|
+
- **Legacy (`.windsurfrules`)** — single-file aggregate at the repo
|
|
9
|
+
root. Older Windsurf builds and the Cascade chat fallback both still
|
|
10
|
+
read it.
|
|
11
|
+
|
|
12
|
+
The package ships **both**.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- Windsurf 1.0+ (Codeium): <https://codeium.com/windsurf>.
|
|
17
|
+
- Node.js ≥ 18.
|
|
18
|
+
|
|
19
|
+
## Project install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx @event4u/create-agent-config init --tools=windsurf
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Populates:
|
|
26
|
+
|
|
27
|
+
- `.windsurf/rules/*.md` — modern Wave-8 per-rule files
|
|
28
|
+
- `.windsurf/workflows/*.md` — slash-command workflows
|
|
29
|
+
- `.windsurfrules` — legacy single-file aggregate
|
|
30
|
+
- `.agent-settings.yml` — per-project knobs
|
|
31
|
+
|
|
32
|
+
Combine with other surfaces:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx @event4u/create-agent-config init --tools=windsurf,claude-code,cursor
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Global install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx @event4u/agent-config global --tools=windsurf
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Seeds `~/.codeium/windsurf/global_workflows/` with the curated
|
|
45
|
+
workflow set (see [`templates/global-install-manifest.yml`](../../../templates/global-install-manifest.yml)).
|
|
46
|
+
Available across every project; per-workspace `.windsurf/workflows/`
|
|
47
|
+
takes precedence on slug collisions.
|
|
48
|
+
|
|
49
|
+
## Wave-8 frontmatter
|
|
50
|
+
|
|
51
|
+
Each rule under `.windsurf/rules/` has the Windsurf-shaped header:
|
|
52
|
+
|
|
53
|
+
```md
|
|
54
|
+
---
|
|
55
|
+
trigger: always_on
|
|
56
|
+
description: Scope control — no unsolicited architectural changes
|
|
57
|
+
globs:
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
# Scope Control
|
|
61
|
+
...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- `trigger: always_on` ↔ source `type: "always"` (kernel rules).
|
|
65
|
+
- `trigger: model_decision` ↔ Cascade decides per turn (auto rules).
|
|
66
|
+
- `globs:` is intentionally empty in the package's projection — set
|
|
67
|
+
per-rule in your fork if you want path-scoped triggering.
|
|
68
|
+
|
|
69
|
+
## Workflows
|
|
70
|
+
|
|
71
|
+
`.windsurf/workflows/<slug>.md` mirrors `.claude/commands/`. Cluster
|
|
72
|
+
commands flatten to `<cluster>-<name>.md`. Cascade lists all workflow
|
|
73
|
+
files in its workflow palette.
|
|
74
|
+
|
|
75
|
+
## Cascade integration
|
|
76
|
+
|
|
77
|
+
Cascade (Windsurf's built-in agent) reads `.windsurf/rules/` and
|
|
78
|
+
`.windsurf/workflows/` automatically. No separate registration step is
|
|
79
|
+
needed once the files are on disk.
|
|
80
|
+
|
|
81
|
+
When Cascade asks a clarifying question, the package's `user-interaction`
|
|
82
|
+
rule (kernel, `always_on`) applies — Cascade will surface numbered
|
|
83
|
+
options with a single recommendation.
|
|
84
|
+
|
|
85
|
+
## Workspace vs global precedence
|
|
86
|
+
|
|
87
|
+
| Layer | Path | Precedence |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| Workspace | `.windsurf/rules/` + `.windsurf/workflows/` | wins on conflicts |
|
|
90
|
+
| Global | `~/.codeium/windsurf/global_workflows/` | falls back when workspace silent |
|
|
91
|
+
|
|
92
|
+
Reuse the same `--tools=windsurf` flag for both — `init` writes
|
|
93
|
+
workspace, `global` writes user-level.
|
|
94
|
+
|
|
95
|
+
## Verification
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
ls .windsurf/rules/ | head -5 # *.md per-rule files
|
|
99
|
+
ls .windsurf/workflows/ | head -5 # *.md workflow files
|
|
100
|
+
test -f .windsurfrules # legacy aggregate exists
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
In Windsurf itself: open Cascade → Workflows panel — listed workflows
|
|
104
|
+
should match `ls .windsurf/workflows/`.
|
|
105
|
+
|
|
106
|
+
## Troubleshooting
|
|
107
|
+
|
|
108
|
+
| Symptom | Fix |
|
|
109
|
+
|---|---|
|
|
110
|
+
| Rules not picked up | Windsurf < 1.0 — upgrade or rely on `.windsurfrules`. |
|
|
111
|
+
| Workflow not in Cascade panel | Reload window after `task generate-tools`. |
|
|
112
|
+
| Global workflows missing | Check `~/.codeium/windsurf/global_workflows/` exists. |
|
|
113
|
+
| Frontmatter parse error | Re-run `python3 scripts/compress.py --generate-tools`. |
|
|
114
|
+
|
|
115
|
+
## Cross-references
|
|
116
|
+
|
|
117
|
+
- [`docs/installation.md`](../../installation.md) — install matrix index.
|
|
118
|
+
- [`templates/windsurf-rule.md.j2`](../../../templates/windsurf-rule.md.j2)
|
|
119
|
+
— template used by the projection generator.
|
|
120
|
+
- [`AGENTS.md`](../../../AGENTS.md) — package self-orientation.
|
package/package.json
CHANGED
package/scripts/compress.py
CHANGED
|
@@ -26,6 +26,8 @@ import shutil
|
|
|
26
26
|
import sys
|
|
27
27
|
from pathlib import Path
|
|
28
28
|
|
|
29
|
+
import yaml
|
|
30
|
+
|
|
29
31
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
30
32
|
from _lib.script_output import info, success, flush_summary, resolve_level # noqa: E402
|
|
31
33
|
|
|
@@ -503,6 +505,149 @@ def generate_windsurfrules() -> int:
|
|
|
503
505
|
return len(rules)
|
|
504
506
|
|
|
505
507
|
|
|
508
|
+
# ── Modern editor formats (road-to-simplicity-and-everywhere Phase 5) ─
|
|
509
|
+
# Cursor `.cursor/rules/*.mdc` (frontmatter: description, globs,
|
|
510
|
+
# alwaysApply) and Windsurf `.windsurf/rules/*.md` (frontmatter:
|
|
511
|
+
# trigger, description, globs) are the formats current editors prefer.
|
|
512
|
+
# Legacy `.windsurfrules` aggregate stays for users who prefer it.
|
|
513
|
+
|
|
514
|
+
CURSOR_RULES_MDC_DIR = PROJECT_ROOT / ".cursor" / "rules"
|
|
515
|
+
WINDSURF_RULES_DIR = PROJECT_ROOT / ".windsurf" / "rules"
|
|
516
|
+
WINDSURF_WORKFLOWS_DIR = PROJECT_ROOT / ".windsurf" / "workflows"
|
|
517
|
+
CURSOR_COMMANDS_DIR = PROJECT_ROOT / ".cursor" / "commands"
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
def _parse_frontmatter(content: str) -> tuple[dict, str]:
|
|
521
|
+
"""Split a `---`-delimited YAML frontmatter from the body."""
|
|
522
|
+
if not content.startswith("---"):
|
|
523
|
+
return {}, content
|
|
524
|
+
end = content.find("\n---", 3)
|
|
525
|
+
if end == -1:
|
|
526
|
+
return {}, content
|
|
527
|
+
raw = content[3:end].strip()
|
|
528
|
+
body = content[end + 4:].lstrip("\n")
|
|
529
|
+
try:
|
|
530
|
+
meta = yaml.safe_load(raw) or {}
|
|
531
|
+
except yaml.YAMLError:
|
|
532
|
+
meta = {}
|
|
533
|
+
return meta if isinstance(meta, dict) else {}, body
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
def _emit_cursor_mdc(source: Path, target: Path) -> None:
|
|
537
|
+
"""Write a Cursor `.mdc` file with Cursor-shaped frontmatter."""
|
|
538
|
+
meta, body = _parse_frontmatter(source.read_text())
|
|
539
|
+
description = (meta.get("description") or "").replace("\n", " ").strip()
|
|
540
|
+
always_apply = bool(meta.get("alwaysApply") or meta.get("type") == "always")
|
|
541
|
+
lines = [
|
|
542
|
+
"---",
|
|
543
|
+
f"description: {description}",
|
|
544
|
+
"globs: ",
|
|
545
|
+
f"alwaysApply: {'true' if always_apply else 'false'}",
|
|
546
|
+
"---",
|
|
547
|
+
"",
|
|
548
|
+
body.rstrip() + "\n",
|
|
549
|
+
]
|
|
550
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
551
|
+
target.write_text("\n".join(lines))
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def _emit_windsurf_rule(source: Path, target: Path) -> None:
|
|
555
|
+
"""Write a Windsurf rule with Wave-8 frontmatter (trigger/description/globs)."""
|
|
556
|
+
meta, body = _parse_frontmatter(source.read_text())
|
|
557
|
+
description = (meta.get("description") or "").replace("\n", " ").strip()
|
|
558
|
+
always_apply = bool(meta.get("alwaysApply") or meta.get("type") == "always")
|
|
559
|
+
trigger = "always_on" if always_apply else "model_decision"
|
|
560
|
+
lines = [
|
|
561
|
+
"---",
|
|
562
|
+
f"trigger: {trigger}",
|
|
563
|
+
f"description: {description}",
|
|
564
|
+
"globs: ",
|
|
565
|
+
"---",
|
|
566
|
+
"",
|
|
567
|
+
body.rstrip() + "\n",
|
|
568
|
+
]
|
|
569
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
570
|
+
target.write_text("\n".join(lines))
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def _clean_modern_dir(target_dir: Path, valid_names: set[str]) -> None:
|
|
574
|
+
"""Drop files in `target_dir` whose names are not in `valid_names`."""
|
|
575
|
+
if not target_dir.exists():
|
|
576
|
+
return
|
|
577
|
+
for item in target_dir.iterdir():
|
|
578
|
+
if item.name == "README.md":
|
|
579
|
+
continue
|
|
580
|
+
if item.name not in valid_names:
|
|
581
|
+
if item.is_dir() and not item.is_symlink():
|
|
582
|
+
shutil.rmtree(item)
|
|
583
|
+
else:
|
|
584
|
+
item.unlink()
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
def generate_cursor_mdc_rules() -> int:
|
|
588
|
+
"""Emit `.cursor/rules/*.mdc` per source rule (alongside legacy `.md` symlinks)."""
|
|
589
|
+
rules = sorted(RULES_SOURCE.glob("*.md"))
|
|
590
|
+
valid = {f"{r.stem}.mdc" for r in rules}
|
|
591
|
+
_clean_modern_dir(CURSOR_RULES_MDC_DIR, valid | {r.name for r in rules})
|
|
592
|
+
for rule in rules:
|
|
593
|
+
_emit_cursor_mdc(rule, CURSOR_RULES_MDC_DIR / f"{rule.stem}.mdc")
|
|
594
|
+
info(f" ✅ Wrote {len(rules)} `.cursor/rules/*.mdc` files")
|
|
595
|
+
return len(rules)
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
def generate_windsurf_modern_rules() -> int:
|
|
599
|
+
"""Emit `.windsurf/rules/*.md` per source rule (Wave-8 frontmatter)."""
|
|
600
|
+
rules = sorted(RULES_SOURCE.glob("*.md"))
|
|
601
|
+
valid = {r.name for r in rules}
|
|
602
|
+
_clean_modern_dir(WINDSURF_RULES_DIR, valid)
|
|
603
|
+
for rule in rules:
|
|
604
|
+
_emit_windsurf_rule(rule, WINDSURF_RULES_DIR / rule.name)
|
|
605
|
+
info(f" ✅ Wrote {len(rules)} `.windsurf/rules/*.md` files")
|
|
606
|
+
return len(rules)
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
def generate_cursor_commands() -> int:
|
|
610
|
+
"""Symlink `.cursor/commands/<slug>.md` per source command."""
|
|
611
|
+
if not COMMANDS_SOURCE.exists():
|
|
612
|
+
return 0
|
|
613
|
+
cmds = list(_iter_commands())
|
|
614
|
+
valid = {f"{slug}.md" for _, slug in cmds}
|
|
615
|
+
_clean_modern_dir(CURSOR_COMMANDS_DIR, valid)
|
|
616
|
+
CURSOR_COMMANDS_DIR.mkdir(parents=True, exist_ok=True)
|
|
617
|
+
count = 0
|
|
618
|
+
for source_file, slug in cmds:
|
|
619
|
+
link = CURSOR_COMMANDS_DIR / f"{slug}.md"
|
|
620
|
+
if link.exists() or link.is_symlink():
|
|
621
|
+
link.unlink()
|
|
622
|
+
rel = Path("../../.agent-src/commands") / source_file.relative_to(COMMANDS_SOURCE)
|
|
623
|
+
link.symlink_to(rel)
|
|
624
|
+
count += 1
|
|
625
|
+
info(f" ✅ Linked {count} `.cursor/commands/*.md` files")
|
|
626
|
+
return count
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
def generate_windsurf_workflows() -> int:
|
|
630
|
+
"""Symlink `.windsurf/workflows/<slug>.md` per source command."""
|
|
631
|
+
if not COMMANDS_SOURCE.exists():
|
|
632
|
+
return 0
|
|
633
|
+
cmds = list(_iter_commands())
|
|
634
|
+
valid = {f"{slug}.md" for _, slug in cmds}
|
|
635
|
+
_clean_modern_dir(WINDSURF_WORKFLOWS_DIR, valid)
|
|
636
|
+
WINDSURF_WORKFLOWS_DIR.mkdir(parents=True, exist_ok=True)
|
|
637
|
+
count = 0
|
|
638
|
+
for source_file, slug in cmds:
|
|
639
|
+
link = WINDSURF_WORKFLOWS_DIR / f"{slug}.md"
|
|
640
|
+
if link.exists() or link.is_symlink():
|
|
641
|
+
link.unlink()
|
|
642
|
+
rel = Path("../../.agent-src/commands") / source_file.relative_to(COMMANDS_SOURCE)
|
|
643
|
+
link.symlink_to(rel)
|
|
644
|
+
count += 1
|
|
645
|
+
info(f" ✅ Linked {count} `.windsurf/workflows/*.md` files")
|
|
646
|
+
return count
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
506
651
|
def generate_gemini_md() -> None:
|
|
507
652
|
"""Create GEMINI.md symlink to AGENTS.md."""
|
|
508
653
|
link = PROJECT_ROOT / "GEMINI.md"
|
|
@@ -695,9 +840,15 @@ def generate_tools() -> None:
|
|
|
695
840
|
skills = generate_claude_skills()
|
|
696
841
|
commands = generate_claude_commands()
|
|
697
842
|
personas = generate_persona_symlinks()
|
|
843
|
+
cursor_mdc = generate_cursor_mdc_rules()
|
|
844
|
+
windsurf_modern = generate_windsurf_modern_rules()
|
|
845
|
+
cursor_cmds = generate_cursor_commands()
|
|
846
|
+
windsurf_wf = generate_windsurf_workflows()
|
|
698
847
|
summary = (
|
|
699
848
|
f"✅ generate-tools — rules={rules} skills={skills} "
|
|
700
|
-
f"commands={commands} personas={personas}"
|
|
849
|
+
f"commands={commands} personas={personas} "
|
|
850
|
+
f"cursor_mdc={cursor_mdc} windsurf_rules={windsurf_modern} "
|
|
851
|
+
f"cursor_commands={cursor_cmds} windsurf_workflows={windsurf_wf}"
|
|
701
852
|
)
|
|
702
853
|
if resolve_level() == "verbose":
|
|
703
854
|
print(f"\n{summary}")
|
|
@@ -806,6 +957,7 @@ def clean_tools() -> None:
|
|
|
806
957
|
PROJECT_ROOT / ".claude",
|
|
807
958
|
PROJECT_ROOT / ".cursor",
|
|
808
959
|
PROJECT_ROOT / ".clinerules",
|
|
960
|
+
PROJECT_ROOT / ".windsurf",
|
|
809
961
|
PROJECT_ROOT / ".windsurfrules",
|
|
810
962
|
PROJECT_ROOT / "GEMINI.md",
|
|
811
963
|
]
|