grounder 0.5.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.
Files changed (144) hide show
  1. package/README.md +21 -20
  2. package/dist/agents/claude.d.ts +4 -4
  3. package/dist/agents/claude.d.ts.map +1 -1
  4. package/dist/agents/claude.js +158 -179
  5. package/dist/agents/claude.js.map +1 -1
  6. package/dist/agents/cursor.d.ts +3 -3
  7. package/dist/agents/cursor.d.ts.map +1 -1
  8. package/dist/agents/cursor.js +97 -144
  9. package/dist/agents/cursor.js.map +1 -1
  10. package/dist/agents/home-skills.d.ts +46 -0
  11. package/dist/agents/home-skills.d.ts.map +1 -0
  12. package/dist/agents/home-skills.js +83 -0
  13. package/dist/agents/home-skills.js.map +1 -0
  14. package/dist/agents/hook-fragment.d.ts +52 -0
  15. package/dist/agents/hook-fragment.d.ts.map +1 -0
  16. package/dist/agents/hook-fragment.js +76 -0
  17. package/dist/agents/hook-fragment.js.map +1 -0
  18. package/dist/agents/hook-install.d.ts +62 -0
  19. package/dist/agents/hook-install.d.ts.map +1 -0
  20. package/dist/agents/hook-install.js +74 -0
  21. package/dist/agents/hook-install.js.map +1 -0
  22. package/dist/agents/hook-runtime.d.ts +77 -10
  23. package/dist/agents/hook-runtime.d.ts.map +1 -1
  24. package/dist/agents/hook-runtime.js +274 -70
  25. package/dist/agents/hook-runtime.js.map +1 -1
  26. package/dist/agents/index.d.ts +8 -14
  27. package/dist/agents/index.d.ts.map +1 -1
  28. package/dist/agents/index.js +13 -19
  29. package/dist/agents/index.js.map +1 -1
  30. package/dist/agents/types.d.ts +56 -16
  31. package/dist/agents/types.d.ts.map +1 -1
  32. package/dist/cli.js +4 -0
  33. package/dist/cli.js.map +1 -1
  34. package/dist/commands/apply.d.ts +69 -0
  35. package/dist/commands/apply.d.ts.map +1 -0
  36. package/dist/commands/apply.js +238 -0
  37. package/dist/commands/apply.js.map +1 -0
  38. package/dist/commands/doctor.d.ts.map +1 -1
  39. package/dist/commands/doctor.js +190 -97
  40. package/dist/commands/doctor.js.map +1 -1
  41. package/dist/commands/handoff/peek.d.ts +1 -1
  42. package/dist/commands/handoff/peek.d.ts.map +1 -1
  43. package/dist/commands/handoff/peek.js +28 -12
  44. package/dist/commands/handoff/peek.js.map +1 -1
  45. package/dist/commands/install-drift.d.ts +34 -0
  46. package/dist/commands/install-drift.d.ts.map +1 -0
  47. package/dist/commands/install-drift.js +72 -0
  48. package/dist/commands/install-drift.js.map +1 -0
  49. package/dist/commands/migrate.d.ts +11 -3
  50. package/dist/commands/migrate.d.ts.map +1 -1
  51. package/dist/commands/migrate.js +67 -33
  52. package/dist/commands/migrate.js.map +1 -1
  53. package/dist/commands/overview.d.ts +33 -0
  54. package/dist/commands/overview.d.ts.map +1 -0
  55. package/dist/commands/overview.js +150 -0
  56. package/dist/commands/overview.js.map +1 -0
  57. package/dist/commands/render-artifact-table.d.ts +85 -0
  58. package/dist/commands/render-artifact-table.d.ts.map +1 -0
  59. package/dist/commands/render-artifact-table.js +232 -0
  60. package/dist/commands/render-artifact-table.js.map +1 -0
  61. package/dist/commands/search.d.ts.map +1 -1
  62. package/dist/commands/search.js +15 -4
  63. package/dist/commands/search.js.map +1 -1
  64. package/dist/commands/setup.d.ts.map +1 -1
  65. package/dist/commands/setup.js +86 -13
  66. package/dist/commands/setup.js.map +1 -1
  67. package/dist/commands/status.d.ts +7 -0
  68. package/dist/commands/status.d.ts.map +1 -1
  69. package/dist/commands/status.js +269 -88
  70. package/dist/commands/status.js.map +1 -1
  71. package/dist/connector/ledger-migrations.d.ts +55 -0
  72. package/dist/connector/ledger-migrations.d.ts.map +1 -0
  73. package/dist/connector/ledger-migrations.js +94 -0
  74. package/dist/connector/ledger-migrations.js.map +1 -0
  75. package/dist/connector/state.d.ts +96 -59
  76. package/dist/connector/state.d.ts.map +1 -1
  77. package/dist/connector/state.js +165 -107
  78. package/dist/connector/state.js.map +1 -1
  79. package/dist/help.d.ts +1 -1
  80. package/dist/help.d.ts.map +1 -1
  81. package/dist/help.js +27 -5
  82. package/dist/help.js.map +1 -1
  83. package/dist/reconcile/apply.d.ts +31 -0
  84. package/dist/reconcile/apply.d.ts.map +1 -0
  85. package/dist/reconcile/apply.js +97 -0
  86. package/dist/reconcile/apply.js.map +1 -0
  87. package/dist/reconcile/core.d.ts +82 -0
  88. package/dist/reconcile/core.d.ts.map +1 -0
  89. package/dist/reconcile/core.js +163 -0
  90. package/dist/reconcile/core.js.map +1 -0
  91. package/dist/reconcile/disk.d.ts +13 -0
  92. package/dist/reconcile/disk.d.ts.map +1 -0
  93. package/dist/reconcile/disk.js +28 -0
  94. package/dist/reconcile/disk.js.map +1 -0
  95. package/dist/util/fs.d.ts +14 -0
  96. package/dist/util/fs.d.ts.map +1 -1
  97. package/dist/util/fs.js +27 -1
  98. package/dist/util/fs.js.map +1 -1
  99. package/dist/util/merge-json.d.ts +13 -2
  100. package/dist/util/merge-json.d.ts.map +1 -1
  101. package/dist/util/merge-json.js +24 -10
  102. package/dist/util/merge-json.js.map +1 -1
  103. package/dist/vault/list-handoffs.d.ts +13 -3
  104. package/dist/vault/list-handoffs.d.ts.map +1 -1
  105. package/dist/vault/list-handoffs.js +28 -13
  106. package/dist/vault/list-handoffs.js.map +1 -1
  107. package/dist/vault/list-notes.d.ts +12 -3
  108. package/dist/vault/list-notes.d.ts.map +1 -1
  109. package/dist/vault/list-notes.js +13 -7
  110. package/dist/vault/list-notes.js.map +1 -1
  111. package/dist/vault/list-plans.d.ts +12 -3
  112. package/dist/vault/list-plans.d.ts.map +1 -1
  113. package/dist/vault/list-plans.js +13 -7
  114. package/dist/vault/list-plans.js.map +1 -1
  115. package/dist/vault/search.d.ts.map +1 -1
  116. package/dist/vault/search.js +128 -24
  117. package/dist/vault/search.js.map +1 -1
  118. package/package.json +2 -2
  119. package/templates/agents/claude/skills/grounder-handoff/SKILL.md +73 -0
  120. package/templates/agents/claude/{commands/grounder-note.md → skills/grounder-note/SKILL.md} +6 -0
  121. package/templates/agents/claude/skills/grounder-overview/SKILL.md +21 -0
  122. package/templates/agents/claude/{commands/grounder-plan.md → skills/grounder-plan/SKILL.md} +6 -0
  123. package/templates/agents/claude/skills/grounder-recall/SKILL.md +34 -0
  124. package/templates/agents/claude/{commands/grounder-search.md → skills/grounder-search/SKILL.md} +16 -8
  125. package/templates/agents/cursor/skills/grounder-handoff/SKILL.md +73 -0
  126. package/templates/agents/cursor/{commands/grounder-note.md → skills/grounder-note/SKILL.md} +6 -0
  127. package/templates/agents/cursor/skills/grounder-overview/SKILL.md +21 -0
  128. package/templates/agents/cursor/{commands/grounder-plan.md → skills/grounder-plan/SKILL.md} +6 -0
  129. package/templates/agents/cursor/skills/grounder-recall/SKILL.md +34 -0
  130. package/templates/agents/cursor/{commands/grounder-search.md → skills/grounder-search/SKILL.md} +16 -8
  131. package/templates/vault/plan.md +1 -1
  132. package/templates/vault/session-handoff.md +2 -1
  133. package/dist/agents/install-command.d.ts +0 -35
  134. package/dist/agents/install-command.d.ts.map +0 -1
  135. package/dist/agents/install-command.js +0 -65
  136. package/dist/agents/install-command.js.map +0 -1
  137. package/dist/commands/apply-agent-installs.d.ts +0 -34
  138. package/dist/commands/apply-agent-installs.d.ts.map +0 -1
  139. package/dist/commands/apply-agent-installs.js +0 -137
  140. package/dist/commands/apply-agent-installs.js.map +0 -1
  141. package/templates/agents/claude/commands/grounder-task-handoff.md +0 -58
  142. package/templates/agents/claude/commands/grounder-task.md +0 -22
  143. package/templates/agents/cursor/commands/grounder-task-handoff.md +0 -58
  144. package/templates/agents/cursor/commands/grounder-task.md +0 -22
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Generic pieces of the session-hook fragment reconciler shared by
3
+ * `cursor.ts` (flat `hooks.sessionStart` array) and `claude.ts` (nested
4
+ * `hooks.SessionStart` matcher groups, each with its own `hooks` array).
5
+ *
6
+ * Model: Ansible `blockinfile` / Kubernetes Server-Side Apply's sole-owner
7
+ * case — locate every entry a recognizer predicate matches (there may be
8
+ * more than one: a legacy `npx grounder handoff peek` entry alongside a
9
+ * runtime-form one, say), remove all of them, and always converge to exactly
10
+ * one canonical entry. No conflict / `--force` gate — Grounder solely owns
11
+ * this one nested entry, there is nothing a user could have "locally edited"
12
+ * the way a whole skill file can be.
13
+ */
14
+ /**
15
+ * The entries registered for one hook event (`hooks.<event>`) in an
16
+ * already-parsed config root, or `null` when the file has no such array —
17
+ * a non-object root, no `hooks` key, a `hooks` that isn't an object, or an
18
+ * event key that is absent or not an array.
19
+ *
20
+ * `null` rather than `[]` because the two callers want opposite things from
21
+ * "nothing there": counting existing entries treats it as empty, while
22
+ * "already converged?" must answer `false` and go on to converge.
23
+ */
24
+ export declare function readEventEntries(parsed: unknown, event: string): unknown[] | null;
25
+ /**
26
+ * Grounder's fragment lives at `hooks.<event>`, so a merge has to read `hooks`
27
+ * as a JSON object. A present-but-non-object `hooks` (an array, a string, a
28
+ * number) is refused rather than replaced: these are shared config files whose
29
+ * unrelated keys Grounder promises to preserve, and silently dropping a value
30
+ * it can't interpret is the one way a merge could destroy user data. Refusing
31
+ * matches how {@link mergeJsonFile} already backs off an unparseable root or a
32
+ * non-object top level — same contract, one level deeper.
33
+ *
34
+ * `null` and absent both mean "nothing there yet" and yield a fresh `{}` —
35
+ * neither carries content a user could lose.
36
+ *
37
+ * Returns a shallow copy, so callers can mutate the result without touching
38
+ * the parsed original (`mergeJsonFile` compares by reference to decide whether
39
+ * anything changed).
40
+ */
41
+ export declare function readHooksObject(current: Record<string, unknown>, filePath: string): Record<string, unknown>;
42
+ /** Remove every entry `isMatch` accepts, preserving order of the rest. */
43
+ export declare function removeMatchingEntries<T>(entries: readonly T[], isMatch: (entry: T) => boolean): T[];
44
+ /**
45
+ * True when `entries` already holds exactly one match and it is byte-for-byte
46
+ * the canonical entry (same keys, same order) — the only case a fragment
47
+ * reconciler should report as already-converged (no write needed). Two
48
+ * matches, zero matches, or a single match with drifted content all count as
49
+ * "not yet converged."
50
+ */
51
+ export declare function isAlreadyConverged<T>(entries: readonly T[], isMatch: (entry: T) => boolean, canonical: T): boolean;
52
+ //# sourceMappingURL=hook-fragment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-fragment.d.ts","sourceRoot":"","sources":["../../src/agents/hook-fragment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,GAAG,IAAI,CAUjF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAC7B,CAAC,EAAE,CAEL;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,EAC9B,SAAS,EAAE,CAAC,GACX,OAAO,CAGT"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Generic pieces of the session-hook fragment reconciler shared by
3
+ * `cursor.ts` (flat `hooks.sessionStart` array) and `claude.ts` (nested
4
+ * `hooks.SessionStart` matcher groups, each with its own `hooks` array).
5
+ *
6
+ * Model: Ansible `blockinfile` / Kubernetes Server-Side Apply's sole-owner
7
+ * case — locate every entry a recognizer predicate matches (there may be
8
+ * more than one: a legacy `npx grounder handoff peek` entry alongside a
9
+ * runtime-form one, say), remove all of them, and always converge to exactly
10
+ * one canonical entry. No conflict / `--force` gate — Grounder solely owns
11
+ * this one nested entry, there is nothing a user could have "locally edited"
12
+ * the way a whole skill file can be.
13
+ */
14
+ /**
15
+ * The entries registered for one hook event (`hooks.<event>`) in an
16
+ * already-parsed config root, or `null` when the file has no such array —
17
+ * a non-object root, no `hooks` key, a `hooks` that isn't an object, or an
18
+ * event key that is absent or not an array.
19
+ *
20
+ * `null` rather than `[]` because the two callers want opposite things from
21
+ * "nothing there": counting existing entries treats it as empty, while
22
+ * "already converged?" must answer `false` and go on to converge.
23
+ */
24
+ export function readEventEntries(parsed, event) {
25
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
26
+ return null;
27
+ }
28
+ const hooks = parsed.hooks;
29
+ if (!hooks || typeof hooks !== "object" || Array.isArray(hooks)) {
30
+ return null;
31
+ }
32
+ const entries = hooks[event];
33
+ return Array.isArray(entries) ? entries : null;
34
+ }
35
+ /**
36
+ * Grounder's fragment lives at `hooks.<event>`, so a merge has to read `hooks`
37
+ * as a JSON object. A present-but-non-object `hooks` (an array, a string, a
38
+ * number) is refused rather than replaced: these are shared config files whose
39
+ * unrelated keys Grounder promises to preserve, and silently dropping a value
40
+ * it can't interpret is the one way a merge could destroy user data. Refusing
41
+ * matches how {@link mergeJsonFile} already backs off an unparseable root or a
42
+ * non-object top level — same contract, one level deeper.
43
+ *
44
+ * `null` and absent both mean "nothing there yet" and yield a fresh `{}` —
45
+ * neither carries content a user could lose.
46
+ *
47
+ * Returns a shallow copy, so callers can mutate the result without touching
48
+ * the parsed original (`mergeJsonFile` compares by reference to decide whether
49
+ * anything changed).
50
+ */
51
+ export function readHooksObject(current, filePath) {
52
+ const hooks = current.hooks;
53
+ if (hooks === undefined || hooks === null) {
54
+ return {};
55
+ }
56
+ if (typeof hooks !== "object" || Array.isArray(hooks)) {
57
+ throw new Error(`Refusing to modify ${filePath}: "hooks" must be a JSON object`);
58
+ }
59
+ return { ...hooks };
60
+ }
61
+ /** Remove every entry `isMatch` accepts, preserving order of the rest. */
62
+ export function removeMatchingEntries(entries, isMatch) {
63
+ return entries.filter((entry) => !isMatch(entry));
64
+ }
65
+ /**
66
+ * True when `entries` already holds exactly one match and it is byte-for-byte
67
+ * the canonical entry (same keys, same order) — the only case a fragment
68
+ * reconciler should report as already-converged (no write needed). Two
69
+ * matches, zero matches, or a single match with drifted content all count as
70
+ * "not yet converged."
71
+ */
72
+ export function isAlreadyConverged(entries, isMatch, canonical) {
73
+ const matches = entries.filter(isMatch);
74
+ return matches.length === 1 && JSON.stringify(matches[0]) === JSON.stringify(canonical);
75
+ }
76
+ //# sourceMappingURL=hook-fragment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-fragment.js","sourceRoot":"","sources":["../../src/agents/hook-fragment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAe,EAAE,KAAa;IAC7D,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAI,MAAkC,CAAC,KAAK,CAAC;IACxD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAI,KAAiC,CAAC,KAAK,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAgC,EAChC,QAAgB;IAEhB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,iCAAiC,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,GAAI,KAAiC,EAAE,CAAC;AACnD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,qBAAqB,CACnC,OAAqB,EACrB,OAA8B;IAE9B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAqB,EACrB,OAA8B,EAC9B,SAAY;IAEZ,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The I/O scaffolding both hook adapters run around their own merge functions:
3
+ * read, converge, write, and report which of created/overwritten/skipped
4
+ * happened. Kept out of `hook-fragment.ts` so that module stays pure — the
5
+ * same split `reconcile/` draws between `core.ts` and `apply.ts`.
6
+ *
7
+ * What stays adapter-specific is the fragment shape itself: the recognizer
8
+ * predicate, where a canonical entry belongs, and what "already converged"
9
+ * means (Cursor: exactly one match in a flat array; Claude Code: exactly one
10
+ * match, under the canonical matcher group). Those arrive here as callbacks.
11
+ */
12
+ import type { AgentInstallOptions, AgentInstallResult } from "./types.js";
13
+ export interface HookFragmentInstall {
14
+ /** The shared JSON config this fragment lives in. */
15
+ dest: string;
16
+ /**
17
+ * Skip the write entirely — exactly one canonical entry is already present
18
+ * *and* the shared runtime is current. Anything else converges.
19
+ */
20
+ isUpToDate(filePath: string): Promise<boolean>;
21
+ /**
22
+ * Does the file already list any Grounder entry (in any form, including a
23
+ * legacy `npx` one)? Decides whether a write reports `overwritten` rather
24
+ * than `created`. Only consulted when the file exists.
25
+ */
26
+ hasGrounderEntry(filePath: string): Promise<boolean>;
27
+ /**
28
+ * Converge the fragment into a parsed config root, returning the new root.
29
+ * `fileExisted` is passed through for the one thing that depends on it
30
+ * (Cursor stamps `version: 1` only onto a file it is creating).
31
+ */
32
+ merge(current: Record<string, unknown>, fileExisted: boolean): Record<string, unknown>;
33
+ }
34
+ /**
35
+ * Install (or converge) a hook fragment, also materializing `~/.grounder/runtime`
36
+ * on a real run if it's stale. Always converges the fragment itself — no
37
+ * `--force` gate; `force` only affects whole-file skill artifacts, never a
38
+ * shared-JSON fragment.
39
+ *
40
+ * The runtime materialization is gated on {@link isHookRuntimeStale}, not
41
+ * unconditional: an invocation running through the materialized runtime's
42
+ * own `dist/cli.js` (e.g. `{{GROUNDER_CLI}}` in a skill) has
43
+ * `defaultPackageRoot` resolve to the runtime itself, which
44
+ * {@link installHookRuntime} refuses to materialize from (see its doc
45
+ * comment) — skipping the call here when the runtime is already current
46
+ * avoids that throw.
47
+ *
48
+ * Never clobbers: an unparseable config backs off inside {@link mergeJsonFile},
49
+ * and a `merge` that refuses (see `readHooksObject`) throws before any write.
50
+ */
51
+ export declare function installHookFragment(install: HookFragmentInstall, opts: AgentInstallOptions): Promise<AgentInstallResult>;
52
+ /**
53
+ * Remove a hook fragment entirely (`--no-hooks`). Reports an artifact only
54
+ * when something actually changed, so an agent that never had the entry
55
+ * contributes no row to the install table.
56
+ *
57
+ * `remove` is expected to return its argument by reference when there is
58
+ * nothing to remove — that is what stops {@link mergeJsonFile} from
59
+ * reformatting an unrelated config file on its way to a no-op.
60
+ */
61
+ export declare function removeHookFragment(dest: string, remove: (current: Record<string, unknown>) => Record<string, unknown>, opts: AgentInstallOptions): Promise<AgentInstallResult>;
62
+ //# sourceMappingURL=hook-install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-install.d.ts","sourceRoot":"","sources":["../../src/agents/hook-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAkB,MAAM,YAAY,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CA2B7B;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrE,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAS7B"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The I/O scaffolding both hook adapters run around their own merge functions:
3
+ * read, converge, write, and report which of created/overwritten/skipped
4
+ * happened. Kept out of `hook-fragment.ts` so that module stays pure — the
5
+ * same split `reconcile/` draws between `core.ts` and `apply.ts`.
6
+ *
7
+ * What stays adapter-specific is the fragment shape itself: the recognizer
8
+ * predicate, where a canonical entry belongs, and what "already converged"
9
+ * means (Cursor: exactly one match in a flat array; Claude Code: exactly one
10
+ * match, under the canonical matcher group). Those arrive here as callbacks.
11
+ */
12
+ import { fileExists } from "../util/fs.js";
13
+ import { mergeJsonFile } from "../util/merge-json.js";
14
+ import { installHookRuntime, isHookRuntimeStale } from "./hook-runtime.js";
15
+ /**
16
+ * Install (or converge) a hook fragment, also materializing `~/.grounder/runtime`
17
+ * on a real run if it's stale. Always converges the fragment itself — no
18
+ * `--force` gate; `force` only affects whole-file skill artifacts, never a
19
+ * shared-JSON fragment.
20
+ *
21
+ * The runtime materialization is gated on {@link isHookRuntimeStale}, not
22
+ * unconditional: an invocation running through the materialized runtime's
23
+ * own `dist/cli.js` (e.g. `{{GROUNDER_CLI}}` in a skill) has
24
+ * `defaultPackageRoot` resolve to the runtime itself, which
25
+ * {@link installHookRuntime} refuses to materialize from (see its doc
26
+ * comment) — skipping the call here when the runtime is already current
27
+ * avoids that throw.
28
+ *
29
+ * Never clobbers: an unparseable config backs off inside {@link mergeJsonFile},
30
+ * and a `merge` that refuses (see `readHooksObject`) throws before any write.
31
+ */
32
+ export async function installHookFragment(install, opts) {
33
+ const dest = install.dest;
34
+ if (await install.isUpToDate(dest)) {
35
+ return { artifacts: { [dest]: "skipped" } };
36
+ }
37
+ if (!opts.dryRun && (await isHookRuntimeStale(opts.homeDir))) {
38
+ await installHookRuntime({ homeDir: opts.homeDir });
39
+ }
40
+ const fileExisted = await fileExists(dest);
41
+ const hadGrounderEntry = fileExisted && (await install.hasGrounderEntry(dest));
42
+ const result = await mergeJsonFile(dest, (current) => install.merge(current, fileExisted), {
43
+ dryRun: opts.dryRun,
44
+ });
45
+ if (!result.ok) {
46
+ throw new Error(result.message);
47
+ }
48
+ const status = !result.changed
49
+ ? "skipped"
50
+ : hadGrounderEntry
51
+ ? "overwritten"
52
+ : "created";
53
+ return { artifacts: { [dest]: status } };
54
+ }
55
+ /**
56
+ * Remove a hook fragment entirely (`--no-hooks`). Reports an artifact only
57
+ * when something actually changed, so an agent that never had the entry
58
+ * contributes no row to the install table.
59
+ *
60
+ * `remove` is expected to return its argument by reference when there is
61
+ * nothing to remove — that is what stops {@link mergeJsonFile} from
62
+ * reformatting an unrelated config file on its way to a no-op.
63
+ */
64
+ export async function removeHookFragment(dest, remove, opts) {
65
+ if (!(await fileExists(dest))) {
66
+ return { artifacts: {} };
67
+ }
68
+ const result = await mergeJsonFile(dest, remove, { dryRun: opts.dryRun });
69
+ if (!result.ok) {
70
+ throw new Error(result.message);
71
+ }
72
+ return result.changed ? { artifacts: { [dest]: "overwritten" } } : { artifacts: {} };
73
+ }
74
+ //# sourceMappingURL=hook-install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-install.js","sourceRoot":"","sources":["../../src/agents/hook-install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAyB3E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAA4B,EAC5B,IAAyB;IAEzB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1B,IAAI,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,gBAAgB,GAAG,WAAW,IAAI,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE;QACzF,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,MAAM,GAAmB,CAAC,MAAM,CAAC,OAAO;QAC5C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,gBAAgB;YAChB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,MAAqE,EACrE,IAAyB;IAEzB,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAC3B,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1E,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;AACvF,CAAC"}
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Home-local runtime shared by session hooks *and* slash commands (originally
2
+ * Home-local runtime shared by session hooks *and* skills (originally
3
3
  * "Issue 2 — replace `npx grounder` in session hooks"; later extended to cover
4
- * slash-command templates too, since they had the identical problem).
4
+ * skill templates too, since they had the identical problem).
5
5
  *
