grounder 0.0.1 → 0.0.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +169 -2
  3. package/dist/agents/claude.d.ts +7 -0
  4. package/dist/agents/claude.d.ts.map +1 -0
  5. package/dist/agents/claude.js +46 -0
  6. package/dist/agents/claude.js.map +1 -0
  7. package/dist/agents/cursor.d.ts +7 -0
  8. package/dist/agents/cursor.d.ts.map +1 -0
  9. package/dist/agents/cursor.js +46 -0
  10. package/dist/agents/cursor.js.map +1 -0
  11. package/dist/agents/index.d.ts +11 -0
  12. package/dist/agents/index.d.ts.map +1 -0
  13. package/dist/agents/index.js +23 -0
  14. package/dist/agents/index.js.map +1 -0
  15. package/dist/agents/types.d.ts +20 -0
  16. package/dist/agents/types.d.ts.map +1 -0
  17. package/dist/agents/types.js +2 -0
  18. package/dist/agents/types.js.map +1 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +95 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands/handoff/list.d.ts +23 -0
  24. package/dist/commands/handoff/list.d.ts.map +1 -0
  25. package/dist/commands/handoff/list.js +64 -0
  26. package/dist/commands/handoff/list.js.map +1 -0
  27. package/dist/commands/handoff.d.ts +25 -0
  28. package/dist/commands/handoff.d.ts.map +1 -0
  29. package/dist/commands/handoff.js +47 -0
  30. package/dist/commands/handoff.js.map +1 -0
  31. package/dist/commands/note.d.ts +10 -0
  32. package/dist/commands/note.d.ts.map +1 -0
  33. package/dist/commands/note.js +33 -0
  34. package/dist/commands/note.js.map +1 -0
  35. package/dist/commands/path/logs.d.ts +7 -0
  36. package/dist/commands/path/logs.d.ts.map +1 -0
  37. package/dist/commands/path/logs.js +17 -0
  38. package/dist/commands/path/logs.js.map +1 -0
  39. package/dist/commands/path/notes.d.ts +7 -0
  40. package/dist/commands/path/notes.d.ts.map +1 -0
  41. package/dist/commands/path/notes.js +17 -0
  42. package/dist/commands/path/notes.js.map +1 -0
  43. package/dist/commands/repo/init.d.ts +11 -0
  44. package/dist/commands/repo/init.d.ts.map +1 -0
  45. package/dist/commands/repo/init.js +78 -0
  46. package/dist/commands/repo/init.js.map +1 -0
  47. package/dist/commands/require-linked.d.ts +7 -0
  48. package/dist/commands/require-linked.d.ts.map +1 -0
  49. package/dist/commands/require-linked.js +19 -0
  50. package/dist/commands/require-linked.js.map +1 -0
  51. package/dist/commands/vault/init.d.ts +11 -0
  52. package/dist/commands/vault/init.d.ts.map +1 -0
  53. package/dist/commands/vault/init.js +73 -0
  54. package/dist/commands/vault/init.js.map +1 -0
  55. package/dist/connector/git.d.ts +12 -0
  56. package/dist/connector/git.d.ts.map +1 -0
  57. package/dist/connector/git.js +53 -0
  58. package/dist/connector/git.js.map +1 -0
  59. package/dist/connector/home.d.ts +13 -0
  60. package/dist/connector/home.d.ts.map +1 -0
  61. package/dist/connector/home.js +52 -0
  62. package/dist/connector/home.js.map +1 -0
  63. package/dist/connector/linked.d.ts +25 -0
  64. package/dist/connector/linked.d.ts.map +1 -0
  65. package/dist/connector/linked.js +24 -0
  66. package/dist/connector/linked.js.map +1 -0
  67. package/dist/connector/project-id.d.ts +17 -0
  68. package/dist/connector/project-id.d.ts.map +1 -0
  69. package/dist/connector/project-id.js +102 -0
  70. package/dist/connector/project-id.js.map +1 -0
  71. package/dist/connector/repo.d.ts +9 -0
  72. package/dist/connector/repo.d.ts.map +1 -0
  73. package/dist/connector/repo.js +41 -0
  74. package/dist/connector/repo.js.map +1 -0
  75. package/dist/connector/vault.d.ts +12 -0
  76. package/dist/connector/vault.d.ts.map +1 -0
  77. package/dist/connector/vault.js +27 -0
  78. package/dist/connector/vault.js.map +1 -0
  79. package/dist/index.d.ts +2 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +7 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/util/fs.d.ts +8 -0
  84. package/dist/util/fs.d.ts.map +1 -0
  85. package/dist/util/fs.js +36 -0
  86. package/dist/util/fs.js.map +1 -0
  87. package/dist/util/parse-args.d.ts +12 -0
  88. package/dist/util/parse-args.d.ts.map +1 -0
  89. package/dist/util/parse-args.js +49 -0
  90. package/dist/util/parse-args.js.map +1 -0
  91. package/dist/util/path.d.ts +10 -0
  92. package/dist/util/path.d.ts.map +1 -0
  93. package/dist/util/path.js +22 -0
  94. package/dist/util/path.js.map +1 -0
  95. package/dist/util/project-id.d.ts +2 -0
  96. package/dist/util/project-id.d.ts.map +1 -0
  97. package/dist/util/project-id.js +8 -0
  98. package/dist/util/project-id.js.map +1 -0
  99. package/dist/util/prompt.d.ts +2 -0
  100. package/dist/util/prompt.d.ts.map +1 -0
  101. package/dist/util/prompt.js +19 -0
  102. package/dist/util/prompt.js.map +1 -0
  103. package/dist/util/timestamp-slug.d.ts +38 -0
  104. package/dist/util/timestamp-slug.d.ts.map +1 -0
  105. package/dist/util/timestamp-slug.js +66 -0
  106. package/dist/util/timestamp-slug.js.map +1 -0
  107. package/dist/util/yaml.d.ts +6 -0
  108. package/dist/util/yaml.d.ts.map +1 -0
  109. package/dist/util/yaml.js +13 -0
  110. package/dist/util/yaml.js.map +1 -0
  111. package/dist/vault/layout.d.ts +13 -0
  112. package/dist/vault/layout.d.ts.map +1 -0
  113. package/dist/vault/layout.js +22 -0
  114. package/dist/vault/layout.js.map +1 -0
  115. package/dist/vault/list-handoffs.d.ts +10 -0
  116. package/dist/vault/list-handoffs.d.ts.map +1 -0
  117. package/dist/vault/list-handoffs.js +30 -0
  118. package/dist/vault/list-handoffs.js.map +1 -0
  119. package/dist/vault/write-handoff.d.ts +21 -0
  120. package/dist/vault/write-handoff.d.ts.map +1 -0
  121. package/dist/vault/write-handoff.js +40 -0
  122. package/dist/vault/write-handoff.js.map +1 -0
  123. package/dist/vault/write-note.d.ts +11 -0
  124. package/dist/vault/write-note.d.ts.map +1 -0
  125. package/dist/vault/write-note.js +15 -0
  126. package/dist/vault/write-note.js.map +1 -0
  127. package/package.json +45 -10
  128. package/templates/agents/claude/commands/grounder-note.md +11 -0
  129. package/templates/agents/claude/commands/grounder-task-handoff.md +54 -0
  130. package/templates/agents/claude/commands/grounder-task.md +20 -0
  131. package/templates/agents/cursor/commands/grounder-note.md +11 -0
  132. package/templates/agents/cursor/commands/grounder-task-handoff.md +54 -0
  133. package/templates/agents/cursor/commands/grounder-task.md +20 -0
  134. package/templates/vault/session-handoff.md +19 -0
  135. package/index.js +0 -1
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Double-quote a YAML scalar and escape `\`, `"`, and newlines.
3
+ * Always quoted so values with `:`, `#`, leading spaces, etc. stay valid.
4
+ */
5
+ export function yamlDoubleQuoted(value) {
6
+ const escaped = value
7
+ .replace(/\\/g, "\\\\")
8
+ .replace(/"/g, '\\"')
9
+ .replace(/\r/g, "\\r")
10
+ .replace(/\n/g, "\\n");
11
+ return `"${escaped}"`;
12
+ }
13
+ //# sourceMappingURL=yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/util/yaml.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,OAAO,GAAG,KAAK;SAClB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzB,OAAO,IAAI,OAAO,GAAG,CAAC;AACxB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Pure vault layout: path segments only — no config files or env overrides.
3
+ */
4
+ export declare const PROJECTS_DIR = "10-Projects";
5
+ /** `<vault>/10-Projects` — parent of all project folders. */
6
+ export declare function projectsParent(vaultRoot: string): string;
7
+ /** `<vault>/10-Projects/{projectId}`. */
8
+ export declare function projectDir(vaultRoot: string, projectId: string): string;
9
+ /** `<vault>/10-Projects/{projectId}/notes`. */
10
+ export declare function notesDir(vaultRoot: string, projectId: string): string;
11
+ /** `<vault>/10-Projects/{projectId}/logs` — session handoffs. */
12
+ export declare function logsDir(vaultRoot: string, projectId: string): string;
13
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/vault/layout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,eAAO,MAAM,YAAY,gBAAgB,CAAC;AAE1C,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,iEAAiE;AACjE,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpE"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Pure vault layout: path segments only — no config files or env overrides.
3
+ */
4
+ import path from "node:path";
5
+ export const PROJECTS_DIR = "10-Projects";
6
+ /** `<vault>/10-Projects` — parent of all project folders. */
7
+ export function projectsParent(vaultRoot) {
8
+ return path.join(vaultRoot, PROJECTS_DIR);
9
+ }
10
+ /** `<vault>/10-Projects/{projectId}`. */
11
+ export function projectDir(vaultRoot, projectId) {
12
+ return path.join(vaultRoot, PROJECTS_DIR, projectId);
13
+ }
14
+ /** `<vault>/10-Projects/{projectId}/notes`. */
15
+ export function notesDir(vaultRoot, projectId) {
16
+ return path.join(vaultRoot, PROJECTS_DIR, projectId, "notes");
17
+ }
18
+ /** `<vault>/10-Projects/{projectId}/logs` — session handoffs. */
19
+ export function logsDir(vaultRoot, projectId) {
20
+ return path.join(vaultRoot, PROJECTS_DIR, projectId, "logs");
21
+ }
22
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/vault/layout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAC;AAE1C,6DAA6D;AAC7D,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,SAAiB;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,QAAQ,CAAC,SAAiB,EAAE,SAAiB;IAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,OAAO,CAAC,SAAiB,EAAE,SAAiB;IAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface ListHandoffsOptions {
2
+ /** Max paths to return (newest first). Omit to return all. */
3
+ limit?: number;
4
+ }
5
+ /**
6
+ * Lists handoff markdown files under `logsDir`, newest filename first.
7
+ * Returns absolute paths. Missing or empty dirs yield `[]`.
8
+ */
9
+ export declare function listHandoffs(logsDir: string, options?: ListHandoffsOptions): Promise<string[]>;
10
+ //# sourceMappingURL=list-handoffs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-handoffs.d.ts","sourceRoot":"","sources":["../../src/vault/list-handoffs.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB"}
@@ -0,0 +1,30 @@
1
+ import { readdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ /**
4
+ * Lists handoff markdown files under `logsDir`, newest filename first.
5
+ * Returns absolute paths. Missing or empty dirs yield `[]`.
6
+ */
7
+ export async function listHandoffs(logsDir, options = {}) {
8
+ let entries;
9
+ try {
10
+ entries = await readdir(logsDir);
11
+ }
12
+ catch (error) {
13
+ if (error.code === "ENOENT") {
14
+ return [];
15
+ }
16
+ throw error;
17
+ }
18
+ const paths = entries
19
+ .filter((name) => name.endsWith(".md"))
20
+ .sort((a, b) => (a < b ? 1 : a > b ? -1 : 0))
21
+ .map((name) => path.join(logsDir, name));
22
+ if (options.limit === undefined) {
23
+ return paths;
24
+ }
25
+ if (options.limit <= 0) {
26
+ return [];
27
+ }
28
+ return paths.slice(0, options.limit);
29
+ }
30
+ //# sourceMappingURL=list-handoffs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-handoffs.js","sourceRoot":"","sources":["../../src/vault/list-handoffs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,UAA+B,EAAE;IAEjC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,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,KAAK,GAAG,OAAO;SAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SACtC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SAC5C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAE3C,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,21 @@
1
+ /** Options for {@link writeHandoff}. */
2
+ export interface WriteHandoffOptions {
3
+ /** Project id written into YAML frontmatter. */
4
+ projectId: string;
5
+ /** Optional title slug for the filename and frontmatter. */
6
+ title?: string;
7
+ /** Git branch when known; omitted from frontmatter if unset. */
8
+ branch?: string;
9
+ /** Timestamp for filename prefix and `created` (default: now). */
10
+ now?: Date;
11
+ }
12
+ /**
13
+ * Writes a new handoff markdown file under `logsDir` (created if missing).
14
+ * Prepends YAML frontmatter (`project`, optional `branch`/`title`, `created`)
15
+ * ahead of `body`. Never overwrites — exclusive create with `_NN` on collision.
16
+ * @param logsDir - Absolute project logs directory.
17
+ * @param body - Agent-supplied markdown (sections such as Done / Next); not validated here.
18
+ * @returns Absolute path of the written file.
19
+ */
20
+ export declare function writeHandoff(logsDir: string, body: string, options: WriteHandoffOptions): Promise<string>;
21
+ //# sourceMappingURL=write-handoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-handoff.d.ts","sourceRoot":"","sources":["../../src/vault/write-handoff.ts"],"names":[],"mappings":"AAKA,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAoBD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
@@ -0,0 +1,40 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { writeUniqueMarkdown } from "../util/fs.js";
3
+ import { timestampedBasename } from "../util/timestamp-slug.js";
4
+ import { yamlDoubleQuoted } from "../util/yaml.js";
5
+ function buildFrontmatter(options) {
6
+ const lines = ["---", `project: ${yamlDoubleQuoted(options.projectId)}`];
7
+ if (options.branch) {
8
+ lines.push(`branch: ${yamlDoubleQuoted(options.branch)}`);
9
+ }
10
+ lines.push(`created: ${yamlDoubleQuoted(options.created)}`);
11
+ if (options.title) {
12
+ lines.push(`title: ${yamlDoubleQuoted(options.title)}`);
13
+ }
14
+ lines.push("---");
15
+ return `${lines.join("\n")}\n\n`;
16
+ }
17
+ /**
18
+ * Writes a new handoff markdown file under `logsDir` (created if missing).
19
+ * Prepends YAML frontmatter (`project`, optional `branch`/`title`, `created`)
20
+ * ahead of `body`. Never overwrites — exclusive create with `_NN` on collision.
21
+ * @param logsDir - Absolute project logs directory.
22
+ * @param body - Agent-supplied markdown (sections such as Done / Next); not validated here.
23
+ * @returns Absolute path of the written file.
24
+ */
25
+ export async function writeHandoff(logsDir, body, options) {
26
+ const now = options.now ?? new Date();
27
+ await mkdir(logsDir, { recursive: true });
28
+ const basename = timestampedBasename(body, {
29
+ title: options.title,
30
+ now,
31
+ });
32
+ const content = buildFrontmatter({
33
+ projectId: options.projectId,
34
+ branch: options.branch,
35
+ created: now.toISOString(),
36
+ title: options.title,
37
+ }) + body;
38
+ return writeUniqueMarkdown(logsDir, basename, content);
39
+ }
40
+ //# sourceMappingURL=write-handoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-handoff.js","sourceRoot":"","sources":["../../src/vault/write-handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAcnD,SAAS,gBAAgB,CAAC,OAKzB;IACC,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,YAAY,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACzE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,WAAW,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,YAAY,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5D,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,UAAU,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,IAAY,EACZ,OAA4B;IAE5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACtC,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,EAAE;QACzC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,GAAG;KACJ,CAAC,CAAC;IACH,MAAM,OAAO,GACX,gBAAgB,CAAC;QACf,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,GAAG,IAAI,CAAC;IAEZ,OAAO,mBAAmB,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface WriteNoteOptions {
2
+ title?: string;
3
+ now?: Date;
4
+ }
5
+ /**
6
+ * Writes a new note markdown file under `notesDir` (created if missing).
7
+ * Never overwrites — exclusive create with `_NN` on collision.
8
+ * @returns Absolute path of the written file.
9
+ */
10
+ export declare function writeNote(notesDir: string, text: string, options?: WriteNoteOptions): Promise<string>;
11
+ //# sourceMappingURL=write-note.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-note.d.ts","sourceRoot":"","sources":["../../src/vault/write-note.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAMjB"}
@@ -0,0 +1,15 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { writeUniqueMarkdown } from "../util/fs.js";
3
+ import { timestampedBasename } from "../util/timestamp-slug.js";
4
+ /**
5
+ * Writes a new note markdown file under `notesDir` (created if missing).
6
+ * Never overwrites — exclusive create with `_NN` on collision.
7
+ * @returns Absolute path of the written file.
8
+ */
9
+ export async function writeNote(notesDir, text, options = {}) {
10
+ const now = options.now ?? new Date();
11
+ await mkdir(notesDir, { recursive: true });
12
+ const basename = timestampedBasename(text, { title: options.title, now });
13
+ return writeUniqueMarkdown(notesDir, basename, text);
14
+ }
15
+ //# sourceMappingURL=write-note.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-note.js","sourceRoot":"","sources":["../../src/vault/write-note.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAOhE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAgB,EAChB,IAAY,EACZ,UAA4B,EAAE;IAE9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;IACtC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1E,OAAO,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACvD,CAAC"}
package/package.json CHANGED
@@ -1,13 +1,48 @@
1
1
  {
2
2
  "name": "grounder",
3
- "version": "0.0.1",
4
- "description": "",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
3
+ "version": "0.0.2",
4
+ "description": "Connect git projects to Obsidian dev vaults for AI agent memory",
5
+ "type": "module",
6
+ "bin": {
7
+ "grounder": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "templates"
12
+ ],
13
+ "engines": {
14
+ "node": ">=18"
15
+ },
16
+ "keywords": [
17
+ "obsidian",
18
+ "cursor",
19
+ "mcp",
20
+ "ai",
21
+ "cli"
22
+ ],
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/andrej-kolic/grounder.git",
27
+ "directory": "packages/grounder"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/andrej-kolic/grounder/issues"
8
31
  },
9
- "keywords": [],
10
- "author": "",
11
- "license": "ISC",
12
- "type": "commonjs"
13
- }
32
+ "homepage": "https://github.com/andrej-kolic/grounder/tree/main/packages/grounder#readme",
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "provenance": true
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^26.0.1",
39
+ "typescript": "^6.0.3",
40
+ "vitest": "^4.1.9"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc -p tsconfig.build.json",
44
+ "typecheck": "tsc -p tsconfig.json --noEmit",
45
+ "pretest": "pnpm run build",
46
+ "test": "vitest run"
47
+ }
48
+ }
@@ -0,0 +1,11 @@
1
+ Save a note to the Obsidian vault for this project.
2
+
3
+ Run from the linked project folder or any subdirectory beneath it:
4
+
5
+ npx grounder note "<user text>"
6
+
7
+ The vault is outside the workspace — grant shell permissions if Claude Code prompts you.
8
+
9
+ Use the text after `/grounder-note` as the note body.
10
+ Do not compute vault paths or write files yourself — the CLI handles it.
11
+ Report the CLI output path from stdout to the user.
@@ -0,0 +1,54 @@
1
+ Write a session handoff checkpoint to the Obsidian vault for this project.
2
+
3
+ Summarize the session into a structured handoff — not a chat transcript.
4
+ Do not dump tool traces, full conversation, or false starts.
5
+
6
+ Build a markdown body with these sections (lean; roughly half a screen to one screen):
7
+
8
+ ```markdown
9
+ # Handoff: <short label>
10
+
11
+ ## Done
12
+ - …
13
+
14
+ ## Next
15
+ 1. … # ordered; most important section for resume — required
16
+ 2. …
17
+
18
+ ## Blockers
19
+ - None | …
20
+
21
+ ## Decisions
22
+ - … # include rejected alternatives / pitfalls when useful
23
+
24
+ ## Files
25
+ - path/to/relevant.ts
26
+ ```
27
+
28
+ Rules:
29
+ - **Next is mandatory and ordered** — if only one section is read, this is it
30
+ - Empty sections are OK (`Blockers: None` beats omission)
31
+ - Few concrete file paths, not an exhaustive diff
32
+
33
+ Then run from the linked project folder or any subdirectory beneath it:
34
+
35
+ npx grounder handoff "<body>"
36
+
37
+ Optional short title slug (filename + frontmatter):
38
+
39
+ npx grounder handoff --title <slug> "<body>"
40
+
41
+ For multi-line bodies, prefer a shell heredoc so quoting does not break:
42
+
43
+ ```bash
44
+ npx grounder handoff "$(cat <<'EOF'
45
+ # Handoff: …
46
+
47
+ EOF
48
+ )"
49
+ ```
50
+
51
+ The vault is outside the workspace — grant shell permissions if Claude Code prompts you.
52
+
53
+ Do not compute vault paths or write files yourself — the CLI handles it.
54
+ Report the CLI output path from stdout to the user.
@@ -0,0 +1,20 @@
1
+ Hydrate this session from the latest vault handoff and repo truth.
2
+
3
+ Read-only — do not write to the vault. Do not invent vault paths.
4
+
5
+ From the linked project folder or any subdirectory beneath it:
6
+
7
+ 1. List recent handoffs (newest first):
8
+
9
+ npx grounder handoff list --limit 5
10
+
11
+ 2. If the list is empty: tell the user there are no handoffs yet, then read repo `AGENTS.md` only and proceed.
12
+
13
+ 3. If handoffs exist: read the newest file (first path). Optionally skim other listed paths if the user names a session or the newest is clearly wrong.
14
+
15
+ 4. Read repo `AGENTS.md` (project conventions and constraints).
16
+
17
+ 5. Summarize briefly what is next (from the handoff `## Next` section when present), then start work.
18
+
19
+ The vault is outside the workspace — grant shell permissions if Claude Code prompts you.
20
+ Use free-text after `/grounder-task` as optional focus (session name, index, or task hint).
@@ -0,0 +1,11 @@
1
+ Save a note to the Obsidian vault for this project.
2
+
3
+ Run from the linked project folder or any subdirectory beneath it:
4
+
5
+ npx grounder note "<user text>"
6
+
7
+ The vault is outside the workspace — approve shell permissions if Cursor prompts you.
8
+
9
+ Use the text after `/grounder-note` as the note body.
10
+ Do not compute vault paths or write files yourself — the CLI handles it.
11
+ Report the CLI output path from stdout to the user.
@@ -0,0 +1,54 @@
1
+ Write a session handoff checkpoint to the Obsidian vault for this project.
2
+
3
+ Summarize the session into a structured handoff — not a chat transcript.
4
+ Do not dump tool traces, full conversation, or false starts.
5
+
6
+ Build a markdown body with these sections (lean; roughly half a screen to one screen):
7
+
8
+ ```markdown
9
+ # Handoff: <short label>
10
+
11
+ ## Done
12
+ - …
13
+
14
+ ## Next
15
+ 1. … # ordered; most important section for resume — required
16
+ 2. …
17
+
18
+ ## Blockers
19
+ - None | …
20
+
21
+ ## Decisions
22
+ - … # include rejected alternatives / pitfalls when useful
23
+
24
+ ## Files
25
+ - path/to/relevant.ts
26
+ ```
27
+
28
+ Rules:
29
+ - **Next is mandatory and ordered** — if only one section is read, this is it
30
+ - Empty sections are OK (`Blockers: None` beats omission)
31
+ - Few concrete file paths, not an exhaustive diff
32
+
33
+ Then run from the linked project folder or any subdirectory beneath it:
34
+
35
+ npx grounder handoff "<body>"
36
+
37
+ Optional short title slug (filename + frontmatter):
38
+
39
+ npx grounder handoff --title <slug> "<body>"
40
+
41
+ For multi-line bodies, prefer a shell heredoc so quoting does not break:
42
+
43
+ ```bash
44
+ npx grounder handoff "$(cat <<'EOF'
45
+ # Handoff: …
46
+
47
+ EOF
48
+ )"
49
+ ```
50
+
51
+ The vault is outside the workspace — approve shell permissions if Cursor prompts you.
52
+
53
+ Do not compute vault paths or write files yourself — the CLI handles it.
54
+ Report the CLI output path from stdout to the user.
@@ -0,0 +1,20 @@
1
+ Hydrate this session from the latest vault handoff and repo truth.
2
+
3
+ Read-only — do not write to the vault. Do not invent vault paths.
4
+
5
+ From the linked project folder or any subdirectory beneath it:
6
+
7
+ 1. List recent handoffs (newest first):
8
+
9
+ npx grounder handoff list --limit 5
10
+
11
+ 2. If the list is empty: tell the user there are no handoffs yet, then read repo `AGENTS.md` only and proceed.
12
+
13
+ 3. If handoffs exist: read the newest file (first path). Optionally skim other listed paths if the user names a session or the newest is clearly wrong.
14
+
15
+ 4. Read repo `AGENTS.md` (project conventions and constraints).
16
+
17
+ 5. Summarize briefly what is next (from the handoff `## Next` section when present), then start work.
18
+
19
+ The vault is outside the workspace — approve shell permissions if Cursor prompts you.
20
+ Use free-text after `/grounder-task` as optional focus (session name, index, or task hint).
@@ -0,0 +1,19 @@
1
+ <!-- Reference shape for /grounder-task-handoff. Not installed or filled by the CLI — slash commands embed this structure. -->
2
+
3
+ # Handoff: <title or short label>
4
+
5
+ ## Done
6
+ - …
7
+
8
+ ## Next
9
+ 1. …
10
+ 2. …
11
+
12
+ ## Blockers
13
+ - None
14
+
15
+ ## Decisions
16
+ - …
17
+
18
+ ## Files
19
+ - path/to/relevant.ts
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = {};