4runr-cursor-setup 0.1.0 → 0.1.2

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/dist/cli.js CHANGED
@@ -1,14 +1,48 @@
1
1
  #!/usr/bin/env node
2
2
  import { init } from "./commands/init.js";
3
+ import { addGroup, listGroups, removeGroup, GROUPS } from "./commands/commands.js";
3
4
  const args = process.argv.slice(2);
4
5
  const cmd = args[0];
6
+ function usage() {
7
+ console.log("4runr-cursor-setup");
8
+ console.log("Usage:");
9
+ console.log(" 4runr-cursor-setup init [--force]");
10
+ console.log(" 4runr-cursor-setup list");
11
+ console.log(" 4runr-cursor-setup add <group> [--force]");
12
+ console.log(" 4runr-cursor-setup remove <group>");
13
+ console.log("");
14
+ console.log("Groups: " + Object.keys(GROUPS).join(", "));
15
+ }
5
16
  async function main() {
17
+ const force = args.includes("--force");
6
18
  if (cmd === "init") {
7
19
  await init({ cwd: process.cwd() });
20
+ addGroup({ cwd: process.cwd(), group: "core", force });
8
21
  return;
9
22
  }
10
- console.log("4runr-cursor-setup");
11
- console.log("Usage: 4runr-cursor-setup init");
23
+ if (cmd === "list") {
24
+ listGroups();
25
+ return;
26
+ }
27
+ if (cmd === "add") {
28
+ const group = args[1];
29
+ if (!group || !(group in GROUPS)) {
30
+ usage();
31
+ process.exit(1);
32
+ }
33
+ addGroup({ cwd: process.cwd(), group, force });
34
+ return;
35
+ }
36
+ if (cmd === "remove") {
37
+ const group = args[1];
38
+ if (!group || !(group in GROUPS)) {
39
+ usage();
40
+ process.exit(1);
41
+ }
42
+ removeGroup({ cwd: process.cwd(), group });
43
+ return;
44
+ }
45
+ usage();
12
46
  process.exit(1);
13
47
  }
