claude-dev-env 1.19.3 → 1.21.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/CLAUDE.md ADDED
@@ -0,0 +1,43 @@
1
+ # Claude Development Assistant
2
+
3
+ ## Code Rules (NON-NEGOTIABLE)
4
+ @~/.claude/docs/CODE_RULES.md
5
+
6
+ ## Core Philosophy
7
+
8
+ **TDD IS NON-NEGOTIABLE.** Build it right, build it simple. Maintainable > Clever.
9
+
10
+ ## Working with Claude
11
+
12
+ ### Expectations
13
+
14
+ 1. **ALWAYS FOLLOW TDD** - No production code without failing test
15
+ 2. **MANDATORY SELF-CHECK before proposing** - See protocol below
16
+ 3. Assess refactoring after every green
17
+
18
+ ### Mandatory Self-Check Protocol
19
+
20
+ **BEFORE proposing plans/implementation:**
21
+
22
+ ☐ Project rules review (e.g. Tasklings `tasklings-preferences` when in that repo path)
23
+ ☐ "Is this KISS?" (simplest? unnecessary complexity?)
24
+ ☐ "Over-engineering?" (multiple files? premature abstractions?)
25
+ ☐ Test infrastructure? (ONE file, functions, YAGNI)
26
+ ☐ Tests add value? (no existence checks, no constant tests)
27
+
28
+ ## Pre-PR Submission Checklist
29
+
30
+ **Run `/check-pr` OR verify:**
31
+ - ☐ KISS / preferences (multiple requirements.txt? over-engineered?)
32
+ - ☐ KISS (simplest? one file? functions not classes?)
33
+ - ☐ Files (proper modules, correct dirs, no empty __init__.py)
34
+ - ☐ Quality (no dupes, types complete, no Any/any)
35
+ - ☐ Tests (no existence checks, no constant value tests)
36
+ - ☐ Self-checked before proposing?
37
+
38
+ ## Compaction
39
+ When compacting, always preserve:
40
+ - Active task and current goal
41
+ - Full list of modified files
42
+ - Any failing test names or error messages
43
+ - Current git branch and PR state
package/bin/install.mjs CHANGED
@@ -13,7 +13,7 @@ const MANIFEST_FILE = join(CLAUDE_HOME, '.claude-dev-env-manifest.json');
13
13
  const PACKAGE_NAME = 'claude-dev-env';
14
14
  const packageRequire = createRequire(import.meta.url);
15
15
 
16
- const CONTENT_DIRECTORIES = ['rules', 'docs', 'commands', 'agents'];
16
+ const CONTENT_DIRECTORIES = ['rules', 'docs', 'commands', 'agents', 'system-prompts', 'scripts'];
17
17
 
