grounder 0.2.0 → 0.3.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.
Files changed (149) hide show
  1. package/README.md +81 -32
  2. package/dist/agents/claude.d.ts +1 -0
  3. package/dist/agents/claude.d.ts.map +1 -1
  4. package/dist/agents/claude.js +38 -13
  5. package/dist/agents/claude.js.map +1 -1
  6. package/dist/agents/cursor.d.ts +1 -0
  7. package/dist/agents/cursor.d.ts.map +1 -1
  8. package/dist/agents/cursor.js +38 -13
  9. package/dist/agents/cursor.js.map +1 -1
  10. package/dist/agents/hook-runtime.d.ts +65 -21
  11. package/dist/agents/hook-runtime.d.ts.map +1 -1
  12. package/dist/agents/hook-runtime.js +172 -31
  13. package/dist/agents/hook-runtime.js.map +1 -1
  14. package/dist/agents/index.d.ts +18 -0
  15. package/dist/agents/index.d.ts.map +1 -1
  16. package/dist/agents/index.js +27 -4
  17. package/dist/agents/index.js.map +1 -1
  18. package/dist/agents/install-command.d.ts +37 -0
  19. package/dist/agents/install-command.d.ts.map +1 -0
  20. package/dist/agents/install-command.js +65 -0
  21. package/dist/agents/install-command.js.map +1 -0
  22. package/dist/agents/types.d.ts +19 -1
  23. package/dist/agents/types.d.ts.map +1 -1
  24. package/dist/cli.js +58 -60
  25. package/dist/cli.js.map +1 -1
  26. package/dist/commands/apply-agent-installs.d.ts +34 -0
  27. package/dist/commands/apply-agent-installs.d.ts.map +1 -0
  28. package/dist/commands/apply-agent-installs.js +137 -0
  29. package/dist/commands/apply-agent-installs.js.map +1 -0
  30. package/dist/commands/doctor.d.ts.map +1 -1
  31. package/dist/commands/doctor.js +202 -51
  32. package/dist/commands/doctor.js.map +1 -1
  33. package/dist/commands/handoff/list.d.ts.map +1 -1
  34. package/dist/commands/handoff/list.js +5 -0
  35. package/dist/commands/handoff/list.js.map +1 -1
  36. package/dist/commands/handoff/peek.d.ts +5 -2
  37. package/dist/commands/handoff/peek.d.ts.map +1 -1
  38. package/dist/commands/handoff/peek.js +47 -6
  39. package/dist/commands/handoff/peek.js.map +1 -1
  40. package/dist/commands/handoff.d.ts.map +1 -1
  41. package/dist/commands/handoff.js +5 -0
  42. package/dist/commands/handoff.js.map +1 -1
  43. package/dist/commands/migrate.d.ts +23 -0
  44. package/dist/commands/migrate.d.ts.map +1 -0
  45. package/dist/commands/migrate.js +104 -0
  46. package/dist/commands/migrate.js.map +1 -0
  47. package/dist/commands/note.d.ts.map +1 -1
  48. package/dist/commands/note.js +5 -0
  49. package/dist/commands/note.js.map +1 -1
  50. package/dist/commands/package-version-notice.d.ts +18 -0
  51. package/dist/commands/package-version-notice.d.ts.map +1 -0
  52. package/dist/commands/package-version-notice.js +39 -0
  53. package/dist/commands/package-version-notice.js.map +1 -0
  54. package/dist/commands/path/logs.d.ts +1 -1
  55. package/dist/commands/path/logs.d.ts.map +1 -1
  56. package/dist/commands/path/logs.js +6 -1
  57. package/dist/commands/path/logs.js.map +1 -1
  58. package/dist/commands/path/notes.d.ts +1 -1
  59. package/dist/commands/path/notes.d.ts.map +1 -1
  60. package/dist/commands/path/notes.js +6 -1
  61. package/dist/commands/path/notes.js.map +1 -1
  62. package/dist/commands/path/plans.d.ts +7 -0
  63. package/dist/commands/path/plans.d.ts.map +1 -0
  64. package/dist/commands/path/plans.js +22 -0
  65. package/dist/commands/path/plans.js.map +1 -0
  66. package/dist/commands/plan/list.d.ts +23 -0
  67. package/dist/commands/plan/list.d.ts.map +1 -0
  68. package/dist/commands/plan/list.js +69 -0
  69. package/dist/commands/plan/list.js.map +1 -0
  70. package/dist/commands/plan.d.ts +34 -0
  71. package/dist/commands/plan.d.ts.map +1 -0
  72. package/dist/commands/plan.js +121 -0
  73. package/dist/commands/plan.js.map +1 -0
  74. package/dist/commands/repo/init.d.ts.map +1 -1
  75. package/dist/commands/repo/init.js +12 -1
  76. package/dist/commands/repo/init.js.map +1 -1
  77. package/dist/commands/status.d.ts +1 -1
  78. package/dist/commands/status.d.ts.map +1 -1
  79. package/dist/commands/status.js +52 -9
  80. package/dist/commands/status.js.map +1 -1
  81. package/dist/commands/upgrade-banner.d.ts +9 -0
  82. package/dist/commands/upgrade-banner.d.ts.map +1 -0
  83. package/dist/commands/upgrade-banner.js +27 -0
  84. package/dist/commands/upgrade-banner.js.map +1 -0
  85. package/dist/commands/vault/init.d.ts.map +1 -1
  86. package/dist/commands/vault/init.js +18 -29
  87. package/dist/commands/vault/init.js.map +1 -1
  88. package/dist/connector/repo.d.ts +2 -0
  89. package/dist/connector/repo.d.ts.map +1 -1
  90. package/dist/connector/repo.js +12 -1
  91. package/dist/connector/repo.js.map +1 -1
  92. package/dist/connector/state.d.ts +95 -0
  93. package/dist/connector/state.d.ts.map +1 -0
  94. package/dist/connector/state.js +189 -0
  95. package/dist/connector/state.js.map +1 -0
  96. package/dist/connector/unsupported-schema.d.ts +9 -0
  97. package/dist/connector/unsupported-schema.d.ts.map +1 -0
  98. package/dist/connector/unsupported-schema.js +14 -0
  99. package/dist/connector/unsupported-schema.js.map +1 -0
  100. package/dist/connector/vault.d.ts +2 -0
  101. package/dist/connector/vault.d.ts.map +1 -1
  102. package/dist/connector/vault.js +6 -1
  103. package/dist/connector/vault.js.map +1 -1
  104. package/dist/help.d.ts +45 -0
  105. package/dist/help.d.ts.map +1 -0
  106. package/dist/help.js +355 -0
  107. package/dist/help.js.map +1 -0
  108. package/dist/util/fs.d.ts +6 -0
  109. package/dist/util/fs.d.ts.map +1 -1
  110. package/dist/util/fs.js +15 -1
  111. package/dist/util/fs.js.map +1 -1
  112. package/dist/util/hash.d.ts +3 -0
  113. package/dist/util/hash.d.ts.map +1 -0
  114. package/dist/util/hash.js +6 -0
  115. package/dist/util/hash.js.map +1 -0
  116. package/dist/util/path.d.ts +10 -0
  117. package/dist/util/path.d.ts.map +1 -1
  118. package/dist/util/path.js +31 -0
  119. package/dist/util/path.js.map +1 -1
  120. package/dist/util/plan-name.d.ts +10 -0
  121. package/dist/util/plan-name.d.ts.map +1 -0
  122. package/dist/util/plan-name.js +18 -0
  123. package/dist/util/plan-name.js.map +1 -0
  124. package/dist/util/semver.d.ts +10 -0
  125. package/dist/util/semver.d.ts.map +1 -0
  126. package/dist/util/semver.js +40 -0
  127. package/dist/util/semver.js.map +1 -0
  128. package/dist/vault/layout.d.ts +2 -0
  129. package/dist/vault/layout.d.ts.map +1 -1
  130. package/dist/vault/layout.js +4 -0
  131. package/dist/vault/layout.js.map +1 -1
  132. package/dist/vault/list-plans.d.ts +11 -0
  133. package/dist/vault/list-plans.d.ts.map +1 -0
  134. package/dist/vault/list-plans.js +40 -0
  135. package/dist/vault/list-plans.js.map +1 -0
  136. package/dist/vault/write-plan.d.ts +28 -0
  137. package/dist/vault/write-plan.d.ts.map +1 -0
  138. package/dist/vault/write-plan.js +61 -0
  139. package/dist/vault/write-plan.js.map +1 -0
  140. package/package.json +1 -1
  141. package/templates/agents/claude/commands/grounder-note.md +1 -1
  142. package/templates/agents/claude/commands/grounder-plan.md +65 -0
  143. package/templates/agents/claude/commands/grounder-task-handoff.md +3 -3
  144. package/templates/agents/claude/commands/grounder-task.md +2 -2
  145. package/templates/agents/cursor/commands/grounder-note.md +1 -1
  146. package/templates/agents/cursor/commands/grounder-plan.md +65 -0
  147. package/templates/agents/cursor/commands/grounder-task-handoff.md +3 -3
  148. package/templates/agents/cursor/commands/grounder-task.md +2 -2
  149. package/templates/vault/plan.md +16 -0
