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,65 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { readGrounderState, recordAgentInstall, recordedFileHash } from "../connector/state.js";
4
+ import { VERSION } from "../index.js";
5
+ import { fileExists } from "../util/fs.js";
6
+ import { hashContent } from "../util/hash.js";
7
+ import { runtimeInvocation } from "./hook-runtime.js";
8
+ /**
9
+ * Install one slash-command markdown file with chezmoi-style drift detection.
10
+ *
11
+ * When the file already exists and `--force` is off:
12
+ * - on-disk hash matches the ledger → safe to refresh to the new template
13
+ * - no ledger hash, or on-disk hash differs → treat as user-edited (`modified`)
14
+ */
15
+ export async function installCommandFile(opts) {
16
+ const dest = path.join(opts.commandsDir, opts.filename);
17
+ const existed = await fileExists(dest);
18
+ const template = await readFile(path.join(opts.templateDir, opts.filename), "utf8");
19
+ const rendered = template.replaceAll("{{GROUNDER_CLI}}", runtimeInvocation(opts.homeDir));
20
+ const renderedHash = hashContent(rendered);
21
+ if (existed && !opts.force) {
22
+ const onDisk = await readFile(dest, "utf8");
23
+ const onDiskHash = hashContent(onDisk);
24
+ const state = await readGrounderState(opts.homeDir);
25
+ const recorded = recordedFileHash(state, opts.agentId, dest);
26
+ if (recorded !== undefined && recorded === onDiskHash) {
27
+ // Untouched since Grounder last wrote it — safe to auto-update.
28
+ if (onDiskHash === renderedHash) {
29
+ return { dest, status: "skipped", hash: renderedHash };
30
+ }
31
+ if (!opts.dryRun) {
32
+ await writeFile(dest, rendered);
33
+ }
34
+ return { dest, status: "overwritten", hash: renderedHash };
35
+ }
36
+ // Legacy (no hash) or user-edited — protect content.
37
+ return { dest, status: "modified" };
38
+ }
39
+ if (!opts.dryRun) {
40
+ await mkdir(path.dirname(dest), { recursive: true });
41
+ await writeFile(dest, rendered);
42
+ }
43
+ return {
44
+ dest,
45
+ status: existed ? "overwritten" : "created",
46
+ hash: renderedHash,
47
+ };
48
+ }
49
+ /**
50
+ * Persist per-file hashes after a command install. No-op when `files` is empty
51
+ * or `dryRun` is set.
52
+ */
53
+ export async function recordCommandFileHashes(opts) {
54
+ if (opts.dryRun || Object.keys(opts.files).length === 0) {
55
+ return;
56
+ }
57
+ await recordAgentInstall({
58
+ agentId: opts.agentId,
59
+ commandsSchema: opts.commandsSchema,
60
+ files: opts.files,
61
+ grounderVersion: VERSION,
62
+ homeDir: opts.homeDir,
63
+ });
64
+ }
65
+ //# sourceMappingURL=install-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-command.js","sourceRoot":"","sources":["../../src/agents/install-command.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,14 @@
1
- export type ArtifactStatus = "created" | "skipped" | "overwritten";
1
+ /**
2
+ * - `created` / `overwritten` — wrote new content
3
+ * - `skipped` — already current (or dry-run would no-op)
4
+ * - `modified` — on-disk content differs from last Grounder write; left alone
5
+ * unless `--force`
6
+ */
7
+ export type ArtifactStatus = "created" | "skipped" | "overwritten" | "modified";
2
8
  export interface AgentInstallOptions {
3
9
  force?: boolean;
10
+ /** Preview decisions without writing files or updating the install ledger. */
11
+ dryRun?: boolean;
4
12
  homeDir?: string;
5
13
  }