6
6
  * ## Why
7
7
  * Both surfaces used to shell out via `npx grounder …`. `npx <pkg>` (no
8
8
  * version specifier) matches against whatever `grounder` version exists in
9
9
  * the *current project's own dependencies*; only when the project doesn't
10
10
  * declare `grounder` as a dependency does it fall back to fetching
11
- * `grounder@latest` from the registry. Session hooks and slash commands both
11
+ * `grounder@latest` from the registry. Session hooks and skills both
12
12
  * run from arbitrary linked projects, which normally have no reason to depend
13
13
  * on `grounder` themselves, so contributors (and anyone ahead of the last
14
14
  * publish, or deliberately pinned to an older version) get the wrong binary.
@@ -18,7 +18,7 @@
18
18
  * ## Design
19
19
  * On `setup`, materialize this package's `dist/` at
20
20
  * `~/.grounder/runtime/dist/` and point both host hook configs *and* the
21
- * commands copied into `~/.cursor/commands/` / `~/.claude/commands/` at:
21
+ * skills copied into `~/.cursor/skills/` / `~/.claude/skills/` at:
22
22
  * `process.execPath` + `~/.grounder/runtime/dist/cli.js` + `<subcommand> …`
23
23
  * No global install and no registry fetch at invocation time, for either
24
24
  * surface. This mirrors how Corepack (packageManager shims) and Husky/lint-staged