14
48
  main().catch((err) => {
@@ -0,0 +1,91 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import * as url from "url";
4
+ export const GROUPS = {
5
+ core: ["4runr-start.md", "4runr-close.md"],
6
+ planning: ["4runr-task.md", "4runr-phase.md"],
7
+ governance: ["4runr-decision.md", "4runr-scope-change.md"],
8
+ debugging: ["4runr-repro.md", "4runr-verify.md"],
9
+ };
10
+ const MANAGED_MARKER = "<!-- managed-by: 4runr-cursor-setup -->";
11
+ function ensureDir(p) {
12
+ fs.mkdirSync(p, { recursive: true });
13
+ }
14
+ function fileContainsMarker(p) {
15
+ if (!fs.existsSync(p))
16
+ return false;
17
+ const s = fs.readFileSync(p, "utf8");
18
+ return s.includes(MANAGED_MARKER);
19
+ }
20
+ function ensureMarkerOnFile(p) {
21
+ // If a file exists but lacks the marker, we do not modify it.
22
+ // Marker is only guaranteed for files we write.
23
+ if (!fs.existsSync(p))
24
+ return;
25
+ const s = fs.readFileSync(p, "utf8");
26
+ if (s.includes(MANAGED_MARKER))
27
+ return;
28
+ }
29
+ function writeWithMarker(src, dst) {
30
+ const body = fs.readFileSync(src, "utf8");
31
+ const out = body.includes(MANAGED_MARKER) ? body : `${MANAGED_MARKER}\n\n${body}`;
32
+ ensureDir(path.dirname(dst));
33
+ fs.writeFileSync(dst, out, "utf8");
34
+ }
35
+ function copyIfMissing(src, dst, force = false) {
36
+ if (!force && fs.existsSync(dst)) {
37
+ // never touch existing files unless --force
38
+ ensureMarkerOnFile(dst);
39
+ return false;
40
+ }
41
+ writeWithMarker(src, dst);
42
+ return true;
43
+ }
44
+ function getTemplatesRoot() {
45
+ const here = path.dirname(url.fileURLToPath(import.meta.url));
46
+ return path.resolve(here, "..", "templates");
47
+ }
48
+ export function listGroups() {
49
+ console.log("Available groups:");
50
+ Object.keys(GROUPS).forEach((g) => {
51
+ console.log("- " + g + ": " + GROUPS[g].join(", "));
52
+ });
53
+ }
54
+ export function addGroup(opts) {
55
+ const { cwd, group, force = false } = opts;
56
+ const templatesRoot = getTemplatesRoot();
57
+ const srcBase = path.join(templatesRoot, "commands", group);
58
+ const outBase = path.join(cwd, ".cursor", "commands");
59
+ ensureDir(outBase);
60
+ const files = GROUPS[group];
61
+ let copied = 0;
62
+ for (const f of files) {
63
+ const src = path.join(srcBase, f);
64
+ const dst = path.join(outBase, f);
65
+ if (!fs.existsSync(src))
66
+ throw new Error("Template missing: " + src);
67
+ if (copyIfMissing(src, dst, force))
68
+ copied++;
69
+ }
70
+ console.log('Installed group "' + group + '" into .cursor/commands (' + copied + " file(s) written).");
71
+ }
72
+ export function removeGroup(opts) {
73
+ const { cwd, group } = opts;
74
+ const outBase = path.join(cwd, ".cursor", "commands");
75
+ const files = GROUPS[group];
76
+ let removed = 0;
77
+ let skipped = 0;
78
+ for (const f of files) {
79
+ const dst = path.join(outBase, f);
80
+ if (!fs.existsSync(dst))
81
+ continue;
82
+ // Only delete files we manage.
83
+ if (!fileContainsMarker(dst)) {
84
+ skipped++;
85
+ continue;
86
+ }
87
+ fs.unlinkSync(dst);
88
+ removed++;
89
+ }
90
+ console.log('Removed group "' + group + '" from .cursor/commands (' + removed + " file(s) deleted, " + skipped + " skipped).");
91
+ }
@@ -0,0 +1,7 @@
1
+ # /4runr-close
2
+
3
+ Before ending the chat:
4
+ 1) Update docs/status.md with a short snapshot (what exists now, what changed).
5
+ 2) Update docs/todo.md with next steps + blockers.
6
+ 3) If any decisions were made, append them to docs/decisions.md (date + decision + reason).
7
+ 4) List files changed (or that should be changed).
@@ -0,0 +1,7 @@
1
+ # /4runr-start
2
+
3
+ Before doing anything:
4
+ 1) Read: docs/status.md, docs/todo.md, docs/decisions.md, docs/scope.md, docs/constraints.md, .cursor/rules/project.md (if they exist).
5
+ 2) Summarize current state in 5-10 bullets.
6
+ 3) List missing info (if any) as targeted questions.
7
+ 4) Do not implement until aligned.
@@ -0,0 +1,8 @@
1
+ # /4runr-repro
2
+
3
+ Produce minimal reproduction steps:
4
+ - Environment
5
+ - Steps
6
+ - Expected vs actual
7
+ - Minimal code / files involved
8
+ Then propose 1-3 hypotheses to test.
@@ -0,0 +1,7 @@
1
+ # /4runr-verify
2
+
3
+ Before claiming 'fixed':
4
+ - Show how to run verification
5
+ - What signals prove it's fixed
6
+ - What edge cases to check
7
+ Never claim success without verification.
@@ -0,0 +1,8 @@
1
+ # /4runr-decision
2
+
3
+ Append a decision to docs/decisions.md using:
4
+ - Date
5
+ - Decision
6
+ - Context
7
+ - Tradeoffs
8
+ - Consequences
@@ -0,0 +1,7 @@
1
+ # /4runr-scope-change
2
+
3
+ Record a scope change in docs/decisions.md:
4
+ - What changed
5
+ - Why
6
+ - Impact
7
+ - New constraints / risks
@@ -0,0 +1,6 @@
1
+ # /4runr-phase
2
+
3
+ Ask the user for the current phase goal, then:
4
+ - Lock scope to that phase only
5
+ - Define exit criteria
6
+ - Proceed in atomic steps
@@ -0,0 +1,6 @@
1
+ # /4runr-task
2
+
3
+ Convert the user's request into:
4
+ - A small plan (3-7 steps)
5
+ - The first atomic step to execute next
6
+ Ask clarifying questions if less than 90% confident.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "4runr-cursor-setup",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,7 @@
1
+ # /4runr-close
2
+
3
+ Before ending the chat:
4
+ 1) Update docs/status.md with a short snapshot (what exists now, what changed).
5
+ 2) Update docs/todo.md with next steps + blockers.
6
+ 3) If any decisions were made, append them to docs/decisions.md (date + decision + reason).
7
+ 4) List files changed (or that should be changed).
@@ -0,0 +1,7 @@
1
+ # /4runr-start
2
+
3
+ Before doing anything:
4
+ 1) Read: docs/status.md, docs/todo.md, docs/decisions.md, docs/scope.md, docs/constraints.md, .cursor/rules/project.md (if they exist).
5
+ 2) Summarize current state in 5-10 bullets.
6
+ 3) List missing info (if any) as targeted questions.
7
+ 4) Do not implement until aligned.
@@ -0,0 +1,8 @@
1
+ # /4runr-repro
2
+
3
+ Produce minimal reproduction steps:
4
+ - Environment
5
+ - Steps
6
+ - Expected vs actual
7
+ - Minimal code / files involved
8
+ Then propose 1-3 hypotheses to test.
@@ -0,0 +1,7 @@
1
+ # /4runr-verify
2
+
3
+ Before claiming 'fixed':
4
+ - Show how to run verification
5
+ - What signals prove it's fixed
6
+ - What edge cases to check
7
+ Never claim success without verification.
@@ -0,0 +1,8 @@
1
+ # /4runr-decision
2
+
3
+ Append a decision to docs/decisions.md using:
4
+ - Date
5
+ - Decision
6
+ - Context
7
+ - Tradeoffs
8
+ - Consequences
@@ -0,0 +1,7 @@
1
+ # /4runr-scope-change
2
+
3
+ Record a scope change in docs/decisions.md:
4
+ - What changed
5
+ - Why
6
+ - Impact
7
+ - New constraints / risks
@@ -0,0 +1,6 @@
1
+ # /4runr-phase
2
+
3
+ Ask the user for the current phase goal, then:
4
+ - Lock scope to that phase only
5
+ - Define exit criteria
6
+ - Proceed in atomic steps
@@ -0,0 +1,6 @@
1
+ # /4runr-task
2
+
3
+ Convert the user's request into:
4
+ - A small plan (3-7 steps)
5
+ - The first atomic step to execute next
6
+ Ask clarifying questions if less than 90% confident.