6
14
  export interface AgentInstallResult {
@@ -12,6 +20,16 @@ export interface AgentAdapter {
12
20
  readonly id: string;
13
21
  /** Human-readable display name, e.g. "Cursor". */
14
22
  readonly name: string;
23
+ /**
24
+ * Bump when `install()` output's contract changes (placeholders, file set,
25
+ * frontmatter). Recorded in `~/.grounder/state.json`.
26
+ */
27
+ readonly commandsSchema: number;
28
+ /**
29
+ * Bump when `installHooks()` output's contract changes. Omit when the
30
+ * adapter has no hooks. Recorded in `~/.grounder/state.json`.
31
+ */
32
+ readonly hooksSchema?: number;
15
33
  /** Returns true when this agent appears to be installed on the machine. */
16
34
  isInstalled(): Promise<boolean>;
17
35
  /** Absolute paths of artifacts this adapter installs (read-only inspect). */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,6EAA6E;IAC7E,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9C,oEAAoE;IACpE,OAAO,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChE,6EAA6E;IAC7E,YAAY,CAAC,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtE,0EAA0E;IAC1E,qBAAqB,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACpD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;AAEhF,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,2EAA2E;IAC3E,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,6EAA6E;IAC7E,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9C,oEAAoE;IACpE,OAAO,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChE,6EAA6E;IAC7E,YAAY,CAAC,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtE,0EAA0E;IAC1E,qBAAqB,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACpD"}
package/dist/cli.js CHANGED
@@ -6,70 +6,41 @@ import { runDoctor } from "./commands/doctor.js";
6
6
  import { runHandoffList } from "./commands/handoff/list.js";
7
7
  import { runHandoffPeek } from "./commands/handoff/peek.js";
8
8
  import { runHandoff } from "./commands/handoff.js";
9
+ import { runMigrate } from "./commands/migrate.js";
9
10
  import { runNote } from "./commands/note.js";
10
11
  import { runPathLogs } from "./commands/path/logs.js";
11
12
  import { runPathNotes } from "./commands/path/notes.js";
13
+ import { runPathPlans } from "./commands/path/plans.js";
14
+ import { runPlanList } from "./commands/plan/list.js";
15
+ import { runPlan } from "./commands/plan.js";
12
16
  import { runRepoInit } from "./commands/repo/init.js";
13
17
  import { runStatus } from "./commands/status.js";
18
+ import { notifyUpgradeIfNeeded } from "./commands/upgrade-banner.js";
14
19
  import { runVaultInit } from "./commands/vault/init.js";
20
+ import { printCommandHelpById, printFullHelp, printSynopsis, runHelp, wantsHelp } from "./help.js";
15
21
  const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
16
22
  const pkg = JSON.parse(readFileSync(path.join(pkgRoot, "package.json"), "utf8"));
17
- const USAGE = `grounder — connect git projects to Obsidian dev vaults for AI agents
18
-
19
- Usage:
20
- grounder vault init <path> Initialize vault + home config (once per machine)
21
- grounder init Connect the current repo to your vault
22
- grounder note <text> Write a note to the vault
23
- grounder handoff <text> Write a session handoff to vault logs/
24
- grounder handoff list Print recent handoff paths (newest first)
25
- grounder handoff list --head Print only the newest usable handoff path
26
- grounder path notes Print resolved notes directory
27
- grounder path logs Print resolved logs directory
28
- grounder status Snapshot of machine + project link + resolved paths
29
- grounder doctor Health checks with fix hints
30
-
31
- Hook plumbing:
32
- grounder handoff peek One-line latest-handoff teaser (used by session hooks)
33
-
34
- Options:
35
- -h, --help Show this help
36
- -v, --version Show version
37
-
38
- Init flags:
39
- --yes Skip confirmation prompts
40
- --force Overwrite existing generated files
41
- --id <id> Override detected project id (grounder init)
42
- --vault <path> Override home vault root for this run (grounder init)
43
- --agent <id> Install for a specific agent (repeatable; default: auto-detect)
44
- Supported: cursor, claude
45
- --hooks Also install session-start teaser hooks (vault init)
46
-
47
- Doctor flags:
48
- --global Machine-only checks (skip project/link checks)
49
-
50
- Note / handoff flags:
51
- --title <slug> Short slug in filename (default: slugified first line)
52
- --limit <n> Max paths for handoff list (default: 5)
53
- --head With handoff list, print only the newest usable path
54
- (skips empty/unreadable files; same pick as handoff peek)
55
-
56
- Quickstart:
57
- grounder vault init <path-to-your-vault>
58
- grounder init
59
- grounder note "my first note"
60
- grounder handoff "# Handoff\\n\\n## Next\\n1. …"
61
- grounder handoff list
62
- `;
63
- function printHelp() {
64
- process.stdout.write(USAGE);
65
- }
66
23
  function printVersion() {
67
24
  process.stdout.write(`${pkg.version}\n`);
68
25
  }
26
+ function exitUnknownCommand(args) {
27
+ process.stderr.write(`Unknown command: ${args.join(" ")}\n`);
28
+ process.stderr.write("Run `grounder --help` for a list of commands.\n");
29
+ process.exit(1);
30
+ }
31
+ /** Parent topic with no/unknown subcommand: print usage (exit 1) or help (exit 0). */
32
+ function exitParentTopic(commandId, asHelp) {
33
+ printCommandHelpById(commandId);
34
+ process.exit(asHelp ? 0 : 1);
35
+ }
69
36
  async function main() {
70
37
  const args = process.argv.slice(2);
71
- if (args.length === 0 || args[0] === "-h" || args[0] === "--help") {
72
- printHelp();
38
+ if (args.length === 0 || args[0] === "-h") {
39
+ printSynopsis();
40
+ process.exit(0);
41
+ }
42
+ if (args[0] === "--help") {
43
+ printFullHelp();
73
44
  process.exit(0);
74
45
  }
75
46
  if (args[0] === "-v" || args[0] === "--version") {
@@ -77,8 +48,22 @@ async function main() {
77
48
  return;
78
49
  }
79
50
  const [command, ...rest] = args;
80
- if (command === "vault" && rest[0] === "init") {
81
- process.exit(await runVaultInit(rest.slice(1)));
51
+ if (command === "help") {
52
+ process.exit(runHelp(rest));
53
+ }
54
+ // Skip banner when it would be noise: help, session hooks, or ledger refresh.
55
+ const skipUpgradeBanner = wantsHelp(args) ||
56
+ (command === "handoff" && rest[0] === "peek") ||
57
+ command === "migrate" ||
58
+ (command === "vault" && rest[0] === "init");
59
+ if (!skipUpgradeBanner) {
60
+ await notifyUpgradeIfNeeded();
61
+ }
62
+ if (command === "vault") {
63
+ if (rest[0] === "init") {
64
+ process.exit(await runVaultInit(rest.slice(1)));
65
+ }
66
+ exitParentTopic("vault", wantsHelp(rest) || rest.length === 0);
82
67
  }
83
68
  if (command === "init") {
84
69
  process.exit(await runRepoInit(rest));
@@ -95,11 +80,23 @@ async function main() {
95
80
  if (command === "handoff") {
96
81
  process.exit(await runHandoff(rest));
97
82
  }
98
- if (command === "path" && rest[0] === "notes") {
99
- process.exit(await runPathNotes(rest.slice(1)));
83
+ if (command === "plan" && rest[0] === "list") {
84
+ process.exit(await runPlanList(rest.slice(1)));
85
+ }
86
+ if (command === "plan") {
87
+ process.exit(await runPlan(rest));
100
88
  }
101
- if (command === "path" && rest[0] === "logs") {
102
- process.exit(await runPathLogs(rest.slice(1)));
89
+ if (command === "path") {
90
+ if (rest[0] === "notes") {
91
+ process.exit(await runPathNotes(rest.slice(1)));
92
+ }
93
+ if (rest[0] === "logs") {
94
+ process.exit(await runPathLogs(rest.slice(1)));
95
+ }
96
+ if (rest[0] === "plans") {
97
+ process.exit(await runPathPlans(rest.slice(1)));
98
+ }
99
+ exitParentTopic("path", wantsHelp(rest) || rest.length === 0);
103
100
  }
104
101
  if (command === "status") {
105
102
  process.exit(await runStatus(rest));
@@ -107,9 +104,10 @@ async function main() {
107
104
  if (command === "doctor") {
108
105
  process.exit(await runDoctor(rest));
109
106
  }
110
- process.stderr.write(`Unknown command: ${args.join(" ")}\n\n`);
111
- printHelp();
112
- process.exit(1);
107
+ if (command === "migrate") {
108
+ process.exit(await runMigrate(rest));
109
+ }
110
+ exitUnknownCommand(args);
113
111
  }
114
112
  main().catch((error) => {
115
113
  const message = error instanceof Error ? error.message : String(error);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { AgentAdapter, AgentInstallResult, ArtifactStatus } from "../agents/types.js";
2
+ export interface ApplyAgentInstallsOptions {
3
+ agents: AgentAdapter[];
4
+ force?: boolean;
5
+ /** Explicitly install/refresh session hooks (vault init --hooks / migrate --hooks). */
6
+ hooks?: boolean;
7
+ /**
8
+ * When true (migrate), also refresh hooks that were previously recorded or
9
+ * already present on disk — without installing hooks for agents that never
10
+ * opted in.
11
+ */
12
+ refreshInstalledHooks?: boolean;
13
+ dryRun?: boolean;
14
+ homeDir?: string;
15
+ }
16
+ export interface AgentApplyResult {
17
+ agent: AgentAdapter;
18
+ commands: AgentInstallResult;
19
+ hooks?: AgentInstallResult;
20
+ }
21
+ export interface ApplyAgentInstallsResult {
22
+ runtime?: {
23
+ cliPath: string;
24
+ status: ArtifactStatus;
25
+ mode: "symlink" | "copy";
26
+ };
27
+ agents: AgentApplyResult[];
28
+ }
29
+ /**
30
+ * Materialize runtime + install/refresh agent command (and optional hook)
31
+ * artifacts. Shared by `grounder vault init` and `grounder migrate`.
32
+ */
33
+ export declare function applyAgentInstalls(opts: ApplyAgentInstallsOptions): Promise<ApplyAgentInstallsResult>;
34
+ //# sourceMappingURL=apply-agent-installs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-agent-installs.d.ts","sourceRoot":"","sources":["../../src/commands/apply-agent-installs.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAS3F,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uFAAuF;IACvF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;KAAE,CAAC;IAChF,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AA+DD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,wBAAwB,CAAC,CA6FnC"}
@@ -0,0 +1,137 @@
1
+ import { hookFileHasGrounderEntry, installHookRuntime, runtimeCliPath, } from "../agents/hook-runtime.js";
2
+ import { recordAgentInstallState } from "../agents/index.js";
3
+ import { assertAgentSchemasSupported, readGrounderState, recordedHooksSchema, statePath, } from "../connector/state.js";
4
+ async function agentHasInstalledHooks(agent, homeDir) {
5
+ if (!agent.expectedHookArtifacts) {
6
+ return false;
7
+ }
8
+ const paths = agent.expectedHookArtifacts(homeDir);
9
+ for (const p of paths) {
10
+ if (await hookFileHasGrounderEntry(p)) {
11
+ return true;
12
+ }
13
+ }
14
+ return false;
15
+ }
16
+ async function shouldInstallHooks(agent, opts, state) {
17
+ if (!agent.installHooks) {
18
+ return false;
19
+ }
20
+ if (opts.hooks) {
21
+ return true;
22
+ }
23
+ if (!opts.refreshInstalledHooks) {
24
+ return false;
25
+ }
26
+ if (recordedHooksSchema(state, agent.id) > 0) {
27
+ return true;
28
+ }
29
+ return agentHasInstalledHooks(agent, opts.homeDir);
30
+ }
31
+ function commandLabel(status, artifactPath, dryRun) {
32
+ switch (status) {
33
+ case "skipped":
34
+ return dryRun ? "would skip (already current)" : "already current (skipped)";
35
+ case "modified":
36
+ return dryRun
37
+ ? `would skip locally modified (needs --force): ${artifactPath}`
38
+ : `locally modified (skipped — use --force): ${artifactPath}`;
39
+ case "created":
40
+ return dryRun ? `would install: ${artifactPath}` : `installed: ${artifactPath}`;
41
+ case "overwritten":
42
+ return dryRun ? `would update: ${artifactPath}` : `updated: ${artifactPath}`;
43
+ }
44
+ }
45
+ function hookLabel(status, artifactPath, dryRun) {
46
+ switch (status) {
47
+ case "skipped":
48
+ return dryRun ? "would skip (already current)" : "already exists (skipped)";
49
+ case "created":
50
+ return dryRun ? `would install: ${artifactPath}` : `installed: ${artifactPath}`;
51
+ case "overwritten":
52
+ return dryRun ? `would update: ${artifactPath}` : `updated: ${artifactPath}`;
53
+ case "modified":
54
+ return dryRun ? `would skip: ${artifactPath}` : `skipped: ${artifactPath}`;
55
+ }
56
+ }
57
+ /**
58
+ * Materialize runtime + install/refresh agent command (and optional hook)
59
+ * artifacts. Shared by `grounder vault init` and `grounder migrate`.
60
+ */
61
+ export async function applyAgentInstalls(opts) {
62
+ const force = opts.force ?? false;
63
+ const dryRun = opts.dryRun ?? false;
64
+ const homeDir = opts.homeDir;
65
+ const agents = opts.agents;
66
+ const state = await readGrounderState(homeDir);
67
+ assertAgentSchemasSupported(state, agents);
68
+ let runtime;
69
+ if (agents.length > 0) {
70
+ if (dryRun) {
71
+ process.stdout.write(`✓ Grounder runtime would refresh: ${runtimeCliPath(homeDir)}\n`);
72
+ }
73
+ else {
74
+ runtime = await installHookRuntime({ homeDir });
75
+ const runtimeLabel = runtime.status === "skipped"
76
+ ? "already exists (skipped)"
77
+ : `installed (${runtime.mode}): ${runtime.cliPath}`;
78
+ process.stdout.write(`✓ Grounder runtime ${runtimeLabel}\n`);
79
+ }
80
+ }
81
+ const results = [];
82
+ for (const agent of agents) {
83
+ const commands = await agent.install({ force, dryRun, homeDir });
84
+ for (const [artifactPath, status] of Object.entries(commands.artifacts)) {
85
+ process.stdout.write(`✓ ${agent.name} command ${commandLabel(status, artifactPath, dryRun)}\n`);
86
+ }
87
+ if (Object.keys(commands.artifacts).length === 0) {
88
+ process.stdout.write(`✓ ${agent.name}: no artifacts to install yet\n`);
89
+ }
90
+ let hooksResult;
91
+ let hooksInstalled = false;
92
+ if (await shouldInstallHooks(agent, opts, state)) {
93
+ const installHooks = agent.installHooks;
94
+ if (installHooks) {
95
+ hooksResult = await installHooks({ force, dryRun, homeDir });
96
+ hooksInstalled = true;
97
+ for (const [artifactPath, status] of Object.entries(hooksResult.artifacts)) {
98
+ process.stdout.write(`✓ ${agent.name} hook ${hookLabel(status, artifactPath, dryRun)}\n`);
99
+ }
100
+ }
101
+ }
102
+ if (!dryRun) {
103
+ const statuses = Object.values(commands.artifacts);
104
+ // Only bump the commands version in state when at least one file was
105
+ // written or already up to date. If every file was skipped as locally
106
+ // edited (or from before Grounder tracked hashes), do not mark state as
107
+ // current — otherwise plain migrate would silence doctor while leaving
108
+ // those old command files untouched.
109
+ const advanceCommandsSchema = statuses.length === 0 || statuses.some((status) => status !== "modified");
110
+ await recordAgentInstallState(agent, {
111
+ hooksInstalled,
112
+ homeDir,
113
+ advanceCommandsSchema,
114
+ });
115
+ }
116
+ results.push({ agent, commands, hooks: hooksResult });
117
+ }
118
+ if (agents.length > 0) {
119
+ const ledger = statePath(homeDir);
120
+ if (dryRun) {
121
+ process.stdout.write(state
122
+ ? `✓ Install state would update: ${ledger}\n`
123
+ : `✓ Install state would create: ${ledger}\n`);
124
+ }
125
+ else {
126
+ process.stdout.write(state ? `✓ Install state updated: ${ledger}\n` : `✓ Install state created: ${ledger}\n`);
127
+ }
128
+ }
129
+ const modifiedWithoutForce = !force &&
130
+ results.some((r) => Object.values(r.commands.artifacts).some((s) => s === "modified"));
131
+ if (modifiedWithoutForce) {
132
+ process.stdout.write("\nNote: some command files were left alone (local edits, or an install from before Grounder 0.3).\n" +
133
+ " To refresh them: grounder migrate --force\n");
134
+ }
135
+ return { runtime, agents: results };
136
+ }
137
+ //# sourceMappingURL=apply-agent-installs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-agent-installs.js","sourceRoot":"","sources":["../../src/commands/apply-agent-installs.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAyTD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/D;AAED,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBvF"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAqCA,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA2hBD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAED,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBvF"}