You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .cursor/rules/SimHub.mdc
+2-1Lines changed: 2 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -58,11 +58,12 @@ alwaysApply: false
58
58
59
59
## Deployment & Testing
60
60
61
-
- **No deploy without 100% passing tests.** The `deploy.ps1` script enforces this: build must succeed, `dotnet test` must pass (if test projects exist), and post-deploy scripts in `tests/` must exit 0.
61
+
- **No deploy without 100% passing tests.** The `deploy.ps1` script enforces this: build must succeed, `dotnet test` must pass (if test projects exist), and post-deploy scripts in `tests/` must exit 0. **`deploy.ps1` always copies all dashboard `*.html` from `src/SimSteward.Dashboard/` to `SimHub\Web\sim-steward-dash\`** (verified after copy); “deploy” includes dashboards, not DLLs-only.
62
62
- **Retry-once-then-stop rule**: when a test or build fails, the agent gets **one** additional attempt to fix and rerun. If it fails again, **hard stop** — do not keep iterating. Either halt the deploy entirely (if downstream work depends on it) or skip and move on to the next independent task.
63
63
- **Linter checks** (`ReadLints`) on edited files must show 0 new errors before committing or deploying.
- See `.cursor/skills/simsteward-deploy/SKILL.md` for the full deploy workflow and test phase details.
66
+
- **`deploy.ps1` prints plugin build id** (`=== SimSteward plugin version (deployed): … ===`, then `Deploy complete. Plugin version: …`). When the user asks the agent to run deploy, **repeat that version in the reply** (same string as WebSocket `state.pluginVersion`).
-**Concepts / “what files matter”:**`search` with `mode``semantic`, `hybrid`, or `auto` — not `graph` for keyword or content lookup.
20
+
-**Structure / deps / usages:**`graph` actions (`related`, `dependencies`, `impact`, `usages`, `call_path`, `path`, etc.) — not a substitute for text search; use **after**`search` narrows targets when you need edges.
21
+
-**C# / SimStewardPlugin:** Smoke tests (`graph(dependencies)` on `src/SimSteward.Plugin/SimStewardPlugin.cs`) may return **0 edges** — do not assume a rich C# call graph. Prefer **`search`** plus the **Code map** table at the top of [docs/ARCHITECTURE.md](../../docs/ARCHITECTURE.md) for module ↔ file mapping.
22
+
-**Corpus:** Rely on `project(action="index_status")` / `ingest_local` so both search and graph see the repo. After large refactors or if structural queries look empty or wrong, run **`graph(action="ingest", wait=true)`** (or queue ingest and retry later).
23
+
24
+
## Corpus hygiene (Cursor vs ContextStream)
25
+
-**[`.cursorignore`](../../.cursorignore)** reduces noise for **Cursor** (plans, build outputs, `.claude/projects/`, `.claude/file-history/`, etc.). It is **not guaranteed** to be applied by ContextStream server ingest; treat it as **local IDE** hygiene plus a signal for what should not dominate embeddings.
26
+
-**Refresh remote index:**`npm run contextstream:ingest:force` from repo root (runs [scripts/contextstream-ingest.ps1](../../scripts/contextstream-ingest.ps1)`-Force`), or MCP **`project(action="ingest_local", path="<repo>", force=true)`**. Poll **`project(action="index_status")`** until idle/fresh.
27
+
28
+
## Workspace binding (mapping quality)
29
+
- Open **only** this repo root as the Cursor workspace when doing ContextStream-heavy work (avoids cross-root hits under unrelated paths).
30
+
- Keep the ContextStream **project** path aligned with that same folder.
31
+
32
+
## When to force ingest
33
+
- After **`.cursorignore`** edits, **large moves** under `src/`, **architecture doc** reshuffles, or when **`index_status`** / search results look **stale** or polluted. Then: `contextstream:ingest:force` and optionally `graph(ingest, wait=true)`.
34
+
35
+
## Context and search density
36
+
-**`context`:** Default before tools: `format="minified"`, `max_tokens=100`, `mode="fast"` for quick turns. For deep refactors or broad changes, raise **`max_tokens`** toward **200–400** and/or use full `context(...)` without `fast`. Use **`distill=true`** or **`mode="pack"`** when the session is long or the pack must shrink; optional **`session_tokens`** / **`context_threshold`** when the client tracks cumulative usage.
37
+
-**`search`:** Prefer **`output_format`**`minimal` or `paths`; default **`limit`****3–5** unless you need exhaustive hits. Lower **`content_max_chars`** when you only need locations; add **`context_lines`** when you need local snippet context around matches.
38
+
-**Long threads:** Keep **`session(action="compress")`** after 30+ turns or milestones (see Maintenance).
39
+
40
+
## Deploy + plugin version (agents)
41
+
- When the user asks to **run deploy** (`deploy.ps1`), run it and **quote the plugin version** from script output: the cyan line `=== SimSteward plugin version (deployed): … ===` and/or the final `Deploy complete. Plugin version: …`. Same value is WebSocket `state.pluginVersion` and Loki `deploy_marker` JSON `detail` suffix `pluginVersion=…`.
42
+
-**Memory (semantic):** Prefer `memory(action="create_node", node_type="fact", …)` for durable deploy/testing facts; tag `simsteward`, `deploy`, `testing` when relevant.
43
+
18
44
## Operations
19
45
-**Plans:** ALWAYS `session(action="capture_plan")` + `memory(action="create_task")`. NO markdown files.
20
-
-**Repo ↔ ContextStream sync:** Use MCP **`project(action="index")`** or **`project(action="ingest_local", path="…")`** — the server-side ingest/index task. Do**not**sync via custom HTTP/API scripts, committed JSON arg files, or non-MCP CLI automation (see `docs/CONTEXTSTREAM-UPLOAD-PLAN.md`). After a sync, log with **`session(action="capture", event_type="operation", …)`**.
46
+
-**Repo ↔ ContextStream sync:** Use MCP **`project(action="index")`** or **`project(action="ingest_local", path="…")`** — the server-side ingest/index task. Prefer**`npm run contextstream:ingest[:force]`**for CLI ingest with `.env` via envmcp. Do **not** sync via ad-hoc HTTP clients or committed JSON payload dumps. After a sync, log with **`session(action="capture", event_type="operation", …)`**.
21
47
-**Optional Memory mirror:**`memory(create_doc|update_doc)` only through MCP in Cursor when you intentionally duplicate a spec in Memory — not via external API clients.
Create Cursor rules for persistent AI guidance. Use when you want to create a
5
+
rule, add coding standards, set up project conventions, configure
6
+
file-specific patterns, create RULE.md files, or asks about .cursor/rules/ or
7
+
AGENTS.md.
8
+
---
9
+
# Creating Cursor Rules
10
+
11
+
Create project rules in `.cursor/rules/` to provide persistent context for the AI agent.
12
+
13
+
## Gather Requirements
14
+
15
+
Before creating a rule, determine:
16
+
17
+
1.**Purpose**: What should this rule enforce or teach?
18
+
2.**Scope**: Should it always apply, or only for specific files?
19
+
3.**File patterns**: If file-specific, which glob patterns?
20
+
21
+
### Inferring from Context
22
+
23
+
If you have previous conversation context, infer rules from what was discussed. You can create multiple rules if the conversation covers distinct topics or patterns. Don't ask redundant questions if the context already provides the answers.
24
+
25
+
### Required Questions
26
+
27
+
If the user hasn't specified scope, ask:
28
+
- "Should this rule always apply, or only when working with specific files?"
29
+
30
+
If they mentioned specific files and haven't provided concrete patterns, ask:
31
+
- "Which file patterns should this rule apply to?" (e.g., `**/*.ts`, `backend/**/*.py`)
32
+
33
+
It's very important that we get clarity on the file patterns.
34
+
35
+
Use the AskQuestion tool when available to gather this efficiently.
36
+
37
+
---
38
+
39
+
## Rule File Format
40
+
41
+
Rules are `.mdc` files in `.cursor/rules/` with YAML frontmatter:
42
+
43
+
```
44
+
.cursor/rules/
45
+
typescript-standards.mdc
46
+
react-patterns.mdc
47
+
api-conventions.mdc
48
+
```
49
+
50
+
### File Structure
51
+
52
+
```markdown
53
+
---
54
+
description: Brief description of what this rule does
55
+
globs: **/*.ts # File pattern for file-specific rules
56
+
alwaysApply: false # Set to true if rule should always apply
57
+
---
58
+
59
+
# Rule Title
60
+
61
+
Your rule content here...
62
+
```
63
+
64
+
### Frontmatter Fields
65
+
66
+
| Field | Type | Description |
67
+
|-------|------|-------------|
68
+
|`description`| string | What the rule does (shown in rule picker) |
69
+
|`globs`| string | File pattern - rule applies when matching files are open |
70
+
|`alwaysApply`| boolean | If true, applies to every session |
71
+
72
+
---
73
+
74
+
## Rule Configurations
75
+
76
+
### Always Apply
77
+
78
+
For universal standards that should apply to every conversation:
79
+
80
+
```yaml
81
+
---
82
+
description: Core coding standards for the project
83
+
alwaysApply: true
84
+
---
85
+
```
86
+
87
+
### Apply to Specific Files
88
+
89
+
For rules that apply when working with certain file types:
90
+
91
+
```yaml
92
+
---
93
+
description: TypeScript conventions for this project
94
+
globs: **/*.ts
95
+
alwaysApply: false
96
+
---
97
+
```
98
+
99
+
---
100
+
101
+
## Best Practices
102
+
103
+
### Keep Rules Concise
104
+
105
+
-**Under 50 lines**: Rules should be concise and to the point
106
+
-**One concern per rule**: Split large rules into focused pieces
107
+
-**Actionable**: Write like clear internal docs
108
+
-**Concrete examples**: Ideally provide concrete examples of how to fix issues
109
+
110
+
---
111
+
112
+
## Example Rules
113
+
114
+
### TypeScript Standards
115
+
116
+
```markdown
117
+
---
118
+
description: TypeScript coding standards
119
+
globs: **/*.ts
120
+
alwaysApply: false
121
+
---
122
+
123
+
# Error Handling
124
+
125
+
\`\`\`typescript
126
+
// ❌ BAD
127
+
try {
128
+
await fetchData();
129
+
} catch (e) {}
130
+
131
+
// ✅ GOOD
132
+
try {
133
+
await fetchData();
134
+
} catch (e) {
135
+
logger.error('Failed to fetch', { error: e });
136
+
throw new DataFetchError('Unable to retrieve data', { cause: e });
0 commit comments