@@ -32,7 +32,9 @@
32
32
  * pick up new code immediately — no re-run of `setup` ever needed.
33
33
  * - **Ephemeral source** (bare `npx grounder …`, no install — each invocation
34
34
  * resolves to an immutable, version-keyed npx cache dir that can be evicted
35
- * or swapped out from under a symlink) → **copy** `dist/`. Re-run
35
+ * or swapped out from under a symlink) → **copy** `dist/`, plus
36
+ * `package.json` and `templates/` alongside it (see {@link installHookRuntime}'s
37
+ * doc comment for why those siblings are needed). Re-run
36
38
  * `grounder setup <vault>` after upgrading to refresh; this is an
37
39
  * inherent limitation of using npx with no install for something that must
38
40
  * persist, not something we can engineer around.
@@ -84,14 +86,14 @@ export declare function shellQuote(value: string): string;
84
86
  */
85
87
  export declare function extractRuntimeNodePath(command: unknown): string | null;
86
88
  /**
87
- * Find every baked Node interpreter path embedded in free-form text (slash-command
89
+ * Find every baked Node interpreter path embedded in free-form text (skill
88
90
  * markdown, etc.). Scans for the same `'<abs node>' '<abs …/cli.js>'` shape as
89
91
  * {@link extractRuntimeNodePath}, including mid-line / backtick-wrapped uses.
90
92
  */