18
18
  function resolveDependencyPackageRoot(dependencyPackageName) {
19
19
  const dependencyPackageJsonPath = packageRequire.resolve(
@@ -152,6 +152,23 @@ function copyTree(sourceBase, destBase) {
152
152
  return stats;
153
153
  }
154
154
 
155
+ /**
156
+ * If destPath exists and differs from incomingPath, copy the existing file to
157
+ * ~/.claude/backups/CLAUDE.md.<timestamp>.bak before the installer overwrites it.
158
+ */
159
+ function backupClaudeHubBeforeOverwrite(destPath, incomingPath) {
160
+ if (!existsSync(destPath)) return null;
161
+ const existingBytes = readFileSync(destPath);
162
+ const incomingBytes = readFileSync(incomingPath);
163
+ if (existingBytes.equals(incomingBytes)) return null;
164
+ const backupsDir = join(CLAUDE_HOME, 'backups');
165
+ mkdirSync(backupsDir, { recursive: true });
166
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
167
+ const backupPath = join(backupsDir, `CLAUDE.md.${stamp}.bak`);
168
+ copyFileSync(destPath, backupPath);
169
+ return backupPath;
170
+ }
171
+
155
172
  function mergeHooks(hooksSourceRoot, pythonCommand) {
156
173
  const hooksJsonPath = join(hooksSourceRoot, 'hooks', 'hooks.json');
157
174
  if (!existsSync(hooksJsonPath)) return 0;
@@ -338,6 +355,19 @@ function install(selectedGroups) {
338
355
  summary.hookGroups = totalHookGroups;
339
356
  console.log(` Hook groups: ${totalHookGroups} merged into settings.json`);
340
357
  }
358
+ const claudeHubSource = join(PACKAGE_ROOT, 'CLAUDE.md');
359
+ if (existsSync(claudeHubSource)) {
360
+ const claudeHubDest = join(CLAUDE_HOME, 'CLAUDE.md');
361
+ const backupPath = backupClaudeHubBeforeOverwrite(claudeHubDest, claudeHubSource);
362
+ if (backupPath) {
363
+ console.log(
364
+ ` \u21bb ${relative(CLAUDE_HOME, backupPath)} (previous CLAUDE.md hub preserved)`
365
+ );
366
+ }
367
+ copyFileSync(claudeHubSource, claudeHubDest);
368
+ allInstalledFiles.push(claudeHubDest);
369
+ console.log(` \u2713 ${relative(CLAUDE_HOME, claudeHubDest)} (hub)`);
370
+ }
341
371
  writeManifest(allInstalledFiles);
342
372
  console.log(`\nInstalled ${PACKAGE_NAME}:`);
343
373
  for (const directory of CONTENT_DIRECTORIES) {
@@ -423,6 +453,9 @@ Examples:
423
453
  npx ${PACKAGE_NAME} --only prompt-generator,research
424
454
 
425
455
  Install location: ~/.claude/
456
+
457
+ If ~/.claude/CLAUDE.md already exists and differs from the package copy, the installer
458
+ writes the previous contents to ~/.claude/backups/CLAUDE.md.<timestamp>.bak first.
426
459
  `);
427
460
  }
428
461
 
@@ -0,0 +1,53 @@
1
+ # BDD Discovery Protocol
2
+
3
+ This protocol guides Claude through **Example Mapping** to discover test ideas from user requests before writing code. Work **breadth-first**: map rules, examples, and unknowns first; park unresolved questions instead of guessing. Based on Smart & Molak *BDD in Action* §6.4 and Dan North, "Introducing BDD" (2006).
4
+
5
+ > §6.4.2: "The team discuss the rules and asks for an example of each. Examples are often described using a short phrase that starts with the words 'The one where ...' This notation, originally described by Daniel Terhorst-North, is known as the 'Friends episode notation', from the 90s TV series of the same name."
6
+
7
+ > §6.4.4: "Questions that can't be answered immediately are noted as pink cards."
8
+
9
+ > §6.4.5: "Example Mapping sessions should be quite short; 25–30 minutes is usually enough to get through a story."
10
+
11
+ ## Core algorithm
12
+
13
+ 1. **State the rule or feature** — Restate until the rule is clearly defined. *Exit:* shared understanding of what we are exploring.
14
+
15
+ 2. **Generate examples** — Produce 3–5 phrases using **"The one where …"** notation, simple to complex. *Exit:* examples cover the rule’s scope without duplicating the same case.
16
+
17
+ 3. **Probe the first unchecked example** — Ask: *What if …?* *Is this always the case?* *Are there examples where this rule behaves differently?* *Exit:* all three probes asked for this example.
18
+
19
+ 4. **Evaluate answers** — When a new rule emerges, return to Step 3 for that rule. New edge cases may become **new rules** (add 2–3 examples each). Questions you cannot answer become **parked items**. *Exit:* probes for this example are processed.
20
+
21
+ 5. **Next example** — Repeat steps 3–4. *Exit:* all examples probed.
22
+
23
+ 6. **Compile and confirm** — In steady state, present a full compile of rules, examples, and parking lot. Ask: "Does this Example Map cover the behavior you need? Any rules or examples to add, remove, or refine?" *Exit:* user confirms; exit when user confirms.
24
+
25
+ 7. **Time-box and exit** — Keep discovery within ~25–30 minutes when possible; also **exit** when tests are under way or the session ends.
26
+
27
+ > "What to call your test is easy: it's a sentence describing the next behaviour in which you are interested." — Dan North (2006)
28
+
29
+ ## Worked Example: Theme Asset Release Date Validation
30
+
31
+ - **Rule:** A theme asset must not go live before its configured release date.
32
+ - **Examples (the one where …):**
33
+ - … the release date is tomorrow and today’s import runs — should block or warn
34
+ - … the release date was last week — should allow publish
35
+ - … the release date field is empty — should use policy default
36
+ - … the release date is updated after a draft was already scheduled — should re-validate against policy
37
+ - **Probe:** *What if the server timezone is UTC but the editor is local?* → Surfaces a **new rule** about timezone for "release day."
38
+ - **New rule examples:** same calendar date in UTC vs local; DST boundary.
39
+ - **Parked:** certification API does not return a timezone — follow up with vendor.
40
+
41
+ ## Using This Protocol
42
+
43
+ - State the business rule clearly
44
+ - Generate concrete examples (the one where ...)
45
+ - Probe each example with three question forms
46
+ - Capture open questions as a parked list for later resolution
47
+ - Compile and confirm the Example Map with the user
48
+ - Proceed to test writing only after user approval
49
+
50
+ ## References
51
+
52
+ - Smart & Molak, *BDD in Action* 2e, Chapter 6, §6.4 (Example Mapping)
53
+ - Dan North, "Introducing BDD" (2006), https://dannorth.net/blog/introducing-bdd/
@@ -0,0 +1,89 @@
1
+ # BDD Scenario Quality Guide
2
+
3
+ This guide defines the seven patterns that make scenarios clear, focused, and testable, enabling teams to align on business behavior, merge ideas from shared examples, and verify outcomes with automation and review.
4
+
5
+ Source: Smart & Molak, *BDD in Action* 2e, Chapter 7.6 — scenario quality patterns.
6
+
7
+ ## Declarative Focus
8
+
9
+ Scenarios work best when they name what users want to achieve in the language of the business. Lead with goals and recognizable domain tasks so readers grasp intent at a glance. Reserve step-level or UI detail for places where it truly clarifies behavior.
10
+
11
+ > "Good scenarios model business behavior, not system interactions." — Smart & Molak §7.6.3
12
+
13
+ Good scenarios name user goals and tasks in domain language before any implementation detail.
14
+
15
+ ## Single-Rule Focus
16
+
17
+ Each scenario tests one business rule. When a rule is complex or a scenario grows hard to read, split it into smaller scenarios that each test one aspect of the rule. That keeps failures pointing to a single behavior.
18
+
19
+ > "Good scenarios focus on testing a single business rule. If a business rule is complex, or if a scenario gets too big and hard to read, a good trick is to break the scenario into smaller, more focused ones that test a specific aspect of the rule." — Smart & Molak §7.6.4
20
+
21
+ Good scenarios isolate one rule so failures point to a single behavior.
22
+
23
+ ### Example: hotel search (illustrates single-rule focus and declarative data)
24
+
25
+ This scenario shows one rule: search returns hotels within a distance threshold.
26
+
27
+ ```
28
+ Scenario: Search for available hotels by distance
29
+ Given the following hotels:
30
+ | Hotel Name | Location | Distance from center |
31
+ | Ritz | Paris | 3.2 |
32
+ | Savoy | Paris | 6.9 |
33
+ | Hilton | Paris | 12.5 |
34
+ When I search for a hotel within 10 km of Paris
35
+ Then I should be presented with the following hotels:
36
+ | Hotel Name | Location | Distance from center |
37
+ | Ritz | Paris | 3.2 |
38
+ | Savoy | Paris | 6.9 |
39
+ ```
40
+
41
+ ## Meaningful Actors
42
+
43
+ Personas ground scenarios in realistic goals and context. Use light soap-opera personas when you need depth before full UX research: introduce names and roles as needed and deepen them across scenarios.
44
+
45
+ > Smart & Molak §7.6.5 describe personas as rich, realistic descriptions: each persona captures goals, abilities, and background information that ground the test scenario in a real user context.
46
+
47
+ Good scenarios name who acts and what they need in plain language.
48
+
49
+ ## Essential Detail
50
+
51
+ Include columns and fields that affect the outcome; verify each column contributes, and simplify tables where values repeat or stay neutral to the result. Every visible value should earn its place in the example.
52
+
53
+ > Smart & Molak §7.6.6 — essential detail is information directly relevant to the business rule.
54
+
55
+ Good scenarios tie every field to a value that changes the outcome.
56
+
57
+ ## State Clarity
58
+
59
+ When examples use data to illustrate behavior, spell out the starting situation and the expected end state in the same breath. Set up or reference test data so the system begins in the expected initial state before the action. Readers should always see both the before and after picture when data carries the story.
60
+
61
+ > "Well-written scenarios describe both behavior and data. When a scenario uses data to illustrate behavior, it should describe the initial state and the final state and manage or set up the test data to ensure that the system is in the expected initial state." — Smart & Molak §7.6.6
62
+
63
+ Good scenarios state initial and final state when data illustrates behavior.
64
+
65
+ ## Outcome Description
66
+
67
+ Well-written scenarios state target outcomes in clear, measurable terms any reader can verify—business results observers can confirm directly in the Then steps.
68
+
69
+ > Smart & Molak §7.6.7 — scenarios state outcomes observers can confirm.
70
+
71
+ Good scenarios describe observable outcomes in domain terms.
72
+
73
+ ## Independence
74
+
75
+ Each scenario sets up its own data and system state so it can run alone; give every scenario a self-contained setup so the suite passes in any run order. Every scenario carries its own setup and makes preconditions explicit.
76
+
77
+ > Smart & Molak §7.6.8 — independent scenarios work in isolation.
78
+
79
+ Good scenarios carry their own setup and expose every precondition needed to run in any order.
80
+
81
+ ## Quick Reference
82
+
83
+ - ✓ Scenarios describe user goals and business tasks in domain terms
84
+ - ✓ Each scenario tests one business rule
85
+ - ✓ Actors have recognizable goals and context
86
+ - ✓ Tables and fields carry the information that affects the outcome
87
+ - ✓ Initial and final state are clear when data matters
88
+ - ✓ Outcomes are unambiguous and measurable
89
+ - ✓ Scenarios run independently with their own data
@@ -0,0 +1,71 @@
1
+ # BDD Test Layout and Personas
2
+
3
+ Tests are **technical documentation**: they should read clearly when you return to the codebase after time away. Organize by **behavior and functional slice**, not necessarily by mirroring production file paths, when that aids navigation.
4
+
5
+ For future readers, tests read as documentation: names, grouping, and **should** sentences should make behavior discoverable without opening production code first.
6
+
7
+ > "Many organizations apply a looser association between test classes and production classes. … Test packages or directories organized in terms of functional slices are often easier to navigate." — Smart & Molak §16.5.5
8
+
9
+ > "Writing unit tests that make good technical documentation relies more on an attitude than on using a particular tool." — Smart & Molak §16.5.5
10
+
11
+ ## Describe / when / should
12
+
13
+ - Outermost **describe** names the unit under test (component, module, or feature slice).
14
+ - Inner **describe** uses **When [context]** (or equivalent grouping) for the situation.
15
+ - **it** (or **test**) names start with **should** and state one observable outcome.
16
+
17
+ Dan North (2006): naming tests as sentences keeps focus on the **next behaviour** you care about.
18
+
19
+ ## Soap-opera personas
20
+
21
+ When you lack full personas, introduce **short-lived characters** with a name and role and deepen them as scenarios grow—like a serial drama adding cast over episodes (Smart & Molak §7.6.5). Embed **\[Name], the \[role]** in scenario titles or setup where the actor changes behavior.
22
+
23
+ ## Example (JavaScript-style)
24
+
25
+ ```javascript
26
+ describe("PaymentProcessor", () => {
27
+ describe("When Carrie the compliance officer requests a refund for a disputed charge", () => {
28
+ it("should deduct the refund amount from the account balance", async () => {
29
+ const disputedChargeAmount = 150.0;
30
+ const refundResult = await processor.refund(carrieAccountId, disputedChargeAmount);
31
+ expect(refundResult.status).toBe("completed");
32
+ expect(refundResult.amount).toBe(disputedChargeAmount);
33
+ });
34
+
35
+ it("should create an audit record with a timestamp and initiator", async () => {
36
+ const disputedChargeAmount = 150.0;
37
+ const auditRecord = await processor.refund(carrieAccountId, disputedChargeAmount);
38
+ expect(auditRecord.timestamp).toBeDefined();
39
+ expect(auditRecord.initiator).toBe("carrie_compliance");
40
+ });
41
+ });
42
+
43
+ describe("When Barry the small business owner requests a refund", () => {
44
+ it("should send a confirmation notification within business hours", async () => {
45
+ const refundAmount = 500.0;
46
+ const confirmation = await processor.refund(barryAccountId, refundAmount);
47
+ expect(confirmation.notificationSent).toBe(true);
48
+ });
49
+ });
50
+ });
51
+ ```
52
+
53
+ Adapt naming to your test runner (pytest: functions; Jest/Vitest: `it`; JUnit: `@Test` methods with `should_` names).
54
+
55
+ ## File organization
56
+
57
+ - Prefer **one file per feature slice** or user journey when it keeps related behaviours together.
58
+ - Split when files grow hard to scan; keep **should** names readable in lists and IDEs.
59
+
60
+ ## Checklist
61
+
62
+ - [ ] Every test name reads as a **should** sentence for one outcome
63
+ - [ ] Groups use **When**-style context where it helps navigation
64
+ - [ ] Personas appear only when they change behaviour or clarity
65
+ - [ ] Tests do not mirror production folders if that obscures behaviour
66
+ - [ ] A new reader can understand intent without opening production code first
67
+
68
+ ## References
69
+
70
+ - Smart & Molak, *BDD in Action* 2e, §16.5.5 (test layout), §7.6.5 (personas)
71
+ - Dan North, "Introducing BDD" (2006)
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- TDD enforcement hook.
3
+ BDD Automate-phase reminder (production code touch).
4
4
 
5
- Prompts confirmation when writing/editing production code files.
5
+ Prompts confirmation when writing or editing production code files.
6
6
  Skips: Test files, config files, documentation.
7
7
  """
8
8
  import json
@@ -51,7 +51,7 @@ def main() -> None:
51
51
  "hookSpecificOutput": {
52
52
  "hookEventName": "PreToolUse",
53
53
  "permissionDecision": "allow",
54
- "additionalContext": "[TDD] Writing production code. Confirm you have a failing test first."
54
+ "additionalContext": "[BDD] Writing production code. Confirm you have a failing specification (test) first."
55
55
  }
56
56
  }
57
57
  print(json.dumps(result))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "1.19.3",
3
+ "version": "1.21.0",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,10 @@
13
13
  "commands/",
14
14
  "agents/",
15
15
  "skills/",
16
- "hooks/"
16
+ "hooks/",
17
+ "system-prompts/",
18
+ "scripts/",
19
+ "CLAUDE.md"
17
20
  ],
18
21
  "keywords": [
19
22
  "claude-code",
package/rules/bdd.md ADDED
@@ -0,0 +1,28 @@
1
+ # BDD (discovery-driven development)
2
+
3
+ **Canonical detail:** `~/.claude/system-prompts/software-engineer.xml` → `<behavior_protocol>`.
4
+
5
+ **On-demand depth:** `@~/.claude/skills/bdd-protocol/SKILL.md` (Example Mapping §6.4, §7.6 catalog, solo patterns). Tracking design: [jl-cmd/claude-code-config#82](https://github.com/jl-cmd/claude-code-config/issues/82).
6
+
7
+ **Optional long-form references (load when needed):**
8
+
9
+ - `@~/.claude/docs/BDD_SCENARIO_QUALITY.md` — seven scenario quality patterns (§7.6-style)
10
+ - `@~/.claude/docs/BDD_DISCOVERY_PROTOCOL.md` — Example Mapping algorithm for chat
11
+ - `@~/.claude/docs/BDD_TEST_LAYOUT.md` — describe/when/should layout and soap-opera personas
12
+
13
+ ## What you do for every non-trivial feature
14
+
15
+ 1. **Deliberate Discovery** — Reduce uncertainty before code; surface what you do not know (Smart & Molak §5.4).
16
+ 2. **Illustrate** — Explore goals, constraints, and concrete examples in chat; "given … when … then …" style outcomes.
17
+ 3. **Formulate** — Express behavior as narrow **"should …"** specifications the user can approve.
18
+ 4. **Automate** — Failing specification first, then minimum code to pass; refactor only for a concrete smell.
19
+
20
+ Conversation is the essential practice: if discovery is skipped, structured formats do not rescue the workflow (Minimal BDD).
21
+
22
+ ## Solo developer
23
+
24
+ You are often the stakeholder. Use **Example Mapping** in chat ("the one where …", probes, parking lot). Load **`bdd-protocol`** when you need the full algorithm and anti-pattern list.
25
+
26
+ ## Naming
27
+
28
+ Developer-facing specs and tests use **should** sentences so intent stays visible (Dan North, "Introducing BDD", 2006).
@@ -3,7 +3,7 @@
3
3
  > **MANDATORY REFERENCE:** CODE_RULES.md - Load for ALL code generation.
4
4
  > This is the single source of truth for code standards. Non-negotiable.
5
5
 
6
- @${CLAUDE_PLUGIN_ROOT}/docs/CODE_RULES.md
6
+ @~/.claude/docs/CODE_RULES.md
7
7
 
8
8
  **Key principles (see CODE_RULES.md for complete reference):**
9
9
  - Self-documenting code (no comments)
@@ -0,0 +1,17 @@
1
+ # Self-Contained Documentation
2
+
3
+ **When this applies:** All generated artifacts — gists, decision docs, PR descriptions, issue bodies, plans, SKILL.md content. Exception: Obsidian session logs (intentionally conversation-scoped).
4
+
5
+ ## Rule
6
+
7
+ Every document must be fully self-contained. A reader with zero prior context must understand every statement without needing access to the conversation that produced it.
8
+
9
+ ## Patterns to Catch and Replace
10
+
11
+ | Pattern | Example | Fix |
12
+ |---|---|---|
13
+ | References to options/choices discussed in conversation | "This is not Option A from the original framing" | Delete the sentence, or restate the decision on its own terms |
14
+ | "As discussed" / "as we decided" / "from the prior session" | "As discussed, we'll use embeddings" | "Sref matching uses sentence-transformer embeddings" |
15
+ | Pronouns pointing to conversation context | "This approach addresses the concerns raised earlier" | State what the concerns were inline, or delete |
16
+ | Relative framing ("instead of X") where X was only discussed verbally | "Instead of the three options considered" | State the chosen approach directly without referencing alternatives the reader can't see |
17
+ | Session-specific sequencing | "After Round 3 we decided..." | State the decision as a fact |
package/rules/testing.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **Reference:** TEST_QUALITY.md - Load when writing or reviewing tests.
4
4
 
5
- @${CLAUDE_PLUGIN_ROOT}/docs/TEST_QUALITY.md
5
+ @~/.claude/docs/TEST_QUALITY.md
6
6
 
7
7
  ## Complete Mocks for Testability
8
8
 
@@ -0,0 +1,34 @@
1
+ # Obsidian Vault Context
2
+
3
+ An Obsidian vault stores session reports, decisions, and research documents across all projects. Its filesystem location is configured per user via the `OBSIDIAN_VAULT_PATH` environment variable (or the equivalent path exposed by the user's Obsidian MCP server). Do not assume a specific OS path; resolve the vault location from the configured MCP tools before reading files directly.
4
+
5
+ ## Available MCP Tools
6
+
7
+ - `mcp__obsidian__search_notes` -- search by content or frontmatter (`searchFrontmatter: true`)
8
+ - `mcp__obsidian__read_note` -- read a single note by path
9
+ - `mcp__obsidian__read_multiple_notes` -- read several notes at once
10
+
11
+ ## Vault Structure
12
+
13
+ - `sessions/` -- session reports with frontmatter: `type: session-report`, `project`, `session`, `date`, `status`, `blocked`, `tags`
14
+ - `decisions/` -- decision notes with frontmatter: `type: decision|procedural|fact|gotcha`, `project`, `date`, `status: Active|Superseded`, `tags`
15
+ - `Research/` -- deep research documents
16
+
17
+ ## When to Search
18
+
19
+ IMPORTANT: Before starting substantive project work, search the vault for prior sessions and decisions for the current project. Also search when:
20
+ - Encountering a component or system with known history
21
+ - A task might repeat or reverse a prior decision
22
+ - You need context on why something was built a certain way
23
+
24
+ Search by `project` frontmatter field first, then by content keywords like "blocked", "superseded", "decision", "gotcha".
25
+
26
+ ## Session Logging
27
+
28
+ When the user invokes `/session-log`, treat **short and long sessions the same**: run the full logging flow. Session length does not change the requirements below.
29
+
30
+ At the end of substantive sessions, offer to run `/session-log` if not already invoked.
31
+
32
+ When running `/session-log`, include `vault_context_retrieved: true|false` in frontmatter based on whether vault MCP tools were used this session.
33
+
34
+ After writing a session log, ALWAYS output a `/rename` command with a descriptive session name based on the session's primary outcome. Format: `/rename [Project] - [Primary Outcome]`. This is a mandatory output requirement, not optional.
@@ -0,0 +1,42 @@
1
+ # Verify Before Asking
2
+
3
+ **When this applies:** Before asking the user any clarifying question during discovery, scoping, or implementation planning.
4
+
5
+ ## Rule
6
+
7
+ If a question can be answered by inspecting files, running a command, querying a database, reading a config, or using any available tool, answer it yourself. Only ask the user questions that require their judgment, preference, or knowledge that is not accessible to automated inspection.
8
+
9
+ ## Decision Checklist
10
+
11
+ Before writing any AskUserQuestion or asking a clarifying question in chat, evaluate:
12
+
13
+ | Check | Action |
14
+ |---|---|
15
+ | Does the answer live in a file on disk? | Read the file. |
16
+ | Does the answer live in a directory structure? | List the directory. |
17
+ | Does the answer live in a database? | Query the database. |
18
+ | Does the answer live in git history? | Run `git log` or `git blame`. |
19
+ | Is the answer determined by file naming patterns or contents? | Glob a sample and inspect. |
20
+ | Is the answer a value in a config or environment variable? | Read the config or check the env. |
21
+ | Is the answer retrievable from any available MCP tool? | Use the tool. |
22
+
23
+ Only after confirming the answer cannot be obtained through any available tool, ask the user.
24
+
25
+ ## Questions That Belong to the User
26
+
27
+ Reserve user questions for:
28
+ - **Preferences** — "Do you want approach A or B?" when both are viable and the user has a stake.
29
+ - **Missing context the user holds** — passwords, account names, intent, future plans.
30
+ - **Judgment calls** — tradeoffs the user needs to evaluate.
31
+ - **Scope decisions** — what to include or exclude from a piece of work.
32
+
33
+ ## Examples
34
+
35
+ **Wrong:** "Are there multiple images per folder, or just one image + one mp4?"
36
+ **Right:** List the folder contents directly, then state what was found.
37
+
38
+ **Wrong:** "What columns does the themes table have?"
39
+ **Right:** Query `information_schema.columns` and report the schema.
40
+
41
+ **Wrong:** "Is there a Prisma schema in this project?"
42
+ **Right:** Glob for `schema.prisma` and check.
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env python3
2
+ """Generate Cursor rules from ~/.claude/rules and docs.
3
+
4
+ Writes to <profile or repo>/.cursor/rules/*.mdc, .cursor/docs/*.md (byte copies of
5
+ CODE_RULES.md and TEST_QUALITY.md when present), and .cursor/.sync-manifest.json.
6
+ If LLM_SETTINGS_ROOT is set to the llm-settings repo root, uses <root>/.claude and
7
+ <root>/.cursor. Otherwise uses ~/.claude and ~/.cursor (after junction install).
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ _SCRIPTS_DIR = Path(__file__).resolve().parent
16
+ if str(_SCRIPTS_DIR) not in sys.path:
17
+ sys.path.insert(0, str(_SCRIPTS_DIR))
18
+
19
+ from sync_to_cursor.engine import main
20
+
21
+ if __name__ == "__main__":
22
+ sys.exit(main())
@@ -0,0 +1,13 @@
1
+ """Sync Claude ~/.claude rules and docs into Cursor .cursor layout."""
2
+
3
+ from sync_to_cursor.config import MAX_RULE_BODY_LINES
4
+ from sync_to_cursor.canonical_docs import sync_canonical_docs as _sync_canonical_docs
5
+ from sync_to_cursor.rules import _limit_lines, merge_code_standards, merge_test_quality
6
+
7
+ __all__ = [
8
+ "MAX_RULE_BODY_LINES",
9
+ "_limit_lines",
10
+ "_sync_canonical_docs",
11
+ "merge_code_standards",
12
+ "merge_test_quality",
13
+ ]
@@ -0,0 +1,66 @@
1
+ """Copy and verify canonical docs under .cursor/docs/."""
2
+
3
+ import shutil
4
+ from pathlib import Path
5
+
6
+ from sync_to_cursor.config import CANONICAL_DOC_FILES
7
+ from sync_to_cursor.hashing import sha256_bytes
8
+
9
+
10
+ def sync_canonical_docs(
11
+ claude: Path,
12
+ cursor: Path,
13
+ dry_run: bool,
14
+ quiet: bool,
15
+ ) -> dict:
16
+ docs_out = cursor / "docs"
17
+ if not dry_run:
18
+ docs_out.mkdir(parents=True, exist_ok=True)
19
+ new_docs: dict = {}
20
+ for name in CANONICAL_DOC_FILES:
21
+ src = claude / "docs" / name
22
+ dst = docs_out / name
23
+ if not src.is_file():
24
+ if dst.is_file():
25
+ if not dry_run:
26
+ dst.unlink()
27
+ if not quiet:
28
+ print(f"WARN docs/{name} (source removed — deleted stale copy at {dst})")
29
+ elif not quiet:
30
+ print(f"WARN docs/{name} (missing source: {src})")
31
+ continue
32
+ key = f"docs/{name}"
33
+ src_hash = sha256_bytes(src.read_bytes())
34
+ if dry_run:
35
+ if dst.is_file():
36
+ out_hash = sha256_bytes(dst.read_bytes())
37
+ else:
38
+ out_hash = ""
39
+ else:
40
+ shutil.copy2(src, dst)
41
+ out_hash = sha256_bytes(dst.read_bytes())
42
+ new_docs[key] = {"sources_hash": src_hash, "output_hash": out_hash}
43
+ return new_docs
44
+
45
+
46
+ def check_canonical_docs(claude: Path, cursor: Path, docs_entries: dict) -> bool:
47
+ for name in CANONICAL_DOC_FILES:
48
+ key = f"docs/{name}"
49
+ src = claude / "docs" / name
50
+ dst = cursor / "docs" / name
51
+ if not src.is_file():
52
+ if key in docs_entries:
53
+ return False
54
+ continue
55
+ if not dst.is_file():
56
+ return False
57
+ src_hash = sha256_bytes(src.read_bytes())
58
+ dst_hash = sha256_bytes(dst.read_bytes())
59
+ prev = docs_entries.get(key)
60
+ if not prev:
61
+ return False
62
+ if prev.get("sources_hash") != src_hash:
63
+ return False
64
+ if prev.get("output_hash") != dst_hash:
65
+ return False
66
+ return True
@@ -0,0 +1,5 @@
1
+ """Shared configuration for the sync-to-cursor package."""
2
+
3
+ GENERATOR_VERSION: str = "1.2.3"
4
+ CANONICAL_DOC_FILES: tuple[str, ...] = ("CODE_RULES.md", "TEST_QUALITY.md")
5
+ MAX_RULE_BODY_LINES: int = 50