@@ -0,0 +1,11 @@
1
+ export interface ListPlansOptions {
2
+ /** Max paths to return (newest first). Omit to return all. */
3
+ limit?: number;
4
+ }
5
+ /**
6
+ * Lists plan markdown files under `plansDir`, newest mtime first.
7
+ * Returns absolute paths. Missing or empty dirs yield `[]`.
8
+ * Ties break by filename descending for stable output.
9
+ */
10
+ export declare function listPlans(plansDir: string, options?: ListPlansOptions): Promise<string[]>;
11
+ //# sourceMappingURL=list-plans.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-plans.d.ts","sourceRoot":"","sources":["../../src/vault/list-plans.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,EAAE,CAAC,CAoCnB"}
@@ -0,0 +1,40 @@
1
+ import { readdir, stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ /**
4
+ * Lists plan markdown files under `plansDir`, newest mtime first.
5
+ * Returns absolute paths. Missing or empty dirs yield `[]`.
6
+ * Ties break by filename descending for stable output.
7
+ */
8
+ export async function listPlans(plansDir, options = {}) {
9
+ let entries;
10
+ try {
11
+ entries = await readdir(plansDir);
12
+ }
13
+ catch (error) {
14
+ if (error.code === "ENOENT") {
15
+ return [];
16
+ }
17
+ throw error;
18
+ }
19
+ const mdNames = entries.filter((name) => name.endsWith(".md"));
20
+ const withMtime = await Promise.all(mdNames.map(async (name) => {
21
+ const filePath = path.join(plansDir, name);
22
+ const { mtimeMs } = await stat(filePath);
23
+ return { filePath, name, mtimeMs };
24
+ }));
25
+ withMtime.sort((a, b) => {
26
+ if (a.mtimeMs !== b.mtimeMs) {
27
+ return b.mtimeMs - a.mtimeMs;
28
+ }
29
+ return a.name < b.name ? 1 : a.name > b.name ? -1 : 0;
30
+ });
31
+ const paths = withMtime.map((entry) => entry.filePath);
32
+ if (options.limit === undefined) {
33
+ return paths;
34
+ }
35
+ if (options.limit <= 0) {
36
+ return [];
37
+ }
38
+ return paths.slice(0, options.limit);
39
+ }
40
+ //# sourceMappingURL=list-plans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-plans.js","sourceRoot":"","sources":["../../src/vault/list-plans.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAgB,EAChB,UAA4B,EAAE;IAE9B,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC,CAAC,CACH,CAAC;IAEF,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtB,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YAC5B,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;QAC/B,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEvD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /** Options for {@link writePlan}. */
2
+ export interface WritePlanOptions {
3
+ /** Project id written into YAML frontmatter. */
4
+ projectId: string;
5
+ /** When true, overwrite an existing plan (preserving original `created`). */
6
+ force?: boolean;
7
+ /** Timestamp for `created` / `updated` (default: now). */
8
+ now?: Date;
9
+ }
10
+ export type WritePlanStatus = "created" | "overwritten" | "exists";
11
+ export interface WritePlanResult {
12
+ path: string;
13
+ status: WritePlanStatus;
14
+ }
15
+ /**
16
+ * Overwrites an existing plan at an absolute path.
17
+ * Preserves original `created` (falls back to `now` if missing) and sets `updated`.
18
+ * Caller must validate the path (e.g. inside this project's `plans/` dir).
19
+ */
20
+ export declare function updatePlanAtPath(filePath: string, body: string, options: Omit<WritePlanOptions, "force">): Promise<WritePlanResult>;
21
+ /**
22
+ * Writes or updates a named plan markdown file under `plansDir` (created if missing).
23
+ * Target is always `plansDir/<name>.md` — no collision suffixes.
24
+ * Without `force`, an existing file is left untouched and status `"exists"` is returned.
25
+ * With `force`, overwrites the body, preserves original `created`, and sets `updated`.
26
+ */
27
+ export declare function writePlan(plansDir: string, name: string, body: string, options: WritePlanOptions): Promise<WritePlanResult>;
28
+ //# sourceMappingURL=write-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-plan.d.ts","sourceRoot":"","sources":["../../src/vault/write-plan.ts"],"names":[],"mappings":"AAMA,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;CACzB;AAmBD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GACvC,OAAO,CAAC,eAAe,CAAC,CAgB1B;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAuB1B"}
@@ -0,0 +1,61 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parseHandoffFrontmatter } from "../util/frontmatter.js";
4
+ import { fileExists } from "../util/fs.js";
5
+ import { yamlDoubleQuoted } from "../util/yaml.js";
6
+ function buildFrontmatter(options) {
7
+ const lines = [
8
+ "---",
9
+ `project: ${yamlDoubleQuoted(options.projectId)}`,
10
+ `created: ${yamlDoubleQuoted(options.created)}`,
11
+ ];
12
+ if (options.updated) {
13
+ lines.push(`updated: ${yamlDoubleQuoted(options.updated)}`);
14
+ }
15
+ lines.push("---");
16
+ return `${lines.join("\n")}\n\n`;
17
+ }
18
+ /**
19
+ * Overwrites an existing plan at an absolute path.
20
+ * Preserves original `created` (falls back to `now` if missing) and sets `updated`.
21
+ * Caller must validate the path (e.g. inside this project's `plans/` dir).
22
+ */
23
+ export async function updatePlanAtPath(filePath, body, options) {
24
+ const now = options.now ?? new Date();
25
+ const existing = await readFile(filePath, "utf8");
26
+ const fm = parseHandoffFrontmatter(existing);
27
+ const created = fm.created ?? now.toISOString();
28
+ const updated = now.toISOString();
29
+ const content = buildFrontmatter({
30
+ projectId: options.projectId,
31
+ created,
32
+ updated,
33
+ }) + body;
34
+ await writeFile(filePath, content, "utf8");
35
+ return { path: filePath, status: "overwritten" };
36
+ }
37
+ /**
38
+ * Writes or updates a named plan markdown file under `plansDir` (created if missing).
39
+ * Target is always `plansDir/<name>.md` — no collision suffixes.
40
+ * Without `force`, an existing file is left untouched and status `"exists"` is returned.
41
+ * With `force`, overwrites the body, preserves original `created`, and sets `updated`.
42
+ */
43
+ export async function writePlan(plansDir, name, body, options) {
44
+ const now = options.now ?? new Date();
45
+ await mkdir(plansDir, { recursive: true });
46
+ const filePath = path.join(plansDir, `${name}.md`);
47
+ const exists = await fileExists(filePath);
48
+ if (exists && !options.force) {
49
+ return { path: filePath, status: "exists" };
50
+ }
51
+ if (exists && options.force) {
52
+ return updatePlanAtPath(filePath, body, { projectId: options.projectId, now });
53
+ }
54
+ const content = buildFrontmatter({
55
+ projectId: options.projectId,
56
+ created: now.toISOString(),
57
+ }) + body;
58
+ await writeFile(filePath, content, "utf8");
59
+ return { path: filePath, status: "created" };
60
+ }
61
+ //# sourceMappingURL=write-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-plan.js","sourceRoot":"","sources":["../../src/vault/write-plan.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grounder",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Connect git projects to Obsidian dev vaults for AI agent memory",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,7 +2,7 @@ Save a note to the Obsidian vault for this project.
2
2
 
