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
package/dist/help.js CHANGED
@@ -136,6 +136,18 @@ Subcommands:
136
136
  --markdown Agent relay: file:// links + fenced snippets
137
137
  --json Structured output (relativePath, fileUri, alsoMatchedHint per hit)`,
138
138
  },
139
+ {
140
+ id: "overview",
141
+ group: "Retrieve",
142
+ summary: "Bird's-eye view: counts + recent titles across notes/handoffs/plans",
143
+ listUsage: "overview",
144
+ usage: "grounder overview [--limit <n>] [--markdown] [--json]",
145
+ flags: `Flags:
146
+ --limit <n> Max recent titles to print per bucket (default: 3)
147
+ --markdown Agent relay: [bucketRelativePath](fileUri) title lines
148
+ --json Structured output (total, count, truncated, items per bucket;
149
+ each item includes mtimeMs)`,
150
+ },
139
151
  {
140
152
  id: "path notes",
141
153
  group: "Paths",
@@ -174,7 +186,9 @@ Subcommands:
174
186
  group: "Maintain",
175
187
  summary: "Snapshot of machine + project link + resolved paths",
176
188
  listUsage: "status",
177
- usage: "grounder status",
189
+ usage: "grounder status [--json]",
190
+ flags: `Flags:
191
+ --json Print a single-line JSON payload instead of formatted text`,
178
192
  },
179
193
  {
180
194
  id: "doctor",
@@ -190,13 +204,20 @@ Subcommands:
190
204
  group: "Maintain",
191
205
  summary: "Refresh agent install after upgrading grounder",
192
206
  listUsage: "migrate",
193
- usage: "grounder migrate [--force] [--dry-run] [--agent <id>] [--hooks]",
207
+ usage: "grounder migrate [--force] [--dry-run] [--agent <id>] [--hooks | --no-hooks]",
194
208
  flags: `Flags:
195
- --force Overwrite command files you edited locally; also needed
196
- once when upgrading from Grounder before 0.3
209
+ --force Overwrite skill files you edited locally; also needed
210
+ once when upgrading from Grounder before 0.3. Also
211
+ deletes locally-edited pre-skill grounder-*.md command
212
+ files left over from before 0.6 (edits are not ported)
197
213
  --dry-run Preview without writing
198
214
  --agent <id> Limit to a specific agent (repeatable)
199
- --hooks Also install hooks if not previously installed`,
215
+ --hooks Also install hooks if not previously installed
216
+ --no-hooks Turn hooks off and remove the installed hook entry
217
+ (sticky — a later plain migrate will not re-enable it)
218
+
219
+ Also retires pre-skill grounder-*.md command files superseded by
220
+ SKILL.md packaging (safe ones automatically; edited ones need --force).`,
200
221
  },
