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.
- package/README.md +81 -32
- package/dist/agents/claude.d.ts +1 -0
- package/dist/agents/claude.d.ts.map +1 -1
- package/dist/agents/claude.js +38 -13
- package/dist/agents/claude.js.map +1 -1
- package/dist/agents/cursor.d.ts +1 -0
- package/dist/agents/cursor.d.ts.map +1 -1
- package/dist/agents/cursor.js +38 -13
- package/dist/agents/cursor.js.map +1 -1
- package/dist/agents/hook-runtime.d.ts +65 -21
- package/dist/agents/hook-runtime.d.ts.map +1 -1
- package/dist/agents/hook-runtime.js +172 -31
- package/dist/agents/hook-runtime.js.map +1 -1
- package/dist/agents/index.d.ts +18 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +27 -4
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/install-command.d.ts +37 -0
- package/dist/agents/install-command.d.ts.map +1 -0
- package/dist/agents/install-command.js +65 -0
- package/dist/agents/install-command.js.map +1 -0
- package/dist/agents/types.d.ts +19 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/cli.js +58 -60
- package/dist/cli.js.map +1 -1
- package/dist/commands/apply-agent-installs.d.ts +34 -0
- package/dist/commands/apply-agent-installs.d.ts.map +1 -0
- package/dist/commands/apply-agent-installs.js +137 -0
- package/dist/commands/apply-agent-installs.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +202 -51
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/handoff/list.d.ts.map +1 -1
- package/dist/commands/handoff/list.js +5 -0
- package/dist/commands/handoff/list.js.map +1 -1
- package/dist/commands/handoff/peek.d.ts +5 -2
- package/dist/commands/handoff/peek.d.ts.map +1 -1
- package/dist/commands/handoff/peek.js +47 -6
- package/dist/commands/handoff/peek.js.map +1 -1
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +5 -0
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/migrate.d.ts +23 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +104 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/note.d.ts.map +1 -1
- package/dist/commands/note.js +5 -0
- package/dist/commands/note.js.map +1 -1
- package/dist/commands/package-version-notice.d.ts +18 -0
- package/dist/commands/package-version-notice.d.ts.map +1 -0
- package/dist/commands/package-version-notice.js +39 -0
- package/dist/commands/package-version-notice.js.map +1 -0
- package/dist/commands/path/logs.d.ts +1 -1
- package/dist/commands/path/logs.d.ts.map +1 -1
- package/dist/commands/path/logs.js +6 -1
- package/dist/commands/path/logs.js.map +1 -1
- package/dist/commands/path/notes.d.ts +1 -1
- package/dist/commands/path/notes.d.ts.map +1 -1
- package/dist/commands/path/notes.js +6 -1
- package/dist/commands/path/notes.js.map +1 -1
- package/dist/commands/path/plans.d.ts +7 -0
- package/dist/commands/path/plans.d.ts.map +1 -0
- package/dist/commands/path/plans.js +22 -0
- package/dist/commands/path/plans.js.map +1 -0
- package/dist/commands/plan/list.d.ts +23 -0
- package/dist/commands/plan/list.d.ts.map +1 -0
- package/dist/commands/plan/list.js +69 -0
- package/dist/commands/plan/list.js.map +1 -0
- package/dist/commands/plan.d.ts +34 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +121 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/repo/init.d.ts.map +1 -1
- package/dist/commands/repo/init.js +12 -1
- package/dist/commands/repo/init.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +52 -9
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/upgrade-banner.d.ts +9 -0
- package/dist/commands/upgrade-banner.d.ts.map +1 -0
- package/dist/commands/upgrade-banner.js +27 -0
- package/dist/commands/upgrade-banner.js.map +1 -0
- package/dist/commands/vault/init.d.ts.map +1 -1
- package/dist/commands/vault/init.js +18 -29
- package/dist/commands/vault/init.js.map +1 -1
- package/dist/connector/repo.d.ts +2 -0
- package/dist/connector/repo.d.ts.map +1 -1
- package/dist/connector/repo.js +12 -1
- package/dist/connector/repo.js.map +1 -1
- package/dist/connector/state.d.ts +95 -0
- package/dist/connector/state.d.ts.map +1 -0
- package/dist/connector/state.js +189 -0
- package/dist/connector/state.js.map +1 -0
- package/dist/connector/unsupported-schema.d.ts +9 -0
- package/dist/connector/unsupported-schema.d.ts.map +1 -0
- package/dist/connector/unsupported-schema.js +14 -0
- package/dist/connector/unsupported-schema.js.map +1 -0
- package/dist/connector/vault.d.ts +2 -0
- package/dist/connector/vault.d.ts.map +1 -1
- package/dist/connector/vault.js +6 -1
- package/dist/connector/vault.js.map +1 -1
- package/dist/help.d.ts +45 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +355 -0
- package/dist/help.js.map +1 -0
- package/dist/util/fs.d.ts +6 -0
- package/dist/util/fs.d.ts.map +1 -1
- package/dist/util/fs.js +15 -1
- package/dist/util/fs.js.map +1 -1
- package/dist/util/hash.d.ts +3 -0
- package/dist/util/hash.d.ts.map +1 -0
- package/dist/util/hash.js +6 -0
- package/dist/util/hash.js.map +1 -0
- package/dist/util/path.d.ts +10 -0
- package/dist/util/path.d.ts.map +1 -1
- package/dist/util/path.js +31 -0
- package/dist/util/path.js.map +1 -1
- package/dist/util/plan-name.d.ts +10 -0
- package/dist/util/plan-name.d.ts.map +1 -0
- package/dist/util/plan-name.js +18 -0
- package/dist/util/plan-name.js.map +1 -0
- package/dist/util/semver.d.ts +10 -0
- package/dist/util/semver.d.ts.map +1 -0
- package/dist/util/semver.js +40 -0
- package/dist/util/semver.js.map +1 -0
- package/dist/vault/layout.d.ts +2 -0
- package/dist/vault/layout.d.ts.map +1 -1
- package/dist/vault/layout.js +4 -0
- package/dist/vault/layout.js.map +1 -1
- package/dist/vault/list-plans.d.ts +11 -0
- package/dist/vault/list-plans.d.ts.map +1 -0
- package/dist/vault/list-plans.js +40 -0
- package/dist/vault/list-plans.js.map +1 -0
- package/dist/vault/write-plan.d.ts +28 -0
- package/dist/vault/write-plan.d.ts.map +1 -0
- package/dist/vault/write-plan.js +61 -0
- package/dist/vault/write-plan.js.map +1 -0
- package/package.json +1 -1
- package/templates/agents/claude/commands/grounder-note.md +1 -1
- package/templates/agents/claude/commands/grounder-plan.md +65 -0
- package/templates/agents/claude/commands/grounder-task-handoff.md +3 -3
- package/templates/agents/claude/commands/grounder-task.md +2 -2
- package/templates/agents/cursor/commands/grounder-note.md +1 -1
- package/templates/agents/cursor/commands/grounder-plan.md +65 -0
- package/templates/agents/cursor/commands/grounder-task-handoff.md +3 -3
- package/templates/agents/cursor/commands/grounder-task.md +2 -2
- 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
|
@@ -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
|
-
|
|
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
|
-
|
|
35
|
+
{{GROUNDER_CLI}} handoff "<body>"
|
|
36
36
|
|
|
37
37
|
Optional short title slug (filename + frontmatter):
|
|
38
38
|
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 `
|
|
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
|
-
|
|
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
|
-
|
|
35
|
+
{{GROUNDER_CLI}} handoff "<body>"
|
|
36
36
|
|
|
37
37
|
Optional short title slug (filename + frontmatter):
|
|
38
38
|
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 `
|
|
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
|
|