3
3
  Run from the linked project folder or any subdirectory beneath it:
4
4
 
5
- npx grounder note "<user text>"
5
+ {{GROUNDER_CLI}} note "<user text>"
6
6
 
7
7
  The vault is outside the workspace — grant shell permissions if Claude Code prompts you.
8
8
 
@@ -0,0 +1,65 @@
1
+ Write a named, updatable plan document to the Obsidian vault for this project.
2
+
3
+ Distill the instruction after `/grounder-plan` into a structured plan — not a chat transcript.
4
+ Do not dump tool traces, full conversation, or false starts.
5
+
6
+ Build a markdown body with these sections:
7
+
8
+ ```markdown
9
+ # Plan: <title>
10
+
11
+ ## Goal
12
+
13
+
14
+ ## Steps
15
+ 1. …
16
+ 2. …
17
+
18
+ ## Decisions / open questions
19
+ - …
20
+
21
+ ## Status
22
+
23
+ ```
24
+
25
+ Update vs create — never guess a `--title` for an update:
26
+
27
+ **1. Path known** (attached/open in chat, or printed by an earlier `grounder plan` this conversation): update that exact file.
28
+
29
+ ```bash
30
+ {{GROUNDER_CLI}} plan "$(cat <<'EOF'
31
+ # Plan: …
32
+
33
+ EOF
34
+ )" --path <path-to-existing-plan.md>
35
+ ```
36
+
37
+ `--path` must resolve under this project's `plans/` dir; it always overwrites (no `--force`).
38
+
39
+ **2. Path unknown** (e.g. "update the plan" with nothing attached and no prior path this conversation): look it up, then update as in (1).
40
+
41
+ ```bash
42
+ {{GROUNDER_CLI}} plan list --limit 5
43
+ ```
44
+
45
+ Pick the path matching the user's intent; ask if none or several match.
46
+
47
+ **3. Genuinely new plan** (not an update): derive a `--title`.
48
+ - If the instruction names one explicitly (e.g. `save as "implementation-phase-1"` or `…phase-1.md`), use it (strip a trailing `.md`).
49
+ - Otherwise derive a short kebab-case name from the plan's title/goal and confirm it with the user before writing.
50
+
51
+ ```bash
52
+ {{GROUNDER_CLI}} plan "$(cat <<'EOF'
53
+ # Plan: …
54
+
55
+ EOF
56
+ )" --title <name>
57
+ ```
58
+
59
+ If the CLI refuses because that name already exists (non-zero exit; stderr names the conflict), tell the user and ask whether to overwrite (`--force`) or pick a different name. `--force` only resolves this title collision — it is never how you update a plan you already meant to target (use `--path` for that). **Never** silently pass `--force`.
60
+
61
+ Run from the linked project folder or any subdirectory beneath it.
62
+ The vault is outside the workspace — grant shell permissions if Claude Code prompts you.
63
+
64
+ Do not compute vault paths or write files yourself — the CLI handles it.
65
+ Report the CLI output path from stdout to the user.
@@ -32,16 +32,16 @@ Rules:
32
32
 