201
222
  {
202
223
  id: "handoff peek",
@@ -240,6 +261,7 @@ export const DISPATCHED_COMMAND_IDS = [
240
261
  "plan",
241
262
  "plan list",
242
263
  "search",
264
+ "overview",
243
265
  "path",
244
266
  "path notes",
245
267
  "path logs",
package/dist/help.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type PlanEntry } from "./core.js";
2
+ export interface ApplyPlanOptions {
3
+ agentId: string;
4
+ plan: readonly PlanEntry[];
5
+ /** Desired content for `create`/`update`/`noop` entries — path → rendered bytes. */
6
+ content: Record<string, string>;
7
+ grounderVersion: string;
8
+ homeDir?: string;
9
+ /**
10
+ * Directories this agent is allowed to write into / delete from (its own
11
+ * `AgentAdapter#ownedPrefixes`) — re-checked here via
12
+ * {@link isUnderOwnedPrefix}, not trusted solely from the caller, so a plan
13
+ * built from a stray/corrupted ledger entry can never be applied as a
14
+ * filesystem write outside the agent's own tree.
15
+ */
16
+ ownedPrefixes: readonly string[];
17
+ }
18
+ /**
19
+ * Execute a whole-file plan: write/delete each path, and persist that path's
20
+ * ledger hash right after its own file write succeeds (per-artifact, not
21
+ * batched) — a mid-run crash leaves the ledger consistent with whatever
22
+ * actually completed.
23
+ *
24
+ * Returns nothing: callers render their tables from the `PlanEntry[]` they
25
+ * passed in (see `commands/render-artifact-table.ts`'s
26
+ * `rowStatusFromPlanAction`), so a second per-path outcome vocabulary here
27
+ * would only be a chance for the two to disagree. Failure is a throw, not a
28
+ * status — every entry that doesn't throw did exactly what its action says.
29
+ */
30
+ export declare function applyPlan(opts: ApplyPlanOptions): Promise<void>;
31
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/reconcile/apply.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IAC3B,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFrE"}
@@ -0,0 +1,97 @@
1
+ import { unlink } from "node:fs/promises";
2
+ import { forgetLedgerFile, setLedgerFileHash } from "../connector/state.js";
3
+ import { writeFileAtomic } from "../util/fs.js";
4
+ import { hashContent } from "../util/hash.js";
5
+ import { isUnderOwnedPrefix } from "./core.js";
6
+ /**
7
+ * Execute a whole-file plan: write/delete each path, and persist that path's
8
+ * ledger hash right after its own file write succeeds (per-artifact, not
9
+ * batched) — a mid-run crash leaves the ledger consistent with whatever
10
+ * actually completed.
11
+ *
12
+ * Returns nothing: callers render their tables from the `PlanEntry[]` they
13
+ * passed in (see `commands/render-artifact-table.ts`'s
14
+ * `rowStatusFromPlanAction`), so a second per-path outcome vocabulary here
15
+ * would only be a chance for the two to disagree. Failure is a throw, not a
16
+ * status — every entry that doesn't throw did exactly what its action says.
17
+ */
18
+ export async function applyPlan(opts) {
19
+ for (const entry of opts.plan) {
20
+ if ((entry.action === "create" || entry.action === "update" || entry.action === "delete") &&
21
+ !isUnderOwnedPrefix(entry.path, opts.ownedPrefixes)) {
22
+ throw new Error(`Refusing to ${entry.action} ${entry.path}: outside ${opts.agentId}'s owned prefixes`);
23
+ }
24
+ switch (entry.action) {
25
+ case "create":
26
+ case "update": {
27
+ const content = opts.content[entry.path];
28
+ if (content === undefined) {
29
+ throw new Error(`No desired content for ${entry.path} (action: ${entry.action})`);
30
+ }
31
+ await writeFileAtomic(entry.path, content);
32
+ await setLedgerFileHash({
33
+ agentId: opts.agentId,
34
+ filePath: entry.path,
35
+ hash: hashContent(content),
36
+ grounderVersion: opts.grounderVersion,
37
+ homeDir: opts.homeDir,
38
+ });
39
+ break;
40
+ }
41
+ case "noop": {
42
+ // A desired path already matching on disk — hydrate the ledger hash
43
+ // when it wasn't recorded yet (or recorded stale), so a manually
44
+ // correct file becomes safely Grounder-managed going forward.
45
+ const content = opts.content[entry.path];
46
+ if (content !== undefined) {
47
+ await setLedgerFileHash({
48
+ agentId: opts.agentId,
49
+ filePath: entry.path,
50
+ hash: hashContent(content),
51
+ grounderVersion: opts.grounderVersion,
52
+ homeDir: opts.homeDir,
53
+ });
54
+ }
55
+ break;
56
+ }
57
+ case "delete": {
58
+ try {
59
+ await unlink(entry.path);
60
+ }
61
+ catch (error) {
62
+ if (error.code !== "ENOENT") {
63
+ // A real failure (EACCES, EISDIR, …) — propagate rather than
64
+ // forgetting the ledger hash for a file that's still on disk;
65
+ // swallowing it here would leave the ledger and disk permanently
66
+ // disagreeing, with no way for a future run to notice and retry.
67
+ throw error;
68
+ }
69
+ }
70
+ await forgetLedgerFile({
71
+ agentId: opts.agentId,
72
+ filePath: entry.path,
73
+ grounderVersion: opts.grounderVersion,
74
+ homeDir: opts.homeDir,
75
+ });
76
+ break;
77
+ }
78
+ case "forget": {
79
+ // Already gone from disk, but the ledger still holds a stale hash
80
+ // (removed outside `migrate`) — drop it so it doesn't linger forever.
81
+ await forgetLedgerFile({
82
+ agentId: opts.agentId,
83
+ filePath: entry.path,
84
+ grounderVersion: opts.grounderVersion,
85
+ homeDir: opts.homeDir,
86
+ });
87
+ break;
88
+ }
89
+ case "conflict":
90
+ // Left alone on purpose — on-disk content Grounder can't confirm it
91
+ // wrote. `--force` is what turns this into an `update`/`delete`
92
+ // upstream in `reconcile()`, so there is nothing to do here.
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/reconcile/apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Pure reconciliation core — no I/O anywhere in this file.
3
+ *
4
+ * Two shapes, per the design: {@link desiredDrift} answers "would migrate
5
+ * change something" cheaply (ledger vs. rendered template hashes only, no
6
+ * disk read) for `peek`/`status`; {@link reconcile} is the full three-way
7
+ * (desired vs. ledger vs. on-disk) plan `setup`/`migrate`/`doctor` execute or
8
+ * preview. Modeled on chezmoi's source/destination/target state and dpkg's
9
+ * old-pristine/new-pristine/on-disk compare.
10
+ */
11
+ /**
12
+ * True when `filePath` sits under one of `prefixes` (a directory, matched
13
+ * exactly or via a `prefix + separator` boundary — never a bare substring
14
+ * match, and never a `..`-segment escape). Callers use this to keep a
15
+ * ledger's extra/stray entries — a hand-edited or corrupted `state.json`,
16
+ * say — from ever being treated as delete candidates for paths outside the
17
+ * directories an adapter actually manages. Comparison is lexical
18
+ * (`path.resolve` + `path.relative`, no symlink following): both sides are
19
+ * resolved to absolute form first, so a `../` segment in `filePath` cannot
20
+ * walk back out of a prefix it superficially starts with.
21
+ * `reconcile()` itself stays agnostic to this (see its own docs); callers
22
+ * filter `ledger` before passing it in.
23
+ */
24
+ export declare function isUnderOwnedPrefix(filePath: string, prefixes: readonly string[]): boolean;
25
+ export type DriftKind = "create" | "update";
26
+ export interface DriftEntry {
27
+ path: string;
28
+ kind: DriftKind;
29
+ }
30
+ /** One agent's last-applied manifest — path → hash of the bytes Grounder wrote. */
31
+ export type LedgerManifest = Record<string, {
32
+ hash?: string;
33
+ }>;
34
+ /**
35
+ * Compare desired (rendered template) hashes against one agent's last-applied
36
+ * ledger manifest. No disk I/O — the caller renders + hashes templates, and
37
+ * passes in the ledger's `files` map already read from `state.json`.
38
+ *
39
+ * `ledger === undefined` means this agent has no ledger entry at all (never
40
+ * installed) — returns no drift. Scoping to ledger-recorded agents lives
41
+ * here, not in every caller: otherwise a detected-but-never-installed agent
42
+ * would tease `migrate` forever with no command able to silence it.
43
+ *
44
+ * Within a ledger-recorded agent, a desired path missing from its `files` map
45
+ * IS drift (`"create"`) — that's how a newly added skill file surfaces here.
46
+ */
47
+ export declare function desiredDrift(desired: Record<string, string>, ledger: LedgerManifest | undefined): DriftEntry[];
48
+ export type PlanAction = "create" | "update" | "delete" | "conflict" | "noop" | "forget";
49
+ export interface PlanEntry {
50
+ path: string;
51
+ action: PlanAction;
52
+ /** Only set when `action === "conflict"` — which action `--force` would take. */
53
+ blockedAction?: "overwrite" | "delete";
54
+ }
55
+ /** path → on-disk content hash, `undefined` when the path does not exist. */
56
+ export type DiskHashes = Record<string, string | undefined>;
57
+ /**
58
+ * Full three-way reconcile for one agent's whole-file artifacts: desired
59
+ * (current templates) vs. ledger (last-applied) vs. disk (actual). Pure —
60
+ * `disk`/`ledger` are already-read snapshots, not live filesystem access.
61
+ *
62
+ * `tombstones` are extra "previously desired, no longer desired" paths
63
+ * (pre-skill command files, etc.) unioned into the retirement side of the
64
+ * diff even when the ledger never recorded them — the case a pure
65
+ * ledger-manifest diff is blind to (pre-hash-tracking installs).
66
+ *
67
+ * Safety: only ever call this for a known agent id whose `desired` this
68
+ * binary can actually compute — never for an unrecognized ledger entry,
69
+ * which would treat its entire recorded file set as delete candidates.
70
+ */
71
+ export declare function reconcile(desired: Record<string, string>, tombstones: readonly string[], ledger: LedgerManifest | undefined, disk: DiskHashes, force: boolean): PlanEntry[];
72
+ /**
73
+ * Would applying `plan` actually change the ledger? Pure — mirrors exactly
74
+ * what `applyPlan()`'s per-artifact writes do (each has its own no-op guard):
75
+ * `create`/`update`/`noop` only write when the recorded hash would actually
76
+ * change; `delete` only forgets an entry that exists; `forget` always writes
77
+ * (by construction it only exists when there's something to forget);
78
+ * `conflict` never touches the ledger. Used so `--dry-run` and a real run
79
+ * predict/report the exact same thing for the exact same reason.
80
+ */
81
+ export declare function planChangesLedger(plan: readonly PlanEntry[], ledger: LedgerManifest | undefined, desired: Record<string, string>): boolean;
82
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/reconcile/core.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAezF;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE/D;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,MAAM,EAAE,cAAc,GAAG,SAAS,GACjC,UAAU,EAAE,CAcd;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEzF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,iFAAiF;IACjF,aAAa,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;CACxC;AAED,6EAA6E;AAC7E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,OAAO,GACb,SAAS,EAAE,CA4Cb;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAyBT"}
@@ -0,0 +1,163 @@
1
+ import path from "node:path";
2
+ /**
3
+ * Pure reconciliation core — no I/O anywhere in this file.
4
+ *
5
+ * Two shapes, per the design: {@link desiredDrift} answers "would migrate
6
+ * change something" cheaply (ledger vs. rendered template hashes only, no
7
+ * disk read) for `peek`/`status`; {@link reconcile} is the full three-way
8
+ * (desired vs. ledger vs. on-disk) plan `setup`/`migrate`/`doctor` execute or
9
+ * preview. Modeled on chezmoi's source/destination/target state and dpkg's
10
+ * old-pristine/new-pristine/on-disk compare.
11
+ */
12
+ /**
13
+ * True when `filePath` sits under one of `prefixes` (a directory, matched
14
+ * exactly or via a `prefix + separator` boundary — never a bare substring
15
+ * match, and never a `..`-segment escape). Callers use this to keep a
16
+ * ledger's extra/stray entries — a hand-edited or corrupted `state.json`,
17
+ * say — from ever being treated as delete candidates for paths outside the
18
+ * directories an adapter actually manages. Comparison is lexical
19
+ * (`path.resolve` + `path.relative`, no symlink following): both sides are
20
+ * resolved to absolute form first, so a `../` segment in `filePath` cannot
21
+ * walk back out of a prefix it superficially starts with.
22
+ * `reconcile()` itself stays agnostic to this (see its own docs); callers
23
+ * filter `ledger` before passing it in.
24
+ */
25
+ export function isUnderOwnedPrefix(filePath, prefixes) {
26
+ const target = path.resolve(filePath);
27
+ return prefixes.some((prefix) => {
28
+ const root = path.resolve(prefix);
29
+ if (root === target) {
30
+ return true;
31
+ }
32
+ const relative = path.relative(root, target);
33
+ return (relative !== "" &&
34
+ relative !== ".." &&
35
+ !relative.startsWith(`..${path.sep}`) &&
36
+ !path.isAbsolute(relative));
37
+ });
38
+ }
39
+ /**
40
+ * Compare desired (rendered template) hashes against one agent's last-applied
41
+ * ledger manifest. No disk I/O — the caller renders + hashes templates, and
42
+ * passes in the ledger's `files` map already read from `state.json`.
43
+ *
44
+ * `ledger === undefined` means this agent has no ledger entry at all (never
45
+ * installed) — returns no drift. Scoping to ledger-recorded agents lives
46
+ * here, not in every caller: otherwise a detected-but-never-installed agent
47
+ * would tease `migrate` forever with no command able to silence it.
48
+ *
49
+ * Within a ledger-recorded agent, a desired path missing from its `files` map
50
+ * IS drift (`"create"`) — that's how a newly added skill file surfaces here.
51
+ */
52
+ export function desiredDrift(desired, ledger) {
53
+ if (!ledger) {
54
+ return [];
55
+ }
56
+ const out = [];
57
+ for (const [path, hash] of Object.entries(desired)) {
58
+ const recorded = ledger[path]?.hash;
59
+ if (recorded === undefined) {
60
+ out.push({ path, kind: "create" });
61
+ }
62
+ else if (recorded !== hash) {
63
+ out.push({ path, kind: "update" });
64
+ }
65
+ }
66
+ return out;
67
+ }
68
+ /**
69
+ * Full three-way reconcile for one agent's whole-file artifacts: desired
70
+ * (current templates) vs. ledger (last-applied) vs. disk (actual). Pure —
71
+ * `disk`/`ledger` are already-read snapshots, not live filesystem access.
72
+ *
73
+ * `tombstones` are extra "previously desired, no longer desired" paths
74
+ * (pre-skill command files, etc.) unioned into the retirement side of the
75
+ * diff even when the ledger never recorded them — the case a pure
76
+ * ledger-manifest diff is blind to (pre-hash-tracking installs).
77
+ *
78
+ * Safety: only ever call this for a known agent id whose `desired` this
79
+ * binary can actually compute — never for an unrecognized ledger entry,
80
+ * which would treat its entire recorded file set as delete candidates.
81
+ */
82
+ export function reconcile(desired, tombstones, ledger, disk, force) {
83
+ const ledgerFiles = ledger ?? {};
84
+ const allPaths = new Set([
85
+ ...Object.keys(desired),
86
+ ...Object.keys(ledgerFiles),
87
+ ...tombstones,
88
+ ]);
89
+ const entries = [];
90
+ for (const path of allPaths) {
91
+ const desiredHash = desired[path];
92
+ const ledgerHash = ledgerFiles[path]?.hash;
93
+ const onDisk = disk[path];
94
+ if (desiredHash !== undefined) {
95
+ // Whole-file artifact currently wanted.
96
+ if (onDisk === undefined) {
97
+ entries.push({ path, action: "create" });
98
+ }
99
+ else if (onDisk === desiredHash) {
100
+ entries.push({ path, action: "noop" });
101
+ }
102
+ else if (force || (ledgerHash !== undefined && ledgerHash === onDisk)) {
103
+ entries.push({ path, action: "update" });
104
+ }
105
+ else {
106
+ entries.push({ path, action: "conflict", blockedAction: "overwrite" });
107
+ }
108
+ continue;
109
+ }
110
+ // Not in the current desired set — retirement candidate (tombstone, or a
111
+ // path dropped from the manifest by a schema change).
112
+ if (onDisk === undefined) {
113
+ // Already gone — noop, not a recurring delete (doctor would otherwise
114
+ // warn about an already-cleaned-up legacy path forever). If the ledger
115
+ // still holds a stale hash for it (removed outside `migrate`), that's
116
+ // a ledger-only cleanup ("forget"), not a file action.
117
+ entries.push({ path, action: ledgerHash !== undefined ? "forget" : "noop" });
118
+ }
119
+ else if (force || (ledgerHash !== undefined && ledgerHash === onDisk)) {
120
+ entries.push({ path, action: "delete" });
121
+ }
122
+ else {
123
+ entries.push({ path, action: "conflict", blockedAction: "delete" });
124
+ }
125
+ }
126
+ return entries;
127
+ }
128
+ /**
129
+ * Would applying `plan` actually change the ledger? Pure — mirrors exactly
130
+ * what `applyPlan()`'s per-artifact writes do (each has its own no-op guard):
131
+ * `create`/`update`/`noop` only write when the recorded hash would actually
132
+ * change; `delete` only forgets an entry that exists; `forget` always writes
133
+ * (by construction it only exists when there's something to forget);
134
+ * `conflict` never touches the ledger. Used so `--dry-run` and a real run
135
+ * predict/report the exact same thing for the exact same reason.
136
+ */
137
+ export function planChangesLedger(plan, ledger, desired) {
138
+ const ledgerFiles = ledger ?? {};
139
+ for (const entry of plan) {
140
+ switch (entry.action) {
141
+ case "create":
142
+ case "update":
143
+ case "noop": {
144
+ const desiredHash = desired[entry.path];
145
+ if (desiredHash !== undefined && ledgerFiles[entry.path]?.hash !== desiredHash) {
146
+ return true;
147
+ }
148
+ break;
149
+ }
150
+ case "delete":
151
+ if (ledgerFiles[entry.path]?.hash !== undefined) {
152
+ return true;
153
+ }
154
+ break;
155
+ case "forget":
156
+ return true;
157
+ case "conflict":
158
+ break;
159
+ }
160
+ }
161
+ return false;
162
+ }
163
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/reconcile/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { DiskHashes } from "./core.js";
2
+ /**
3
+ * Read + hash each path; a missing file maps to `undefined`. Any other read
4
+ * failure (EACCES, EISDIR, …) propagates instead of being folded into
5
+ * "missing" — an unreadable-but-present file must never be silently planned
6
+ * as a `create`, writing blind over content this binary never actually saw.
7
+ * Both callers already have somewhere for that to land gracefully: doctor's
8
+ * `computeAgentPlansSafe` catches per-agent and turns it into a "could not
9
+ * verify skill drift" warning; `setup`/`migrate` catch it around
10
+ * `applyAgentInstalls` and report it on stderr.
11
+ */
12
+ export declare function readDiskHashes(paths: Iterable<string>): Promise<DiskHashes>;
13
+ //# sourceMappingURL=disk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk.d.ts","sourceRoot":"","sources":["../../src/reconcile/disk.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAajF"}
@@ -0,0 +1,28 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { hashContent } from "../util/hash.js";
3
+ /**
4
+ * Read + hash each path; a missing file maps to `undefined`. Any other read
5
+ * failure (EACCES, EISDIR, …) propagates instead of being folded into
6
+ * "missing" — an unreadable-but-present file must never be silently planned
7
+ * as a `create`, writing blind over content this binary never actually saw.
8
+ * Both callers already have somewhere for that to land gracefully: doctor's
9
+ * `computeAgentPlansSafe` catches per-agent and turns it into a "could not
10
+ * verify skill drift" warning; `setup`/`migrate` catch it around
11
+ * `applyAgentInstalls` and report it on stderr.
12
+ */
13
+ export async function readDiskHashes(paths) {
14
+ const out = {};
15
+ for (const p of paths) {
16
+ try {
17
+ out[p] = hashContent(await readFile(p, "utf8"));
18
+ }
19
+ catch (error) {
20
+ if (error.code !== "ENOENT") {
21
+ throw error;
22
+ }
23
+ out[p] = undefined;
24
+ }
25
+ }
26
+ return out;
27
+ }
28
+ //# sourceMappingURL=disk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk.js","sourceRoot":"","sources":["../../src/reconcile/disk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAuB;IAC1D,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,GAAG,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;YACD,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/util/fs.d.ts CHANGED
@@ -5,6 +5,20 @@ export declare function fileExists(filePath: string): Promise<boolean>;
5
5
  * not oversell POSIX execute-bit semantics there.
6
6
  */
7
7
  export declare function isExecutable(filePath: string): Promise<boolean>;
8
+ /**
9
+ * Write `content` to `filePath` via tmp file + rename, so a crash mid-write
10
+ * never leaves a truncated file at the real path. Creates the destination
11
+ * directory if needed; best-effort removes the tmp file if `rename` itself
12
+ * throws, so a failed write doesn't leave an orphaned `.tmp-*` sibling behind.
13
+ * `mode` (e.g. the pre-existing file's permission bits), when given, is
14
+ * applied to the tmp file before the rename — otherwise the replaced file
15
+ * would pick up the tmp file's default umask permissions instead of keeping
16
+ * whatever the file already had, which matters for host-owned config files
17
+ * edited by other tools.
18
+ */
19
+ export declare function writeFileAtomic(filePath: string, content: string, options?: {
20
+ mode?: number;
21
+ }): Promise<void>;
8
22
  /**
9
23
  * Creates a new markdown file under `dir`; never overwrites.
10
24
  * Tries `basename.md`, then `basename_02.md`, `_03`, … with `wx` (O_EXCL)
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/util/fs.ts"],"names":[],"mappings":"AAIA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrE;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAgBjB"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/util/fs.ts"],"names":[],"mappings":"AAIA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAgBjB"}
package/dist/util/fs.js CHANGED
@@ -1,4 +1,4 @@
1
- import { access, constants, writeFile } from "node:fs/promises";
1
+ import { access, chmod, constants, mkdir, rename, unlink, writeFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { collisionSuffix } from "./timestamp-slug.js";
4
4
  export async function fileExists(filePath) {
@@ -24,6 +24,32 @@ export async function isExecutable(filePath) {
24
24
  return false;
25
25
  }
26
26
  }
27
+ /**
28
+ * Write `content` to `filePath` via tmp file + rename, so a crash mid-write
29
+ * never leaves a truncated file at the real path. Creates the destination
30
+ * directory if needed; best-effort removes the tmp file if `rename` itself
31
+ * throws, so a failed write doesn't leave an orphaned `.tmp-*` sibling behind.
32
+ * `mode` (e.g. the pre-existing file's permission bits), when given, is
33
+ * applied to the tmp file before the rename — otherwise the replaced file
34
+ * would pick up the tmp file's default umask permissions instead of keeping
35
+ * whatever the file already had, which matters for host-owned config files
36
+ * edited by other tools.
37
+ */
38
+ export async function writeFileAtomic(filePath, content, options = {}) {
39
+ await mkdir(path.dirname(filePath), { recursive: true });
40
+ const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
41
+ await writeFile(tmpPath, content, "utf8");
42
+ if (options.mode !== undefined) {
43
+ await chmod(tmpPath, options.mode);
44
+ }
45
+ try {
46
+ await rename(tmpPath, filePath);
47
+ }
48
+ catch (error) {
49
+ await unlink(tmpPath).catch(() => { });
50
+ throw error;
51
+ }
52
+ }
27
53
  /**
28
54
  * Creates a new markdown file under `dir`; never overwrites.
29
55
  * Tries `basename.md`, then `basename_02.md`, `_03`, … with `wx` (O_EXCL)
@@ -1 +1 @@
1
- {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/util/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAW,EACX,QAAgB,EAChB,OAAe;IAEf,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/util/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,OAAe,EACf,UAA6B,EAAE;IAE/B,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,GAAG,QAAQ,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC/D,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACtC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAW,EACX,QAAgB,EAChB,OAAe;IAEf,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC"}