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,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"}
@@ -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 schema hard-stops,
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, homeDir?: string): Promise<AgentAdapter[]>;
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;AAQlF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,EACjC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,EAAE,CAAC,CAmBzB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAchE;AAED,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8DzF"}
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"}
@@ -1,10 +1,12 @@
1
1
  import { ALL_AGENTS, resolveAgents } from "../agents/index.js";
2
2
  import { readHomeConfig, withHomeDir } from "../connector/home.js";
3
- import { assertAgentSchemasSupported, readGrounderState, statePath } from "../connector/state.js";
3
+ import { ledgerVersionChanged, readGrounderState, statePath, } from "../connector/state.js";
4
4
  import { isUnsupportedSchemaError } from "../connector/unsupported-schema.js";
5
5
  import { helpExitCode } from "../help.js";
6
+ import { VERSION } from "../index.js";
6
7
  import { flagBool, flagStrings, parseArgs } from "../util/parse-args.js";
7
- import { applyAgentInstalls } from "./apply-agent-installs.js";
8
+ import { applyAgentInstalls } from "./apply.js";
9
+ import { renderAgentErrors, renderModifiedNote, renderSummary, renderTable, rowsFromApplyResult, stateRow, } from "./render-artifact-table.js";
8
10
  /**
9
11
  * Resolve which agents to migrate:
10
12
  * 1. Explicit `--agent` ids (unknown ids still throw)
@@ -12,14 +14,18 @@ import { applyAgentInstalls } from "./apply-agent-installs.js";
12
14
  * 3. Else auto-detect installed agents (legacy / pre-ledger)
13
15
  *
14
16
  * Ledger keys from a newer Grounder (agents this binary does not know) are
15
- * skipped with a stderr warning — same forward-compat idea as schema hard-stops,
16
- * but migrate can still refresh the agents it understands.
17
+ * skipped with a stderr warning — same forward-compat idea as the version
18
+ * hard stop, but migrate can still refresh the agents it understands.
19
+ *
20
+ * Takes the already-read `state` rather than reading it itself — the caller
21
+ * has already read it once (and needs it again for the too-new guard and the
22
+ * trailing state row), so this stays pure lookup logic instead of a second
23
+ * read of the same file.
17
24
  */