33
33
  Then run from the linked project folder or any subdirectory beneath it:
34
34
 
35
- npx grounder handoff "<body>"
35
+ {{GROUNDER_CLI}} handoff "<body>"
36
36
 
37
37
  Optional short title slug (filename + frontmatter):
38
38
 
39
- npx grounder handoff --title <slug> "<body>"
39
+ {{GROUNDER_CLI}} handoff --title <slug> "<body>"
40
40
 
41
41
  For multi-line bodies, prefer a shell heredoc so quoting does not break:
42
42
 
43
43
  ```bash
44
- npx grounder handoff "$(cat <<'EOF'
44
+ {{GROUNDER_CLI}} handoff "$(cat <<'EOF'
45
45
  # Handoff: …
46
46
 
47
47
  EOF
@@ -6,11 +6,11 @@ From the linked project folder or any subdirectory beneath it:
6
6
 
7
7
  1. Get the current handoff (skips empty/unreadable files, same pick as the session-start teaser):
8
8
 
9
- npx grounder handoff list --head
9
+ {{GROUNDER_CLI}} handoff list --head
10
10
 
11
11
  2. If empty: tell the user there are no handoffs yet, then read repo `AGENTS.md` only and proceed.
12
12
 
13
- 3. Otherwise, read that file. If the user names a specific session instead, run `npx grounder handoff list --limit 5` and read the path they mean.
13
+ 3. Otherwise, read that file. If the user names a specific session instead, run `{{GROUNDER_CLI}} handoff list --limit 5` and read the path they mean.
14
14
 
15
15
  4. Read repo `AGENTS.md` (project conventions and constraints).
16
16
 
@@ -2,7 +2,7 @@ Save a note to the Obsidian vault for this project.
2
2
 
3
3
  Run from the linked project folder or any subdirectory beneath it:
4
4
 
5
- npx grounder note "<user text>"
5
+ {{GROUNDER_CLI}} note "<user text>"
6
6
 
7
7
  The vault is outside the workspace — approve shell permissions if Cursor prompts you.
8
8
 
@@ -0,0 +1,65 @@
1
+ Write a named, updatable plan document to the Obsidian vault for this project.
2
+
3
+ Distill the instruction after `/grounder-plan` into a structured plan — not a chat transcript.
4
+ Do not dump tool traces, full conversation, or false starts.
5
+
6
+ Build a markdown body with these sections:
7
+
8
+ ```markdown
9
+ # Plan: <title>
10
+
11
+ ## Goal
12
+
13
+
14
+ ## Steps
15
+ 1. …
16
+ 2. …
17
+
18
+ ## Decisions / open questions
19
+ - …
20
+
21
+ ## Status
22
+
23
+ ```
24
+
25
+ Update vs create — never guess a `--title` for an update:
26
+
27
+ **1. Path known** (attached/open in chat, or printed by an earlier `grounder plan` this conversation): update that exact file.
28
+
29
+ ```bash
30
+ {{GROUNDER_CLI}} plan "$(cat <<'EOF'
31
+ # Plan: …
32
+
33
+ EOF
34
+ )" --path <path-to-existing-plan.md>
35
+ ```
36
+
37
+ `--path` must resolve under this project's `plans/` dir; it always overwrites (no `--force`).
38
+
39
+ **2. Path unknown** (e.g. "update the plan" with nothing attached and no prior path this conversation): look it up, then update as in (1).
40
+
41
+ ```bash
42
+ {{GROUNDER_CLI}} plan list --limit 5
43
+ ```
44
+
45
+ Pick the path matching the user's intent; ask if none or several match.
46
+
47
+ **3. Genuinely new plan** (not an update): derive a `--title`.
48
+ - If the instruction names one explicitly (e.g. `save as "implementation-phase-1"` or `…phase-1.md`), use it (strip a trailing `.md`).
49
+ - Otherwise derive a short kebab-case name from the plan's title/goal and confirm it with the user before writing.
50
+
51
+ ```bash
52
+ {{GROUNDER_CLI}} plan "$(cat <<'EOF'
53
+ # Plan: …
54
+
55
+ EOF
56
+ )" --title <name>
57
+ ```
58
+
59
+ If the CLI refuses because that name already exists (non-zero exit; stderr names the conflict), tell the user and ask whether to overwrite (`--force`) or pick a different name. `--force` only resolves this title collision — it is never how you update a plan you already meant to target (use `--path` for that). **Never** silently pass `--force`.
60
+
61
+ Run from the linked project folder or any subdirectory beneath it.
62
+ The vault is outside the workspace — approve shell permissions if Cursor prompts you.
63
+
64
+ Do not compute vault paths or write files yourself — the CLI handles it.
65
+ Report the CLI output path from stdout to the user.
@@ -32,16 +32,16 @@ Rules:
32
32
 
33
33
  Then run from the linked project folder or any subdirectory beneath it:
34
34
 
35
- npx grounder handoff "<body>"
35
+ {{GROUNDER_CLI}} handoff "<body>"
36
36
 
37
37
  Optional short title slug (filename + frontmatter):
38
38
 
39
- npx grounder handoff --title <slug> "<body>"
39
+ {{GROUNDER_CLI}} handoff --title <slug> "<body>"
40
40
 
41
41
  For multi-line bodies, prefer a shell heredoc so quoting does not break:
42
42
 
43
43
  ```bash
