grounder 0.4.0 → 0.6.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 +150 -271
- package/dist/agents/claude.d.ts +4 -4
- package/dist/agents/claude.d.ts.map +1 -1
- package/dist/agents/claude.js +158 -178
- package/dist/agents/claude.js.map +1 -1
- package/dist/agents/cursor.d.ts +3 -3
- package/dist/agents/cursor.d.ts.map +1 -1
- package/dist/agents/cursor.js +97 -143
- package/dist/agents/cursor.js.map +1 -1
- package/dist/agents/home-skills.d.ts +46 -0
- package/dist/agents/home-skills.d.ts.map +1 -0
- package/dist/agents/home-skills.js +83 -0
- package/dist/agents/home-skills.js.map +1 -0
- package/dist/agents/hook-fragment.d.ts +52 -0
- package/dist/agents/hook-fragment.d.ts.map +1 -0
- package/dist/agents/hook-fragment.js +76 -0
- package/dist/agents/hook-fragment.js.map +1 -0
- package/dist/agents/hook-install.d.ts +62 -0
- package/dist/agents/hook-install.d.ts.map +1 -0
- package/dist/agents/hook-install.js +74 -0
- package/dist/agents/hook-install.js.map +1 -0
- package/dist/agents/hook-runtime.d.ts +80 -13
- package/dist/agents/hook-runtime.d.ts.map +1 -1
- package/dist/agents/hook-runtime.js +278 -74
- package/dist/agents/hook-runtime.js.map +1 -1
- package/dist/agents/index.d.ts +8 -14
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +13 -19
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/types.d.ts +56 -16
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/cli.js +15 -10
- package/dist/cli.js.map +1 -1
- package/dist/commands/apply.d.ts +69 -0
- package/dist/commands/apply.d.ts.map +1 -0
- package/dist/commands/apply.js +238 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +197 -101
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/handoff/list.d.ts +23 -13
- package/dist/commands/handoff/list.d.ts.map +1 -1
- package/dist/commands/handoff/list.js +28 -16
- package/dist/commands/handoff/list.js.map +1 -1
- package/dist/commands/handoff/peek.d.ts +1 -1
- package/dist/commands/handoff/peek.d.ts.map +1 -1
- package/dist/commands/handoff/peek.js +28 -12
- package/dist/commands/handoff/peek.js.map +1 -1
- package/dist/commands/handoff.d.ts +2 -0
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +10 -1
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/install-drift.d.ts +34 -0
- package/dist/commands/install-drift.d.ts.map +1 -0
- package/dist/commands/install-drift.js +72 -0
- package/dist/commands/install-drift.js.map +1 -0
- package/dist/commands/link.d.ts +12 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/{repo/init.js → link.js} +35 -27
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/migrate.d.ts +11 -3
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +66 -34
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/note/list.d.ts +17 -9
- package/dist/commands/note/list.d.ts.map +1 -1
- package/dist/commands/note/list.js +19 -14
- package/dist/commands/note/list.js.map +1 -1
- package/dist/commands/note.d.ts +2 -0
- package/dist/commands/note.d.ts.map +1 -1
- package/dist/commands/note.js +10 -1
- package/dist/commands/note.js.map +1 -1
- package/dist/commands/output.d.ts +22 -2
- package/dist/commands/output.d.ts.map +1 -1
- package/dist/commands/output.js +18 -6
- package/dist/commands/output.js.map +1 -1
- package/dist/commands/overview.d.ts +33 -0
- package/dist/commands/overview.d.ts.map +1 -0
- package/dist/commands/overview.js +150 -0
- package/dist/commands/overview.js.map +1 -0
- package/dist/commands/plan/list.d.ts +20 -12
- package/dist/commands/plan/list.d.ts.map +1 -1
- package/dist/commands/plan/list.js +22 -17
- package/dist/commands/plan/list.js.map +1 -1
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +12 -2
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/render-artifact-table.d.ts +85 -0
- package/dist/commands/render-artifact-table.d.ts.map +1 -0
- package/dist/commands/render-artifact-table.js +232 -0
- package/dist/commands/render-artifact-table.js.map +1 -0
- package/dist/commands/require-linked.js +2 -2
- package/dist/commands/require-linked.js.map +1 -1
- package/dist/commands/search.d.ts +23 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +288 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/{vault/init.d.ts → setup.d.ts} +5 -4
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +210 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +273 -83
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/upgrade-banner.d.ts +2 -2
- package/dist/commands/upgrade-banner.js +2 -2
- package/dist/connector/home.d.ts +12 -0
- package/dist/connector/home.d.ts.map +1 -1
- package/dist/connector/home.js +26 -2
- package/dist/connector/home.js.map +1 -1
- package/dist/connector/ledger-migrations.d.ts +55 -0
- package/dist/connector/ledger-migrations.d.ts.map +1 -0
- package/dist/connector/ledger-migrations.js +94 -0
- package/dist/connector/ledger-migrations.js.map +1 -0
- package/dist/connector/state.d.ts +97 -60
- package/dist/connector/state.d.ts.map +1 -1
- package/dist/connector/state.js +165 -107
- package/dist/connector/state.js.map +1 -1
- 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 +3 -3
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +97 -56
- package/dist/help.js.map +1 -1
- package/dist/reconcile/apply.d.ts +31 -0
- package/dist/reconcile/apply.d.ts.map +1 -0
- package/dist/reconcile/apply.js +97 -0
- package/dist/reconcile/apply.js.map +1 -0
- package/dist/reconcile/core.d.ts +82 -0
- package/dist/reconcile/core.d.ts.map +1 -0
- package/dist/reconcile/core.js +163 -0
- package/dist/reconcile/core.js.map +1 -0
- package/dist/reconcile/disk.d.ts +13 -0
- package/dist/reconcile/disk.d.ts.map +1 -0
- package/dist/reconcile/disk.js +28 -0
- package/dist/reconcile/disk.js.map +1 -0
- package/dist/util/frontmatter.d.ts +9 -7
- package/dist/util/frontmatter.d.ts.map +1 -1
- package/dist/util/frontmatter.js +29 -4
- package/dist/util/frontmatter.js.map +1 -1
- package/dist/util/fs.d.ts +14 -0
- package/dist/util/fs.d.ts.map +1 -1
- package/dist/util/fs.js +27 -1
- package/dist/util/fs.js.map +1 -1
- package/dist/util/merge-json.d.ts +13 -2
- package/dist/util/merge-json.d.ts.map +1 -1
- package/dist/util/merge-json.js +24 -10
- package/dist/util/merge-json.js.map +1 -1
- package/dist/util/path.d.ts +23 -0
- package/dist/util/path.d.ts.map +1 -1
- package/dist/util/path.js +39 -0
- package/dist/util/path.js.map +1 -1
- package/dist/vault/list-handoffs.d.ts +14 -2
- package/dist/vault/list-handoffs.d.ts.map +1 -1
- package/dist/vault/list-handoffs.js +40 -23
- package/dist/vault/list-handoffs.js.map +1 -1
- package/dist/vault/list-markdown.d.ts +8 -0
- package/dist/vault/list-markdown.d.ts.map +1 -0
- package/dist/vault/list-markdown.js +35 -0
- package/dist/vault/list-markdown.js.map +1 -0
- package/dist/vault/list-notes.d.ts +15 -6
- package/dist/vault/list-notes.d.ts.map +1 -1
- package/dist/vault/list-notes.js +23 -27
- package/dist/vault/list-notes.js.map +1 -1
- package/dist/vault/list-plans.d.ts +12 -3
- package/dist/vault/list-plans.d.ts.map +1 -1
- package/dist/vault/list-plans.js +20 -24
- package/dist/vault/list-plans.js.map +1 -1
- package/dist/vault/search.d.ts +55 -0
- package/dist/vault/search.d.ts.map +1 -0
- package/dist/vault/search.js +432 -0
- package/dist/vault/search.js.map +1 -0
- package/dist/vault/write-handoff.d.ts +2 -0
- package/dist/vault/write-handoff.d.ts.map +1 -1
- package/dist/vault/write-handoff.js +5 -0
- package/dist/vault/write-handoff.js.map +1 -1
- package/dist/vault/write-note.d.ts +2 -0
- package/dist/vault/write-note.d.ts.map +1 -1
- package/dist/vault/write-note.js +9 -1
- package/dist/vault/write-note.js.map +1 -1
- package/dist/vault/write-plan.d.ts +4 -0
- package/dist/vault/write-plan.d.ts.map +1 -1
- package/dist/vault/write-plan.js +14 -1
- package/dist/vault/write-plan.js.map +1 -1
- package/package.json +11 -4
- package/templates/agents/claude/skills/grounder-handoff/SKILL.md +73 -0
- package/templates/agents/claude/{commands/grounder-note.md → skills/grounder-note/SKILL.md} +12 -2
- package/templates/agents/claude/skills/grounder-overview/SKILL.md +21 -0
- package/templates/agents/claude/{commands/grounder-plan.md → skills/grounder-plan/SKILL.md} +13 -5
- package/templates/agents/claude/skills/grounder-recall/SKILL.md +34 -0
- package/templates/agents/claude/skills/grounder-search/SKILL.md +152 -0
- package/templates/agents/cursor/skills/grounder-handoff/SKILL.md +73 -0
- package/templates/agents/cursor/{commands/grounder-note.md → skills/grounder-note/SKILL.md} +12 -2
- package/templates/agents/cursor/skills/grounder-overview/SKILL.md +21 -0
- package/templates/agents/cursor/{commands/grounder-plan.md → skills/grounder-plan/SKILL.md} +13 -5
- package/templates/agents/cursor/skills/grounder-recall/SKILL.md +34 -0
- package/templates/agents/cursor/skills/grounder-search/SKILL.md +152 -0
- package/templates/vault/plan.md +1 -1
- package/templates/vault/session-handoff.md +2 -1
- package/dist/agents/install-command.d.ts +0 -35
- package/dist/agents/install-command.d.ts.map +0 -1
- package/dist/agents/install-command.js +0 -65
- package/dist/agents/install-command.js.map +0 -1
- package/dist/commands/apply-agent-installs.d.ts +0 -34
- package/dist/commands/apply-agent-installs.d.ts.map +0 -1
- package/dist/commands/apply-agent-installs.js +0 -137
- package/dist/commands/apply-agent-installs.js.map +0 -1
- package/dist/commands/repo/init.d.ts +0 -11
- package/dist/commands/repo/init.d.ts.map +0 -1
- package/dist/commands/repo/init.js.map +0 -1
- package/dist/commands/vault/init.d.ts.map +0 -1
- package/dist/commands/vault/init.js +0 -90
- package/dist/commands/vault/init.js.map +0 -1
- package/templates/agents/claude/commands/grounder-task-handoff.md +0 -54
- package/templates/agents/claude/commands/grounder-task.md +0 -22
- package/templates/agents/cursor/commands/grounder-task-handoff.md +0 -54
- package/templates/agents/cursor/commands/grounder-task.md +0 -22
|
@@ -7,13 +7,13 @@ import { listHandoffs } from "../../vault/list-handoffs.js";
|
|
|
7
7
|
import { writeVaultItemList } from "../output.js";
|
|
8
8
|
import { requireLinkedProject } from "../require-linked.js";
|
|
9
9
|
const DEFAULT_LIMIT = 5;
|
|
10
|
-
const USAGE = "Usage: grounder handoff list [--limit <n>] [--head]\n";
|
|
10
|
+
const USAGE = "Usage: grounder handoff list [--limit <n>] [--head] [--markdown]\n";
|
|
11
11
|
function usageError() {
|
|
12
12
|
process.stderr.write(USAGE);
|
|
13
13
|
return 1;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* CLI entry for `grounder handoff list [--limit <n>]`.
|
|
16
|
+
* CLI entry for `grounder handoff list [--limit <n>] [--head] [--markdown]`.
|
|
17
17
|
* `--limit` must be a positive integer when provided.
|
|
18
18
|
* @returns Exit code (`0` on success, `1` on usage or config errors).
|
|
19
19
|
*/
|
|
@@ -27,7 +27,7 @@ export async function runHandoffList(argv) {
|
|
|
27
27
|
return usageError();
|
|
28
28
|
}
|
|
29
29
|
for (const key of flags.keys()) {
|
|
30
|
-
if (key !== "limit" && key !== "head") {
|
|
30
|
+
if (key !== "limit" && key !== "head" && key !== "markdown") {
|
|
31
31
|
return usageError();
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -44,20 +44,29 @@ export async function runHandoffList(argv) {
|
|
|
44
44
|
}
|
|
45
45
|
limit = parsed;
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
const head = flagBool(flags, "head");
|
|
48
|
+
const markdown = flagBool(flags, "markdown");
|
|
49
|
+
if (head && markdown) {
|
|
50
|
+
process.stderr.write("Use only one of --head or --markdown.\n");
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
return runHandoffListWithOptions({ limit, head, markdown });
|
|
48
54
|
}
|
|
49
55
|
/**
|
|
50
|
-
* Resolves the linked project, lists recent handoffs under `logs/`
|
|
51
|
-
* Default: prints a count header (blank line after when
|
|
52
|
-
* handoff as a numbered two-line block — `N. ` +
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* empty
|
|
60
|
-
*
|
|
56
|
+
* Resolves the linked project, lists recent handoffs under `logs/` recursively
|
|
57
|
+
* (newest first). Default: prints a count header (blank line after when
|
|
58
|
+
* non-empty), then each handoff as a numbered two-line block — `N. ` +
|
|
59
|
+
* bucket-relative stem path (nested files include subfolders; timestamp
|
|
60
|
+
* prefixes included), then the indented absolute path — separated by a blank
|
|
61
|
+
* line. With `markdown: true`, the title line is `[bucketRelativePath](fileUri)`
|
|
62
|
+
* under `logs/` (`.md` kept; no `logs/` prefix). The title line ends with two
|
|
63
|
+
* trailing spaces (a Markdown hard line break) so agents can relay stdout into
|
|
64
|
+
* chat and keep title and path on separate rendered lines. When `logs/` is
|
|
65
|
+
* empty, prints `No handoffs.` only. The number is positional within this
|
|
66
|
+
* listing only (not a stable identifier). With `head: true`, prints only the
|
|
67
|
+
* single newest *usable* handoff path (or empty stdout) — see
|
|
68
|
+
* {@link findUsableHandoff}. Same vault/link prerequisites as
|
|
69
|
+
* `grounder handoff`.
|
|
61
70
|
* @returns Exit code (`0` on success, `1` when vault/link is missing).
|
|
62
71
|
*/
|
|
63
72
|
export async function runHandoffListWithOptions(options = {}) {
|
|
@@ -76,7 +85,10 @@ export async function runHandoffListWithOptions(options = {}) {
|
|
|
76
85
|
return 0;
|
|
77
86
|
}
|
|
78
87
|
const paths = await listHandoffs(logsDir, { limit });
|
|
79
|
-
writeVaultItemList(paths, limit, { singular: "handoff", plural: "handoffs" }
|
|
88
|
+
writeVaultItemList(paths, limit, { singular: "handoff", plural: "handoffs" }, {
|
|
89
|
+
markdown: options.markdown === true,
|
|
90
|
+
titleRootDir: logsDir,
|
|
91
|
+
});
|
|
80
92
|
return 0;
|
|
81
93
|
});
|
|
82
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/handoff/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,aAAa,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/handoff/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,7 +30,7 @@ export declare function runHandoffPeek(argv: string[]): Promise<number>;
|
|
|
30
30
|
* Resolves the linked project and prints a one-line teaser for the newest *usable*
|
|
31
31
|
* handoff, or nothing. "Usable" (via {@link findUsableHandoff}) skips empty/unreadable
|
|
32
32
|
* files and falls back to the next-newest — the same selection `grounder handoff list
|
|
33
|
-
* --head` uses, so the teaser and `/grounder-
|
|
33
|
+
* --head` uses, so the teaser and `/grounder-recall` never disagree about which handoff
|
|
34
34
|
* is current.
|
|
35
35
|
* Also checks `state.json` and may add a one-line "run grounder migrate" hint
|
|
36
36
|
* for people who never run doctor.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peek.d.ts","sourceRoot":"","sources":["../../../src/commands/handoff/peek.ts"],"names":[],"mappings":"AAYA,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAOD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWjE;
|
|
1
|
+
{"version":3,"file":"peek.d.ts","sourceRoot":"","sources":["../../../src/commands/handoff/peek.ts"],"names":[],"mappings":"AAYA,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAOD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWjE;AAgGD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAYpE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BjG"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { readCursorHookWorkspaceRoot } from "../../agents/cursor-hook-input.js";
|
|
3
|
-
import { ALL_AGENTS } from "../../agents/index.js";
|
|
4
3
|
import { withHomeDir } from "../../connector/home.js";
|
|
5
4
|
import { resolveLinkedProject } from "../../connector/linked.js";
|
|
6
|
-
import {
|
|
5
|
+
import { readGrounderState } from "../../connector/state.js";
|
|
7
6
|
import { resolveLogsDir } from "../../connector/vault.js";
|
|
8
7
|
import { helpExitCode } from "../../help.js";
|
|
9
8
|
import { parseHandoffFrontmatter } from "../../util/frontmatter.js";
|
|
10
9
|
import { flagBool, parseArgs } from "../../util/parse-args.js";
|
|
11
10
|
import { findUsableHandoff } from "../../vault/find-usable-handoff.js";
|
|
11
|
+
import { installDriftDetected } from "../install-drift.js";
|
|
12
12
|
const MIGRATE_TEASER = "[grounder] Install outdated — run: grounder migrate.";
|
|
13
13
|
/** `YYYY-MM-DD-HHmm` or `YYYY-MM-DD-HHmmss`, optionally followed by `-slug`. */
|
|
14
14
|
const TIMESTAMP_STEM = /^(\d{4}-\d{2}-\d{2})-\d{4}(?:\d{2})?(?:-(.*))?$/;
|
|
@@ -28,6 +28,20 @@ export function labelFromHandoffFilename(filePath) {
|
|
|
28
28
|
}
|
|
29
29
|
return slug.replace(/-/g, " ");
|
|
30
30
|
}
|
|
31
|
+
/** Max characters kept from a handoff title before truncating with an ellipsis. */
|
|
32
|
+
const MAX_LABEL_LENGTH = 80;
|
|
33
|
+
/**
|
|
34
|
+
* Collapse embedded newlines/control characters to single spaces and cap
|
|
35
|
+
* length, so a malformed or unusually long `title` frontmatter value can't
|
|
36
|
+
* blow out the single-line teaser this label renders on.
|
|
37
|
+
*/
|
|
38
|
+
function sanitizeLabel(label) {
|
|
39
|
+
const collapsed = label.replace(/\s+/g, " ").trim();
|
|
40
|
+
if (collapsed.length <= MAX_LABEL_LENGTH) {
|
|
41
|
+
return collapsed;
|
|
42
|
+
}
|
|
43
|
+
return `${collapsed.slice(0, MAX_LABEL_LENGTH - 1)}…`;
|
|
44
|
+
}
|
|
31
45
|
function createdDateFromFilename(filePath) {
|
|
32
46
|
const stem = path.basename(filePath, ".md");
|
|
33
47
|
const match = TIMESTAMP_STEM.exec(stem);
|
|
@@ -66,16 +80,19 @@ function resolveCursorHookCwd(stdinWorkspaceRoot) {
|
|
|
66
80
|
}
|
|
67
81
|
/**
|
|
68
82
|
* Whether to print the "run grounder migrate" line from session peek.
|
|
69
|
-
*
|
|
83
|
+
* Cheap by design: a package-local template render/hash per ledger-recorded
|
|
84
|
+
* agent (`installDriftDetected`) — no Cursor/Claude host-file I/O.
|
|
70
85
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
86
|
+
* Hook-content-only drift is not surfaced here (see
|
|
87
|
+
* `docs/architecture/state-reconciliation.md`) — that ships with a package
|
|
88
|
+
* version bump, which the upgrade banner already covers, and doctor catches
|
|
89
|
+
* it on the next full check. If state is missing or unreadable, stay quiet —
|
|
90
|
+
* doctor reports that.
|
|
74
91
|
*/
|
|
75
92
|
async function schemaMigrateNeeded(homeDir) {
|
|
76
93
|
try {
|
|
77
94
|
const state = await readGrounderState(homeDir);
|
|
78
|
-
return
|
|
95
|
+
return await installDriftDetected(state, homeDir);
|
|
79
96
|
}
|
|
80
97
|
catch {
|
|
81
98
|
return false;
|
|
@@ -119,7 +136,7 @@ export async function runHandoffPeek(argv) {
|
|
|
119
136
|
* Resolves the linked project and prints a one-line teaser for the newest *usable*
|
|
120
137
|
* handoff, or nothing. "Usable" (via {@link findUsableHandoff}) skips empty/unreadable
|
|
121
138
|
* files and falls back to the next-newest — the same selection `grounder handoff list
|
|
122
|
-
* --head` uses, so the teaser and `/grounder-
|
|
139
|
+
* --head` uses, so the teaser and `/grounder-recall` never disagree about which handoff
|
|
123
140
|
* is current.
|
|
124
141
|
* Also checks `state.json` and may add a one-line "run grounder migrate" hint
|
|
125
142
|
* for people who never run doctor.
|
|
@@ -137,11 +154,10 @@ export async function runHandoffPeekWithOptions(options = {}) {
|
|
|
137
154
|
const usable = await findUsableHandoff(logsDir);
|
|
138
155
|
if (usable) {
|
|
139
156
|
const fm = parseHandoffFrontmatter(usable.content);
|
|
140
|
-
const label = fm.title?.trim() || labelFromHandoffFilename(usable.path);
|
|
157
|
+
const label = sanitizeLabel(fm.title?.trim() || labelFromHandoffFilename(usable.path));
|
|
141
158
|
const createdDate = formatCreatedDate(fm.created, usable.path);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
159
|
+
const dateSuffix = createdDate ? ` (${createdDate})` : "";
|
|
160
|
+
handoffLine = `[grounder] Latest handoff: "${label}"${dateSuffix}. Run /grounder-recall to load it, or ignore if unrelated.`;
|
|
145
161
|
}
|
|
146
162
|
}
|
|
147
163
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peek.js","sourceRoot":"","sources":["../../../src/commands/handoff/peek.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"peek.js","sourceRoot":"","sources":["../../../src/commands/handoff/peek.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAe3D,MAAM,cAAc,GAAG,sDAAsD,CAAC;AAE9E,gFAAgF;AAChF,MAAM,cAAc,GAAG,iDAAiD,CAAC;AAEzE;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B;;;;GAIG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACpD,IAAI,SAAS,CAAC,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACzC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,GAAG,CAAC,CAAC,GAAG,CAAC;AACxD,CAAC;AAED,SAAS,uBAAuB,CAAC,QAAgB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,mEAAmE;AACnE,SAAS,iBAAiB,CAAC,OAA2B,EAAE,QAAgB;IACtE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,uBAAuB,CAAC,QAAQ,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,eAAe,CAAC,MAA0B,EAAE,IAAyB;IAC5E,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,IAAI,CACtF,CAAC;QACF,OAAO;IACT,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,kBAAsC;IAClE,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACvD,OAAO,OAAO,IAAI,SAAS,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,mBAAmB,CAAC,OAAgB;IACjD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,MAAM,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,WAA+B,EAC/B,aAAsB;IAEtB,IAAI,WAAW,IAAI,aAAa,EAAE,CAAC;QACjC,OAAO,GAAG,WAAW,KAAK,cAAc,EAAE,CAAC;IAC7C,CAAC;IACD,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACpD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,kBAAkB,GAAG,MAAM,2BAA2B,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5E,OAAO,yBAAyB,CAAC;QAC/B,GAAG,EAAE,oBAAoB,CAAC,kBAAkB,CAAC;QAC7C,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,UAA8B,EAAE;IAC9E,IAAI,CAAC;QACH,OAAO,MAAM,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;YACnD,IAAI,WAA+B,CAAC;YACpC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC1E,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAChB,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACzE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;oBAChD,IAAI,MAAM,EAAE,CAAC;wBACX,MAAM,EAAE,GAAG,uBAAuB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;wBACnD,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;wBACvF,MAAM,WAAW,GAAG,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;wBAC/D,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC1D,WAAW,GAAG,+BAA+B,KAAK,IAAI,UAAU,4DAA4D,CAAC;oBAC/H,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,WAAW,GAAG,SAAS,CAAC;YAC1B,CAAC;YAED,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjE,eAAe,CAAC,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACzE,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
|
|
@@ -6,6 +6,8 @@ export interface HandoffOptions {
|
|
|
6
6
|
text: string;
|
|
7
7
|
/** Optional filename + frontmatter title slug (`--title`). */
|
|
8
8
|
title?: string;
|
|
9
|
+
/** Topic keywords for search (`--topics "auth,jwt,middleware"`). */
|
|
10
|
+
topics?: string[];
|
|
9
11
|
/** Override home dir / `GROUNDER_HOME` (tests). */
|
|
10
12
|
homeDir?: string;
|
|
11
13
|
/** Fixed clock for deterministic filenames and `created` (tests). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AAQA,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AAQA,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BhE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBpF"}
|
package/dist/commands/handoff.js
CHANGED
|
@@ -17,12 +17,20 @@ export async function runHandoff(argv) {
|
|
|
17
17
|
const { positional, flags } = parseArgs(argv);
|
|
18
18
|
const text = positional.join(" ").trim();
|
|
19
19
|
if (!text) {
|
|
20
|
-
process.stderr.write("Usage: grounder handoff <text
|
|
20
|
+
process.stderr.write("Usage: grounder handoff <text> [--title <slug>] [--topics <list>]\n");
|
|
21
21
|
return 1;
|
|
22
22
|
}
|
|
23
|
+
const topicsRaw = flagString(flags, "topics");
|
|
24
|
+
const topics = topicsRaw
|
|
25
|
+
? topicsRaw
|
|
26
|
+
.split(",")
|
|
27
|
+
.map((t) => t.trim())
|
|
28
|
+
.filter(Boolean)
|
|
29
|
+
: undefined;
|
|
23
30
|
return runHandoffWithOptions({
|
|
24
31
|
text,
|
|
25
32
|
title: flagString(flags, "title"),
|
|
33
|
+
topics,
|
|
26
34
|
});
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
@@ -43,6 +51,7 @@ export async function runHandoffWithOptions(options) {
|
|
|
43
51
|
projectId: repo.projectId,
|
|
44
52
|
title: options.title,
|
|
45
53
|
branch,
|
|
54
|
+
topics: options.topics,
|
|
46
55
|
now: options.now,
|
|
47
56
|
});
|
|
48
57
|
process.stdout.write(`Wrote ${writtenPath}\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAkB3D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAc;IAC7C,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAEzC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAC5F,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,SAAS;QACtB,CAAC,CAAC,SAAS;aACN,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC;QACpB,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO,qBAAqB,CAAC;QAC3B,IAAI;QACJ,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC;QACjC,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAuB;IACjE,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACvC,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;YAC5D,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM;YACN,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,WAAW,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type GrounderState } from "../connector/state.js";
|
|
2
|
+
/**
|
|
3
|
+
* Cheap "would migrate change something" check for `peek`/`status`: no
|
|
4
|
+
* Cursor/Claude host-file I/O, just a package-local template render + hash
|
|
5
|
+
* per ledger-recorded agent, diffed against `state.json`'s `files` map, plus
|
|
6
|
+
* one ledger-only lookup for tombstoned legacy paths still on record.
|
|
7
|
+
* Scoped to agents already present in the ledger — a detected-but-never-set-up
|
|
8
|
+
* agent produces no drift here (see `desiredDrift`'s own scoping rule), so
|
|
9
|
+
* this never teases `migrate` forever with no command able to silence it.
|
|
10
|
+
*
|
|
11
|
+
* `ledgerFiles` is run through `ownedLedgerFiles()` first, same as
|
|
12
|
+
* `migrate`/`doctor`/`applyPlan()` — a stray key outside the adapter's
|
|
13
|
+
* `ownedPrefixes` (a hand-edited or corrupted `state.json` entry) is invisible
|
|
14
|
+
* to `reconcile()` and refused on apply, so counting it as drift here would
|
|
15
|
+
* nag `migrate` forever for a path `migrate` will never actually touch.
|
|
16
|
+
*
|
|
17
|
+
* A tombstoned path still present in the ledger's `files` map means `migrate`
|
|
18
|
+
* has something to retire (delete, forget, or a conflict needing `--force`) —
|
|
19
|
+
* checking that is a plain key lookup against data already in memory, not a
|
|
20
|
+
* disk read, so it stays as cheap as the hash diff above. Doctor's own
|
|
21
|
+
* `agent-*-legacy-commands` check is the one place that actually reads disk
|
|
22
|
+
* to tell delete/conflict/already-gone apart; this only answers "is migrate
|
|
23
|
+
* a no-op," which none of those three are.
|
|
24
|
+
*
|
|
25
|
+
* An owned ledger key that is neither desired nor tombstoned (a skill dropped
|
|
26
|
+
* from the current release with nobody remembering to tombstone the old path)
|
|
27
|
+
* is the same kind of drift: `reconcile()` never plans a non-desired ledger
|
|
28
|
+
* path as `noop`, so `migrate` always has something to do with it (forget it
|
|
29
|
+
* if already gone from disk, else delete/conflict). Same plain key-lookup
|
|
30
|
+
* cost as the tombstone check above — no disk read needed to know *that*
|
|
31
|
+
* there's drift, only to know which of forget/delete/conflict it'll be.
|
|
32
|
+
*/
|
|
33
|
+
export declare function installDriftDetected(state: GrounderState | null, homeDir?: string): Promise<boolean>;
|
|
34
|
+
//# sourceMappingURL=install-drift.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-drift.d.ts","sourceRoot":"","sources":["../../src/commands/install-drift.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,uBAAuB,CAAC;AAI/F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,aAAa,GAAG,IAAI,EAC3B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAmClB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ALL_AGENTS, ownedLedgerFiles } from "../agents/index.js";
|
|
2
|
+
import { ledgerFilesFor, recordedInvocation } from "../connector/state.js";
|
|
3
|
+
import { desiredDrift } from "../reconcile/core.js";
|
|
4
|
+
import { hashContent } from "../util/hash.js";
|
|
5
|
+
/**
|
|
6
|
+
* Cheap "would migrate change something" check for `peek`/`status`: no
|
|
7
|
+
* Cursor/Claude host-file I/O, just a package-local template render + hash
|
|
8
|
+
* per ledger-recorded agent, diffed against `state.json`'s `files` map, plus
|
|
9
|
+
* one ledger-only lookup for tombstoned legacy paths still on record.
|
|
10
|
+
* Scoped to agents already present in the ledger — a detected-but-never-set-up
|
|
11
|
+
* agent produces no drift here (see `desiredDrift`'s own scoping rule), so
|
|
12
|
+
* this never teases `migrate` forever with no command able to silence it.
|
|
13
|
+
*
|
|
14
|
+
* `ledgerFiles` is run through `ownedLedgerFiles()` first, same as
|
|
15
|
+
* `migrate`/`doctor`/`applyPlan()` — a stray key outside the adapter's
|
|
16
|
+
* `ownedPrefixes` (a hand-edited or corrupted `state.json` entry) is invisible
|
|
17
|
+
* to `reconcile()` and refused on apply, so counting it as drift here would
|
|
18
|
+
* nag `migrate` forever for a path `migrate` will never actually touch.
|
|
19
|
+
*
|
|
20
|
+
* A tombstoned path still present in the ledger's `files` map means `migrate`
|
|
21
|
+
* has something to retire (delete, forget, or a conflict needing `--force`) —
|
|
22
|
+
* checking that is a plain key lookup against data already in memory, not a
|
|
23
|
+
* disk read, so it stays as cheap as the hash diff above. Doctor's own
|
|
24
|
+
* `agent-*-legacy-commands` check is the one place that actually reads disk
|
|
25
|
+
* to tell delete/conflict/already-gone apart; this only answers "is migrate
|
|
26
|
+
* a no-op," which none of those three are.
|
|
27
|
+
*
|
|
28
|
+
* An owned ledger key that is neither desired nor tombstoned (a skill dropped
|
|
29
|
+
* from the current release with nobody remembering to tombstone the old path)
|
|
30
|
+
* is the same kind of drift: `reconcile()` never plans a non-desired ledger
|
|
31
|
+
* path as `noop`, so `migrate` always has something to do with it (forget it
|
|
32
|
+
* if already gone from disk, else delete/conflict). Same plain key-lookup
|
|
33
|
+
* cost as the tombstone check above — no disk read needed to know *that*
|
|
34
|
+
* there's drift, only to know which of forget/delete/conflict it'll be.
|
|
35
|
+
*/
|
|
36
|
+
export async function installDriftDetected(state, homeDir) {
|
|
37
|
+
if (!state) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
for (const agent of ALL_AGENTS) {
|
|
41
|
+
const ledgerFiles = ownedLedgerFiles(agent, ledgerFilesFor(state, agent.id), homeDir);
|
|
42
|
+
if (!ledgerFiles) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Replay the invocation baked in at this agent's last real install
|
|
46
|
+
// instead of this process's own `process.execPath` — otherwise a
|
|
47
|
+
// checking process with a different interpreter path (e.g. an editor
|
|
48
|
+
// extension host vs. a terminal) would manufacture drift that isn't
|
|
49
|
+
// real. See docs/architecture/runtime-invocation.md's "Repair loop".
|
|
50
|
+
// Falls back to the live invocation for a ledger predating this field.
|
|
51
|
+
const desired = await agent.desiredArtifacts(homeDir, {
|
|
52
|
+
invocation: recordedInvocation(state, agent.id),
|
|
53
|
+
});
|
|
54
|
+
const desiredHashes = {};
|
|
55
|
+
for (const [p, content] of Object.entries(desired)) {
|
|
56
|
+
desiredHashes[p] = hashContent(content);
|
|
57
|
+
}
|
|
58
|
+
if (desiredDrift(desiredHashes, ledgerFiles).length > 0) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
const tombstonePaths = new Set(agent.tombstones(homeDir));
|
|
62
|
+
if ([...tombstonePaths].some((p) => p in ledgerFiles)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
const desiredPaths = new Set(Object.keys(desiredHashes));
|
|
66
|
+
if (Object.keys(ledgerFiles).some((p) => !desiredPaths.has(p) && !tombstonePaths.has(p))) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=install-drift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-drift.js","sourceRoot":"","sources":["../../src/commands/install-drift.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAsB,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAA2B,EAC3B,OAAgB;IAEhB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QACtF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QACD,mEAAmE;QACnE,iEAAiE;QACjE,qEAAqE;QACrE,oEAAoE;QACpE,qEAAqE;QACrE,uEAAuE;QACvE,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE;YACpD,UAAU,EAAE,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,aAAa,GAA2B,EAAE,CAAC;QACjD,KAAK,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,YAAY,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,WAAW,CAAC,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACzD,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LinkOptions {
|
|
2
|
+
cwd?: string;
|
|
3
|
+
yes?: boolean;
|
|
4
|
+
force?: boolean;
|
|
5
|
+
dryRun?: boolean;
|
|
6
|
+
id?: string;
|
|
7
|
+
vault?: string;
|
|
8
|
+
homeDir?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function runLink(argv: string[]): Promise<number>;
|
|
11
|
+
export declare function runLinkWithOptions(options?: LinkOptions): Promise<number>;
|
|
12
|
+
//# sourceMappingURL=link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAc7D;AAED,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsFnF"}
|
|
@@ -1,37 +1,39 @@
|
|
|
1
1
|
import { mkdir } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { findGitRoot } from "
|
|
4
|
-
import { readHomeConfig, withHomeDir } from "
|
|
5
|
-
import { detectProjectId, formatProjectIdSource } from "
|
|
6
|
-
import { readRepoConfig, repoConfigPath, writeRepoConfig } from "
|
|
7
|
-
import { resolveLogsDir, resolveNotesDir, resolvePlansDir, resolveVaultRoot, } from "
|
|
8
|
-
import { helpExitCode } from "
|
|
9
|
-
import { flagBool, flagString, parseArgs } from "
|
|
10
|
-
import { resolveUserPath } from "
|
|
11
|
-
import { confirm } from "
|
|
12
|
-
export async function
|
|
13
|
-
const helpCode = helpExitCode(argv, "
|
|
3
|
+
import { findGitRoot } from "../connector/git.js";
|
|
4
|
+
import { readHomeConfig, withHomeDir } from "../connector/home.js";
|
|
5
|
+
import { detectProjectId, formatProjectIdSource } from "../connector/project-id.js";
|
|
6
|
+
import { readRepoConfig, repoConfigPath, writeRepoConfig } from "../connector/repo.js";
|
|
7
|
+
import { resolveLogsDir, resolveNotesDir, resolvePlansDir, resolveVaultRoot, } from "../connector/vault.js";
|
|
8
|
+
import { helpExitCode } from "../help.js";
|
|
9
|
+
import { flagBool, flagString, parseArgs } from "../util/parse-args.js";
|
|
10
|
+
import { resolveUserPath } from "../util/path.js";
|
|
11
|
+
import { confirm } from "../util/prompt.js";
|
|
12
|
+
export async function runLink(argv) {
|
|
13
|
+
const helpCode = helpExitCode(argv, "link");
|
|
14
14
|
if (helpCode !== null) {
|
|
15
15
|
return helpCode;
|
|
16
16
|
}
|
|
17
17
|
const { flags } = parseArgs(argv);
|
|
18
|
-
return
|
|
18
|
+
return runLinkWithOptions({
|
|
19
19
|
yes: flagBool(flags, "yes", "y"),
|
|
20
20
|
force: flagBool(flags, "force", "f"),
|
|
21
|
+
dryRun: flagBool(flags, "dry-run"),
|
|
21
22
|
id: flagString(flags, "id"),
|
|
22
23
|
vault: flagString(flags, "vault"),
|
|
23
24
|
});
|
|
24
25
|
}
|
|
25
|
-
export async function
|
|
26
|
+
export async function runLinkWithOptions(options = {}) {
|
|
26
27
|
return withHomeDir(options.homeDir, async () => {
|
|
27
28
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
28
29
|
const yes = options.yes ?? false;
|
|
29
30
|
const force = options.force ?? false;
|
|
31
|
+
const dryRun = options.dryRun ?? false;
|
|
30
32
|
const gitRoot = await findGitRoot(cwd);
|
|
31
33
|
let home = await readHomeConfig();
|
|
32
34
|
if (!home) {
|
|
33
35
|
if (!options.vault) {
|
|
34
|
-
process.stderr.write("No vault configured. Run: grounder
|
|
36
|
+
process.stderr.write("No vault configured. Run: grounder setup <path>\n");
|
|
35
37
|
return 1;
|
|
36
38
|
}
|
|
37
39
|
home = { vaultRoot: resolveUserPath(options.vault) };
|
|
@@ -52,11 +54,28 @@ export async function runRepoInitWithOptions(options = {}) {
|
|
|
52
54
|
const notesDirRelative = path.relative(vaultRoot, notesDir);
|
|
53
55
|
const logsDirRelative = path.relative(vaultRoot, logsDir);
|
|
54
56
|
const plansDirRelative = path.relative(vaultRoot, plansDir);
|
|
55
|
-
|
|
57
|
+
if (existingRepo && !force) {
|
|
58
|
+
if (existingRepo.projectId === detected.id) {
|
|
59
|
+
process.stdout.write(dryRun ? "Already linked (would skip).\n" : "✓ Already linked (skipped)\n");
|
|
60
|
+
if (!dryRun) {
|
|
61
|
+
await mkdir(notesDir, { recursive: true });
|
|
62
|
+
await mkdir(logsDir, { recursive: true });
|
|
63
|
+
await mkdir(plansDir, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
process.stderr.write(`Folder already linked as ${existingRepo.projectId}. Use --force to overwrite.\n`);
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
process.stdout.write("Link this project inside the markdown vault (once per project).\n");
|
|
71
|
+
process.stdout.write(dryRun ? "Would create:\n" : "Will create:\n");
|
|
56
72
|
process.stdout.write(` link ${repoConfigPath(cwd)}\n`);
|
|
57
73
|
process.stdout.write(` vault ${notesDirRelative}/\n`);
|
|
58
74
|
process.stdout.write(` vault ${logsDirRelative}/\n`);
|
|
59
75
|
process.stdout.write(` vault ${plansDirRelative}/\n`);
|
|
76
|
+
if (dryRun) {
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
60
79
|
if (!yes) {
|
|
61
80
|
const proceed = await confirm("Proceed?");
|
|
62
81
|
if (!proceed) {
|
|
@@ -64,17 +83,6 @@ export async function runRepoInitWithOptions(options = {}) {
|
|
|
64
83
|
return 0;
|
|
65
84
|
}
|
|
66
85
|
}
|
|
67
|
-
if (existingRepo && !force) {
|
|
68
|
-
if (existingRepo.projectId === detected.id) {
|
|
69
|
-
process.stdout.write("✓ Already linked (skipped)\n");
|
|
70
|
-
await mkdir(notesDir, { recursive: true });
|
|
71
|
-
await mkdir(logsDir, { recursive: true });
|
|
72
|
-
await mkdir(plansDir, { recursive: true });
|
|
73
|
-
return 0;
|
|
74
|
-
}
|
|
75
|
-
process.stderr.write(`Folder already linked as ${existingRepo.projectId}. Use --force to overwrite.\n`);
|
|
76
|
-
return 1;
|
|
77
|
-
}
|
|
78
86
|
await writeRepoConfig(cwd, { version: 1, projectId: detected.id });
|
|
79
87
|
await mkdir(notesDir, { recursive: true });
|
|
80
88
|
await mkdir(logsDir, { recursive: true });
|
|
@@ -86,4 +94,4 @@ export async function runRepoInitWithOptions(options = {}) {
|
|
|
86
94
|
return 0;
|
|
87
95
|
});
|
|
88
96
|
}
|
|
89
|
-
//# sourceMappingURL=
|
|
97
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { type AgentAdapter } from "../agents/index.js";
|
|
2
|
+
import { type GrounderState } from "../connector/state.js";
|
|
2
3
|
export interface MigrateOptions {
|
|
3
4
|
force?: boolean;
|
|
4
5
|
hooks?: boolean;
|
|
6
|
+
/** Turn hooks off (sticky — removes the fragment, flips hooksEnabled false). */
|
|
7
|
+
noHooks?: boolean;
|
|
5
8
|
dryRun?: boolean;
|
|
6
9
|
homeDir?: string;
|
|
7
10
|
/** Agent ids to migrate. Defaults to ledger keys, else auto-detect. */
|
|
@@ -14,10 +17,15 @@ export interface MigrateOptions {
|
|
|
14
17
|
* 3. Else auto-detect installed agents (legacy / pre-ledger)
|
|
15
18
|
*
|
|
16
19
|
* Ledger keys from a newer Grounder (agents this binary does not know) are
|
|
17
|
-
* skipped with a stderr warning — same forward-compat idea as
|
|
18
|
-
* but migrate can still refresh the agents it understands.
|
|
20
|
+
* skipped with a stderr warning — same forward-compat idea as the version
|
|
21
|
+
* hard stop, but migrate can still refresh the agents it understands.
|
|
22
|
+
*
|
|
23
|
+
* Takes the already-read `state` rather than reading it itself — the caller
|
|
24
|
+
* has already read it once (and needs it again for the too-new guard and the
|
|
25
|
+
* trailing state row), so this stays pure lookup logic instead of a second
|
|
26
|
+
* read of the same file.
|
|
19
27
|
*/
|
|
20
|
-
export declare function resolveMigrateAgents(explicitIds: string[] | undefined,
|
|
28
|
+
export declare function resolveMigrateAgents(explicitIds: string[] | undefined, state: GrounderState | null): Promise<AgentAdapter[]>;
|
|
21
29
|
export declare function runMigrate(argv: string[]): Promise<number>;
|
|
22
30
|
export declare function runMigrateWithOptions(options?: MigrateOptions): Promise<number>;
|
|
23
31
|
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAA6B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAA6B,MAAM,oBAAoB,CAAC;AAElF,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,uBAAuB,CAAC;AAe/B,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,EACjC,KAAK,EAAE,aAAa,GAAG,IAAI,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC,CAkBzB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBhE;AAED,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuFzF"}
|