18
- export async function resolveMigrateAgents(explicitIds, homeDir) {
25
+ export async function resolveMigrateAgents(explicitIds, state) {
19
26
  if (explicitIds && explicitIds.length > 0) {
20
27
  return resolveAgents(explicitIds);
21
28
  }
22
- const state = await readGrounderState(homeDir);
23
29
  const recordedIds = state ? Object.keys(state.agents) : [];
24
30
  if (recordedIds.length === 0) {
25
31
  return resolveAgents();
@@ -38,9 +44,16 @@ export async function runMigrate(argv) {
38
44
  }
39
45
  const { flags, repeated } = parseArgs(argv);
40
46
  const agents = flagStrings(repeated, "agent");
47
+ const hooks = flagBool(flags, "hooks");
48
+ const noHooks = flagBool(flags, "no-hooks");
49
+ if (hooks && noHooks) {
50
+ process.stderr.write("Cannot pass both --hooks and --no-hooks.\n");
51
+ return 1;
52
+ }
41
53
  return runMigrateWithOptions({
42
54
  force: flagBool(flags, "force", "f"),
43
- hooks: flagBool(flags, "hooks"),
55
+ hooks,
56
+ noHooks,
44
57
  dryRun: flagBool(flags, "dry-run"),
45
58
  agents: agents.length > 0 ? agents : undefined,
46
59
  });
@@ -50,16 +63,21 @@ export async function runMigrateWithOptions(options = {}) {
50
63
  const homeDir = options.homeDir;
51
64
  const force = options.force ?? false;
52
65
  const hooks = options.hooks ?? false;
66
+ const noHooks = options.noHooks ?? false;
53
67
  const dryRun = options.dryRun ?? false;
54
68
  const home = await readHomeConfig();
55
69
  if (!home) {
56
70
  process.stderr.write("No home config found. Run `grounder setup <path>` first.\n");
57
71
  return 1;
58
72
  }
59
- const agents = await resolveMigrateAgents(options.agents, homeDir);
73
+ // Read once, up front, inside this guard — `resolveMigrateAgents` used to
74
+ // trigger a second, unguarded read (migrate.ts:46 pre-refactor) that a
75
+ // too-new ledger threw through before this catch was ever reached.
76
+ let state;
77
+ let agents;
60
78
  try {
61
- const state = await readGrounderState(homeDir);
62
- assertAgentSchemasSupported(state, agents);
79
+ state = await readGrounderState(homeDir);
80
+ agents = await resolveMigrateAgents(options.agents, state);
63
81
  }
64
82
  catch (error) {
65
83
  if (isUnsupportedSchemaError(error)) {
@@ -69,34 +87,50 @@ export async function runMigrateWithOptions(options = {}) {
69
87
  throw error;
70
88
  }
71
89
  process.stdout.write(`Vault root: ${home.vaultRoot}\n`);
72
- process.stdout.write("Refresh Grounder after an upgrade (slash commands/hooks; vault path unchanged).\n");
73
- process.stdout.write(dryRun ? "Would refresh:\n" : "Will refresh:\n");
90
+ process.stdout.write("Refresh Grounder after an upgrade (skills/hooks; vault path unchanged).\n");
74
91
  if (agents.length === 0) {
75
- process.stdout.write(" (no agents recorded or detected)\n");
92
+ process.stdout.write("No agents recorded or detected — nothing to migrate.\n" +
93
+ "Run `grounder setup` first, or pass --agent to target one explicitly.\n");
94
+ return 0;
76
95
  }
77
- else {
78
- for (const agent of agents) {
79
- for (const artifactPath of agent.expectedArtifacts(homeDir)) {
80
- process.stdout.write(` ${agent.id.padEnd(8)} ${artifactPath}\n`);
81
- }
82
- }
83
- process.stdout.write(" hooks previously installed or --hooks (owned JSON always refreshed)\n");
84
- process.stdout.write(` state ${statePath(homeDir)}\n`);
96
+ if (dryRun) {
97
+ process.stdout.write("Dry run no files will be written.\n");
85
98
  }
86
99
  process.stdout.write("\n");
87
- if (agents.length === 0) {
88
- process.stdout.write("Nothing to migrate.\n");
89
- return 0;
100
+ let applyResult;
101
+ try {
102
+ applyResult = await applyAgentInstalls({
103
+ agents,
104
+ force,
105
+ hooks,
106
+ noHooks,
107
+ refreshInstalledHooks: true,
108
+ dryRun,
109
+ homeDir,
110
+ grounderVersion: VERSION,
111
+ });
90
112
  }
91
- await applyAgentInstalls({
92
- agents,
93
- force,
94
- hooks,
95
- refreshInstalledHooks: true,
96
- dryRun,
97
- homeDir,
98
- });
99
- return 0;
113
+ catch (error) {
114
+ if (isUnsupportedSchemaError(error)) {
115
+ process.stderr.write(`${error.message}\n`);
116
+ return 1;
117
+ }
118
+ throw error;
119
+ }
120
+ const rows = rowsFromApplyResult(applyResult);
121
+ // Computed once, by the same code, whether or not this is `--dry-run` —
122
+ // `applyAgentInstalls` decides "would this write change the ledger" from
123
+ // the reconciled plan itself, and only actually writes when it's real. So
124
+ // there's no separate prediction to keep in sync here: real and dry-run
125
+ // report the exact same thing for the exact same reason.
126
+ const ledgerChanged = applyResult.agents.some((a) => a.ledgerChanged) || ledgerVersionChanged(state, VERSION);
127
+ rows.push(stateRow(ledgerChanged, state, statePath(homeDir)));
128
+ renderTable(rows);
129
+ process.stdout.write("\n");
130
+ renderSummary(rows, dryRun);
131
+ renderModifiedNote(rows, "grounder migrate");
132
+ renderAgentErrors(applyResult);
133
+ return applyResult.agents.some((a) => a.error !== undefined) ? 1 : 0;
100
134
  });
101
135
  }
102
136
  //# sourceMappingURL=migrate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /** Options for {@link runOverviewWithOptions} (CLI parsing and tests). */
2
+ export interface OverviewOptions {
3
+ /** Directory used to find the linked repo (default: `process.cwd()`). */
4
+ cwd?: string;
5
+ /** Max recent titles to print per bucket (default: 3). */
6
+ limit?: number;
7
+ /**
8
+ * Agent relay: `[bucketRelativePath](fileUri)` on each title line (default:
9
+ * plain bucket-relative stem path).
10
+ */
11
+ markdown?: boolean;
12
+ /** Structured JSON payload instead of formatted text. Mutually exclusive with `markdown`. */
13
+ json?: boolean;
14
+ /** Override home dir / `GROUNDER_HOME` (tests). */
15
+ homeDir?: string;
16
+ }
17
+ /**
18
+ * CLI entry for `grounder overview [--limit <n>] [--markdown] [--json]`.
19
+ * `--limit` must be a positive integer when provided.
20
+ * @returns Exit code (`0` on success, `1` on usage or config errors).
21
+ */
22
+ export declare function runOverview(argv: string[]): Promise<number>;
23
+ /**
24
+ * Resolves the linked project, gathers a per-bucket count + capped recent
25
+ * titles across `notes/`, `logs/` (handoffs), and `plans/` — the same
26
+ * newest-first listings `note/handoff/plan list` use, in one call. `--json`
27
+ * items also include `mtimeMs` (the same on-disk mtime each lister already
28
+ * fetches to rank entries; see `listNotesDetailed` / `listHandoffsDetailed` /
29
+ * `listPlansDetailed`). Text and markdown stay title + path only.
30
+ * @returns Exit code (`0` on success, `1` when vault/link is missing).
31
+ */
32
+ export declare function runOverviewWithOptions(options?: OverviewOptions): Promise<number>;
33
+ //# sourceMappingURL=overview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.d.ts","sourceRoot":"","sources":["../../src/commands/overview.ts"],"names":[],"mappings":"AAaA,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AASD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCjE;AA6FD;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2C3F"}
@@ -0,0 +1,150 @@
1
+ import { withHomeDir } from "../connector/home.js";
2
+ import { resolveLogsDir, resolveNotesDir, resolvePlansDir } from "../connector/vault.js";
3
+ import { helpExitCode } from "../help.js";
4
+ import { flagBool, parseArgs } from "../util/parse-args.js";
5
+ import { toFileUri, vaultRelativePath } from "../util/path.js";
6
+ import { listHandoffsDetailed } from "../vault/list-handoffs.js";
7
+ import { listNotesDetailed } from "../vault/list-notes.js";
8
+ import { listPlansDetailed } from "../vault/list-plans.js";
9
+ import { writeSection, writeVaultItemListEntries } from "./output.js";
10
+ import { requireLinkedProject } from "./require-linked.js";
11
+ const DEFAULT_LIMIT = 3;
12
+ const USAGE = "Usage: grounder overview [--limit <n>] [--markdown] [--json]\n";
13
+ function usageError() {
14
+ process.stderr.write(USAGE);
15
+ return 1;
16
+ }
17
+ /**
18
+ * CLI entry for `grounder overview [--limit <n>] [--markdown] [--json]`.
19
+ * `--limit` must be a positive integer when provided.
20
+ * @returns Exit code (`0` on success, `1` on usage or config errors).
21
+ */
22
+ export async function runOverview(argv) {
23
+ const helpCode = helpExitCode(argv, "overview");
24
+ if (helpCode !== null) {
25
+ return helpCode;
26
+ }
27
+ const { positional, flags } = parseArgs(argv);
28
+ if (positional.length > 0) {
29
+ return usageError();
30
+ }
31
+ for (const key of flags.keys()) {
32
+ if (key !== "limit" && key !== "markdown" && key !== "json") {
33
+ return usageError();
34
+ }
35
+ }
36
+ const markdown = flagBool(flags, "markdown");
37
+ const json = flagBool(flags, "json");
38
+ if (markdown && json) {
39
+ process.stderr.write("Use only one of --markdown or --json.\n");
40
+ return 1;
41
+ }
42
+ const limitRaw = flags.get("limit");
43
+ let limit = DEFAULT_LIMIT;
44
+ if (limitRaw !== undefined) {
45
+ if (typeof limitRaw !== "string") {
46
+ return usageError();
47
+ }
48
+ const trimmed = limitRaw.trim();
49
+ const parsed = Number.parseInt(trimmed, 10);
50
+ if (!/^\d+$/.test(trimmed) || Number.isNaN(parsed) || parsed < 1) {
51
+ return usageError();
52
+ }
53
+ limit = parsed;
54
+ }
55
+ return runOverviewWithOptions({ limit, markdown, json });
56
+ }
57
+ /**
58
+ * Lists a bucket uncapped (each lister already builds this full sorted array
59
+ * internally before slicing, so this costs no extra traversal) and slices
60
+ * locally — giving `--json` an honest `total` instead of reporting the
61
+ * shown-count twice under different names.
62
+ */
63
+ async function gatherBucket(dir, noun, title, limit, lister) {
64
+ const all = await lister(dir);
65
+ return { dir, noun, title, all, shown: all.slice(0, limit) };
66
+ }
67
+ function jsonBucket(bucket) {
68
+ return {
69
+ total: bucket.all.length,
70
+ count: bucket.shown.length,
71
+ truncated: bucket.all.length > bucket.shown.length,
72
+ items: bucket.shown.map((entry) => ({
73
+ path: entry.path,
74
+ relativePath: vaultRelativePath(bucket.dir, entry.path),
75
+ fileUri: toFileUri(entry.path),
76
+ mtimeMs: entry.mtimeMs,
77
+ })),
78
+ };
79
+ }
80
+ /**
81
+ * Header line for one bucket's text/markdown section. Unlike the shared
82
+ * `note`/`handoff`/`plan list` header (`writeVaultItemList`'s
83
+ * `count === limit` → "there may be more" guess), overview already has the
84
+ * true total for free (see {@link gatherBucket}), so it reports an exact
85
+ * "N of M" instead of a maybe — the `--markdown` skill path relays this
86
+ * straight to the agent, where an honest count matters more than terseness.
87
+ */
88
+ function bucketHeader(bucket) {
89
+ const total = bucket.all.length;
90
+ const shown = bucket.shown.length;
91
+ if (total === 0) {
92
+ return `No ${bucket.noun.plural}.\n`;
93
+ }
94
+ if (shown === total) {
95
+ const label = total === 1 ? bucket.noun.singular : bucket.noun.plural;
96
+ return `All ${total} ${label}:\n\n`;
97
+ }
98
+ return `Most recent ${shown} of ${total} ${bucket.noun.plural}:\n\n`;
99
+ }
100
+ function writeTextOutput(buckets, markdown) {
101
+ buckets.forEach((bucket, index) => {
102
+ if (index > 0) {
103
+ process.stdout.write("\n");
104
+ }
105
+ writeSection(bucket.title);
106
+ process.stdout.write(bucketHeader(bucket));
107
+ writeVaultItemListEntries(bucket.shown.map((entry) => entry.path), { markdown, titleRootDir: bucket.dir });
108
+ });
109
+ }
110
+ function writeJsonOutput(buckets) {
111
+ const payload = {};
112
+ for (const bucket of buckets) {
113
+ payload[bucket.noun.plural] = jsonBucket(bucket);
114
+ }
115
+ process.stdout.write(`${JSON.stringify(payload)}\n`);
116
+ }
117
+ /**
118
+ * Resolves the linked project, gathers a per-bucket count + capped recent
119
+ * titles across `notes/`, `logs/` (handoffs), and `plans/` — the same
120
+ * newest-first listings `note/handoff/plan list` use, in one call. `--json`
121
+ * items also include `mtimeMs` (the same on-disk mtime each lister already
122
+ * fetches to rank entries; see `listNotesDetailed` / `listHandoffsDetailed` /
123
+ * `listPlansDetailed`). Text and markdown stay title + path only.
124
+ * @returns Exit code (`0` on success, `1` when vault/link is missing).
125
+ */
126
+ export async function runOverviewWithOptions(options = {}) {
127
+ return withHomeDir(options.homeDir, async () => {
128
+ const linked = await requireLinkedProject(options.cwd ?? process.cwd());
129
+ if (!linked) {
130
+ return 1;
131
+ }
132
+ const limit = options.limit ?? DEFAULT_LIMIT;
133
+ const notesDir = resolveNotesDir(linked.home, linked.repo);
134
+ const logsDir = resolveLogsDir(linked.home, linked.repo);
135
+ const plansDir = resolvePlansDir(linked.home, linked.repo);
136
+ const buckets = await Promise.all([
137
+ gatherBucket(notesDir, { singular: "note", plural: "notes" }, "Notes", limit, listNotesDetailed),
138
+ gatherBucket(logsDir, { singular: "handoff", plural: "handoffs" }, "Handoffs", limit, listHandoffsDetailed),
139
+ gatherBucket(plansDir, { singular: "plan", plural: "plans" }, "Plans", limit, listPlansDetailed),
140
+ ]);
141
+ if (options.json) {
142
+ writeJsonOutput(buckets);
143
+ }
144
+ else {
145
+ writeTextOutput(buckets, options.markdown === true);
146
+ }
147
+ return 0;
148
+ });
149
+ }
150
+ //# sourceMappingURL=overview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.js","sourceRoot":"","sources":["../../src/commands/overview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ import type { ArtifactStatus } from "../agents/types.js";
2
+ import type { GrounderState } from "../connector/state.js";
3
+ import type { PlanAction, PlanEntry } from "../reconcile/core.js";
4
+ import type { ApplyAgentInstallsResult } from "./apply.js";
5
+ /** A row's plan status, independent of tense — "current" never changes wording; the
6
+ * others are rendered as an infinitive in a dry run and past tense in a real one. */
7
+ export type RowStatus = "current" | "create" | "update" | "delete" | "forget" | "modified";
8
+ export interface Row {
9
+ status: RowStatus;
10
+ target: string;
11
+ path: string;
12
+ /** Only meaningful when `status === "modified"` — what `--force` would do to this path. */
13
+ forceAction?: "overwrite" | "delete";
14
+ }
15
+ /** For hook/runtime rows, still reported via the old imperative `ArtifactStatus` shape. */
16
+ export declare function toRowStatus(status: ArtifactStatus): RowStatus;
17
+ /**
18
+ * Whole-file artifact rows come straight from the reconciler's own plan
19
+ * vocabulary. `forget` gets its own status, distinct from `noop`'s
20
+ * "current" — a forget entry always changes `state.json` (see
21
+ * `planChangesLedger`), even though it never touches the file itself, so
22
+ * folding it into "current"/"unchanged" would hide the one row that explains
23
+ * why the trailing state row says "updated".
24
+ */
25
+ export declare function rowStatusFromPlanAction(action: PlanAction): RowStatus;
26
+ export declare function rowFromPlanEntry(target: string, entry: PlanEntry): Row;
27
+ export declare const VERB: Record<RowStatus, {
28
+ dry: string;
29
+ real: string;
30
+ }>;
31
+ /**
32
+ * Table cell label per status — the same word in dry-run and real, so the
33
+ * table asserts one outcome vocabulary instead of reconjugating per row
34
+ * (matching `kubectl apply`'s created/configured/unchanged). Dry-run-ness is
35
+ * already announced once above the table and in the summary sentence, which
36
+ * keeps its own tense (`VERB` above) since "would create" is a sentence
37
+ * construction, not a table cell.
38
+ *
39
+ * `modified` is deliberately not "modified" here: that word would read as
40
+ * Grounder having modified the file, when the row means the opposite — a
41
+ * local edit was found and Grounder left it untouched. "conflict" names that
42
+ * outcome without implying an action was taken (see the STATUS header below,
43
+ * not ACTION, for the same reason).
44
+ *
45
+ * `forget` is deliberately not "unchanged" here, even though the file itself
46
+ * is untouched: the ledger entry for it is dropped, which is exactly the
47
+ * "updated" the trailing state row reports — collapsing it into "unchanged"
48
+ * would leave that state-row change unexplained by any visible row.
49
+ */
50
+ export declare const TABLE_LABEL: Record<RowStatus, string>;
51
+ /**
52
+ * Runtime + per-agent whole-file/hook rows shared by `setup` and `migrate` —
53
+ * both callers add the trailing state/ledger row on top since that isn't
54
+ * part of `applyAgentInstalls`'s result. Tombstone retirement is already
55
+ * folded into each agent's own `plan`, so it lands right after that agent's
56
+ * own artifact rows with no separate grouping step needed.
57
+ */
58
+ export declare function rowsFromApplyResult(applyResult: ApplyAgentInstallsResult): Row[];
59
+ /**
60
+ * The trailing `state` row both `setup` and `migrate` append — same
61
+ * create/update/current rule either way, so the two callers can't drift on
62
+ * how a ledger write is reported. `ledgerChanged` is each caller's own
63
+ * computation; this only owns turning that bit plus prior-state nullness
64
+ * into a `Row`.
65
+ */
66
+ export declare function stateRow(ledgerChanged: boolean, priorState: GrounderState | null, path: string): Row;
67
+ export declare function plural(count: number, noun: string): string;
68
+ export declare function renderTable(rows: Row[]): void;
69
+ export declare function renderSummary(rows: Row[], dryRun: boolean): void;
70
+ /**
71
+ * Per-agent hook failures `applyAgentInstalls` isolated (see
72
+ * `AgentApplyResult#error`) — printed after the table/summary so a failing
73
+ * agent's hook error doesn't obscure whether other agents (or this agent's
74
+ * own whole-file artifacts, already applied by this point) succeeded.
75
+ */
76
+ export declare function renderAgentErrors(applyResult: ApplyAgentInstallsResult): void;
77
+ /**
78
+ * @param forceCommand The command line (without `--force`) the reader should
79
+ * re-run to resolve conflicts. Both `setup` and `migrate` pass `"grounder
80
+ * migrate"` today — `setup --force` applies just as well, but pointing every
81
+ * conflict at one canonical command keeps the remediation message the same
82
+ * regardless of which command surfaced the conflict.
83
+ */
84
+ export declare function renderModifiedNote(rows: Row[], forceCommand: string): void;
85
+ //# sourceMappingURL=render-artifact-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-artifact-table.d.ts","sourceRoot":"","sources":["../../src/commands/render-artifact-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D;qFACqF;AACrF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE3F,MAAM,WAAW,GAAG;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,WAAW,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;CACtC;AAED,2FAA2F;AAC3F,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAS7D;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAerE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,GAAG,CAOtE;AAED,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,SAAS,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAOjE,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAOjD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,wBAAwB,GAAG,GAAG,EAAE,CA8BhF;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,aAAa,GAAG,IAAI,EAChC,IAAI,EAAE,MAAM,GACX,GAAG,CAGL;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAW7C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CA4DhE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,wBAAwB,GAAG,IAAI,CAa7E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAuB1E"}