44
- npx grounder handoff "$(cat <<'EOF'
44
+ {{GROUNDER_CLI}} handoff "$(cat <<'EOF'
45
45
  # Handoff: …
46
46
 
47
47
  EOF
@@ -6,11 +6,11 @@ From the linked project folder or any subdirectory beneath it:
6
6
 
7
7
  1. Get the current handoff (skips empty/unreadable files, same pick as the session-start teaser):
8
8
 
9
- npx grounder handoff list --head
9
+ {{GROUNDER_CLI}} handoff list --head
10
10
 
11
11
  2. If empty: tell the user there are no handoffs yet, then read repo `AGENTS.md` only and proceed.
12
12
 
13
- 3. Otherwise, read that file. If the user names a specific session instead, run `npx grounder handoff list --limit 5` and read the path they mean.
13
+ 3. Otherwise, read that file. If the user names a specific session instead, run `{{GROUNDER_CLI}} handoff list --limit 5` and read the path they mean.
14
14
 
15
15
  4. Read repo `AGENTS.md` (project conventions and constraints).
16
16
 
@@ -0,0 +1,16 @@
1
+ <!-- Reference shape for /grounder-plan. Not installed or filled by the CLI — slash commands embed this structure. -->
2
+
3
+ # Plan: <title>
4
+
5
+ ## Goal
6
+
7
+
8
+ ## Steps
9
+ 1. …
10
+ 2. …
11
+
12
+ ## Decisions / open questions
13
+ - …
14
+
15
+ ## Status
16
+