91
93
  export declare function findRuntimeNodePathsInText(text: string): string[];
92
94
  /**
93
95
  * Quoted `<node> <runtime cli.js>` prefix, shared by every home-runtime
94
- * invocation (session hooks and slash-command templates alike). Append
96
+ * invocation (session hooks and skill templates alike). Append
95
97
  * subcommand args to build a full command string.
96
98
  */
97
99
  export declare function runtimeInvocation(homeDir?: string): string;
@@ -119,24 +121,89 @@ export declare function hookFileHasGrounderEntry(filePath: string): Promise<bool
119
121
  /**
120
122
  * True when the materialized runtime is missing or out of date for the given
121
123
  * source package:
124
+ * - **Self-referential** (`packageRoot` is `~/.grounder/runtime` itself —
125
+ * see {@link isSelfReferential}): never stale. There is no real source to
126
+ * compare against from inside this invocation, so the only sound answer is
127
+ * "leave it alone."
122
128
  * - **Symlink mode** (durable source): stale iff `dist/` isn't currently a
123
129
  * symlink resolving to this source's `dist/` (cheap `realpath` compare — no
124
130
  * staleness window, since a matching symlink is *always* current).
125
131
  * - **Copy mode** (ephemeral `npx` source): stale iff the manifest is
126
- * missing/unreadable or its recorded version differs from this source's.
132
+ * missing/unreadable, its recorded version differs from this source's, or
133
+ * `package.json` / `templates/` (when the source has one) are missing
134
+ * alongside `dist/` — a same-version repair case a version-only check
135
+ * would otherwise skip forever (e.g. a runtime materialized before these
136
+ * siblings were added, or one left mid-way by a partial install).
127
137
  *
128
138
  * @param packageRoot - Source package root to compare against (defaults to the
129
139
  * currently running package — override only in tests)
130
140
  */
131
141
  export declare function isHookRuntimeStale(homeDir?: string, packageRoot?: string): Promise<boolean>;
142
+ /**
143
+ * Materialization mode this source would use — symlink (durable) or copy
144
+ * (ephemeral `npx` cache) — without writing anything (read-only `realpath`
145
+ * checks only). Lets callers label a skipped/dry-run install the same way
146
+ * {@link installHookRuntime} would.
147
+ */
148
+ export declare function runtimeMode(packageRoot?: string): Promise<"symlink" | "copy">;
149
+ /**
150
+ * Materialize every artifact via `populate(stagingPath)` first — a
151
+ * populate/symlink/cp failure on any one of them leaves every `dest`
152
+ * untouched, since none have been promoted yet. Only once all of them are
153
+ * staged does promotion (backup-aside + rename-in) run for each in turn.
154
+ *
155
+ * If a promote fails partway through, every artifact already promoted in
156
+ * this call is rolled back (its backup renamed back over `dest`) before
157
+ * rethrowing — so a failure on, say, `package.json` after `dist/` has
158
+ * already promoted doesn't leave a new `dist/` sitting next to an old
159
+ * `package.json`. This isn't a true single filesystem transaction (POSIX
160
+ * has no atomic rename across independent paths), but it narrows the
161
+ * mixed-state window down to the renames themselves rather than leaving one
162
+ * as a visible end state after this function returns (successfully or not).
163
+ *
164
+ * A restore rename (`backup` back over `dest`) can itself fail — e.g. the
165
+ * same fault that broke the promote also blocks the rename back. When that
166
+ * happens `dest` is left in whatever state the failed renames put it in, but
167
+ * `backup` is deliberately *not* deleted by the cleanup below: it's the only
168
+ * remaining copy of what was there before this call, so a double failure
169
+ * degrades to "manual recovery from `<dest>.bak`" rather than silent data
170
+ * loss.
171
+ *
172
+ * `populate` decides how each artifact's staging gets filled (symlink vs.
173
+ * plain copy) — everything else (staging, backup, promote, rollback,
174
+ * cleanup) is identical for every artifact {@link installHookRuntime}
175
+ * materializes (`dist/`, and in copy mode, `package.json` / `templates/`).
176
+ */
177
+ export declare function installArtifacts(artifacts: Array<{
178
+ dest: string;
179
+ populate: (staging: string) => Promise<void>;
180
+ }>): Promise<void>;
132
181
  /**
133
182
  * Materialize this package's `dist/` at `~/.grounder/runtime/dist/` — symlinked
134
183
  * when the source is durable, copied when it's an ephemeral `npx` cache — and
135
184
  * write a manifest recording how.
136
185
  *
186
+ * Copy mode also copies `package.json` and `templates/` alongside `dist/`:
187
+ * `src/index.ts` reads `VERSION` from `<pkgRoot>/package.json` eagerly at
188
+ * import (every invocation), and `home-skills.ts` reads `<pkgRoot>/templates`
189
+ * on demand (`desiredArtifacts()` — real installs, and the drift check
190
+ * `status`/`doctor`/`peek` run). Neither exists under a copied `dist/`'s
191
+ * parent otherwise, so the materialized runtime crashed at import for every
192
+ * copy-mode (bare `npx grounder setup`) user. Symlink mode needs neither —
193
+ * Node resolves `import.meta.url` through `dist/`'s own symlink back to the
194
+ * real package root, package.json and templates included — and actively
195
+ * removes them if a previous copy-mode install left them behind, so
196
+ * `~/.grounder/runtime` never ends up with stale copy-mode siblings next to
197
+ * a symlinked `dist/`.
198
+ *
137
199
  * Callers should gate on {@link isHookRuntimeStale} (or `force`) before calling —
138
- * this always replaces whatever is currently at the destination, staging the
139
- * new materialization first so a failed symlink/cp leaves the live runtime intact.
200
+ * this always replaces whatever is currently at the destination. All
201
+ * artifacts (`dist/`, and in copy mode, `package.json` / `templates/`) are
202
+ * staged and promoted together via {@link installArtifacts}, which rolls
203
+ * back any artifact already promoted if a later one fails to promote.
204
+ * Refuses outright (see {@link isSelfReferential}) rather than attempting a
205
+ * self-symlink that would corrupt the runtime with an `ELOOP`-inducing link
206
+ * to itself.
140
207
  *
141
208
  * @param options.packageRoot - Source package root to materialize (defaults to
142
209
  * the currently running package — override only in tests)
@@ -1 +1 @@
1
- {"version":3,"file":"hook-runtime.d.ts","sourceRoot":"","sources":["../../src/agents/hook-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AAkBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD,wFAAwF;AACxF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,6FAA6F;AAC7F,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAgCD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAyBtE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAcjE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAE3F;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAanE;AAED,mFAAmF;AACnF,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAqBxE;AAED,mFAAmF;AACnF,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEvE;AAED,qGAAqG;AACrG,wBAAsB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAUtF;AAED,gFAAgF;AAChF,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjF;AA2DD;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,GAAE,MAA2B,GACvC,OAAO,CAAC,OAAO,CAAC,CAkBlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;CAAE,CAAC,CAkEjF"}
1
+ {"version":3,"file":"hook-runtime.d.ts","sourceRoot":"","sources":["../../src/agents/hook-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAkBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD,wFAAwF;AACxF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,6FAA6F;AAC7F,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AA+DD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKtE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAcjE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAE3F;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAanE;AAED,mFAAmF;AACnF,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAqBxE;AAED,mFAAmF;AACnF,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEvE;AAED,qGAAqG;AACrG,wBAAsB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAUtF;AAED,gFAAgF;AAChF,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjF;AAuGD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,GAAE,MAA2B,GACvC,OAAO,CAAC,OAAO,CAAC,CAmClB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,WAAW,GAAE,MAA2B,GACvC,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,CAE7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,GAC/E,OAAO,CAAC,IAAI,CAAC,CAqEf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;CAAE,CAAC,CA0EjF"}