harnery 0.9.0 → 0.11.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 (211) hide show
  1. package/README.md +1 -0
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +6 -0
  4. package/dist/commands/agents.d.ts +24 -0
  5. package/dist/commands/agents.d.ts.map +1 -1
  6. package/dist/commands/agents.js +244 -13
  7. package/dist/commands/backup.d.ts +5 -4
  8. package/dist/commands/backup.d.ts.map +1 -1
  9. package/dist/commands/backup.js +15 -14
  10. package/dist/commands/browse.d.ts.map +1 -1
  11. package/dist/commands/browse.js +27 -1
  12. package/dist/commands/claude-desktop.d.ts +19 -0
  13. package/dist/commands/claude-desktop.d.ts.map +1 -0
  14. package/dist/commands/claude-desktop.js +168 -0
  15. package/dist/commands/context.d.ts.map +1 -1
  16. package/dist/commands/context.js +149 -1
  17. package/dist/commands/doctor.d.ts.map +1 -1
  18. package/dist/commands/doctor.js +2 -3
  19. package/dist/commands/eml.d.ts +32 -0
  20. package/dist/commands/eml.d.ts.map +1 -1
  21. package/dist/commands/eml.js +16 -3
  22. package/dist/commands/harness.d.ts +11 -0
  23. package/dist/commands/harness.d.ts.map +1 -0
  24. package/dist/commands/harness.js +118 -0
  25. package/dist/commands/presence.d.ts +9 -4
  26. package/dist/commands/presence.d.ts.map +1 -1
  27. package/dist/commands/presence.js +88 -5
  28. package/dist/commands/relay.d.ts +9 -0
  29. package/dist/commands/relay.d.ts.map +1 -0
  30. package/dist/commands/relay.js +143 -0
  31. package/dist/commands/sync.d.ts.map +1 -1
  32. package/dist/commands/sync.js +5 -0
  33. package/dist/commands/workflow.d.ts.map +1 -1
  34. package/dist/commands/workflow.js +53 -17
  35. package/dist/core/agents/canonical-emit.d.ts +15 -0
  36. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  37. package/dist/core/agents/canonical-emit.js +41 -3
  38. package/dist/core/agents/cli.js +4 -2
  39. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  40. package/dist/core/agents/render/prompt-context.js +44 -3
  41. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  42. package/dist/core/agents/render/session-context.js +26 -1
  43. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  44. package/dist/core/agents/rules/commit-conflict.js +4 -37
  45. package/dist/core/agents/session-events.d.ts.map +1 -1
  46. package/dist/core/agents/session-events.js +16 -43
  47. package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
  48. package/dist/core/agents/state/heartbeat-projector.js +11 -2
  49. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  50. package/dist/core/agents/state/heartbeat-writer.js +3 -3
  51. package/dist/core/agents/state/names.d.ts +38 -3
  52. package/dist/core/agents/state/names.d.ts.map +1 -1
  53. package/dist/core/agents/state/names.js +46 -7
  54. package/dist/core/agents/state/pidmap.d.ts +5 -1
  55. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  56. package/dist/core/agents/state/pidmap.js +58 -2
  57. package/dist/core/agents/state/stale-sweep.d.ts +3 -2
  58. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  59. package/dist/core/agents/state/stale-sweep.js +6 -6
  60. package/dist/core/config.d.ts +68 -11
  61. package/dist/core/config.d.ts.map +1 -1
  62. package/dist/core/config.js +191 -25
  63. package/dist/core/context/index.d.ts +144 -0
  64. package/dist/core/context/index.d.ts.map +1 -0
  65. package/dist/core/context/index.js +380 -0
  66. package/dist/core/harnesses/bench.d.ts +29 -0
  67. package/dist/core/harnesses/bench.d.ts.map +1 -0
  68. package/dist/core/harnesses/bench.js +151 -0
  69. package/dist/core/harnesses/index.d.ts +9 -0
  70. package/dist/core/harnesses/index.d.ts.map +1 -0
  71. package/dist/core/harnesses/index.js +4 -0
  72. package/dist/core/harnesses/profiles.d.ts +62 -0
  73. package/dist/core/harnesses/profiles.d.ts.map +1 -0
  74. package/dist/core/harnesses/profiles.js +115 -0
  75. package/dist/core/harnesses/registry.d.ts +15 -0
  76. package/dist/core/harnesses/registry.d.ts.map +1 -0
  77. package/dist/core/harnesses/registry.js +113 -0
  78. package/dist/core/harnesses/types.d.ts +64 -0
  79. package/dist/core/harnesses/types.d.ts.map +1 -0
  80. package/dist/core/harnesses/types.js +20 -0
  81. package/dist/core/hooks/cli.js +280 -63
  82. package/dist/core/hooks/events/schema.d.ts +38 -1
  83. package/dist/core/hooks/events/schema.d.ts.map +1 -1
  84. package/dist/core/hooks/harness/events.d.ts.map +1 -1
  85. package/dist/core/hooks/harness/events.js +3 -0
  86. package/dist/core/hooks/harness/parse.d.ts +1 -1
  87. package/dist/core/hooks/harness/parse.d.ts.map +1 -1
  88. package/dist/core/hooks/harness/parse.js +4 -0
  89. package/dist/core/presence/blob.d.ts +40 -0
  90. package/dist/core/presence/blob.d.ts.map +1 -0
  91. package/dist/core/presence/blob.js +91 -0
  92. package/dist/core/presence/git.d.ts +68 -0
  93. package/dist/core/presence/git.d.ts.map +1 -0
  94. package/dist/core/presence/git.js +173 -0
  95. package/dist/core/presence/index.d.ts +74 -0
  96. package/dist/core/presence/index.d.ts.map +1 -0
  97. package/dist/core/presence/index.js +224 -0
  98. package/dist/core/presence/relay-client.d.ts +39 -0
  99. package/dist/core/presence/relay-client.d.ts.map +1 -0
  100. package/dist/core/presence/relay-client.js +295 -0
  101. package/dist/core/presence/relay-protocol.d.ts +94 -0
  102. package/dist/core/presence/relay-protocol.d.ts.map +1 -0
  103. package/dist/core/presence/relay-protocol.js +169 -0
  104. package/dist/core/workflow/billing.d.ts +1 -1
  105. package/dist/core/workflow/billing.d.ts.map +1 -1
  106. package/dist/core/workflow/billing.js +7 -1
  107. package/dist/core/workflow/engine.d.ts +5 -0
  108. package/dist/core/workflow/engine.d.ts.map +1 -1
  109. package/dist/core/workflow/engine.js +164 -16
  110. package/dist/core/workflow/harnesses.d.ts +3 -3
  111. package/dist/core/workflow/harnesses.d.ts.map +1 -1
  112. package/dist/core/workflow/harnesses.js +8 -17
  113. package/dist/core/workflow/index.d.ts +5 -0
  114. package/dist/core/workflow/index.d.ts.map +1 -0
  115. package/dist/core/workflow/index.js +3 -0
  116. package/dist/core/workflow/proof.d.ts +42 -0
  117. package/dist/core/workflow/proof.d.ts.map +1 -0
  118. package/dist/core/workflow/proof.js +342 -0
  119. package/dist/core/workflow/spawn-claude.d.ts +4 -1
  120. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  121. package/dist/core/workflow/spawn-claude.js +39 -18
  122. package/dist/core/workflow/spawn-codex.d.ts +4 -1
  123. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  124. package/dist/core/workflow/spawn-codex.js +44 -22
  125. package/dist/core/workflow/spawn-cursor.d.ts +4 -1
  126. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  127. package/dist/core/workflow/spawn-cursor.js +35 -16
  128. package/dist/core/workflow/types.d.ts +156 -2
  129. package/dist/core/workflow/types.d.ts.map +1 -1
  130. package/dist/core/workflow/types.js +1 -1
  131. package/dist/lib/browser/client.d.ts +16 -0
  132. package/dist/lib/browser/client.d.ts.map +1 -1
  133. package/dist/lib/browser/client.js +22 -0
  134. package/dist/lib/browser/index.d.ts +1 -0
  135. package/dist/lib/browser/index.d.ts.map +1 -1
  136. package/dist/lib/browser/index.js +1 -0
  137. package/dist/lib/browser/launch-args.d.ts +21 -0
  138. package/dist/lib/browser/launch-args.d.ts.map +1 -0
  139. package/dist/lib/browser/launch-args.js +32 -0
  140. package/dist/lib/claude-desktop.d.ts +105 -0
  141. package/dist/lib/claude-desktop.d.ts.map +1 -0
  142. package/dist/lib/claude-desktop.js +217 -0
  143. package/dist/lib/docs-lint.d.ts.map +1 -1
  144. package/dist/lib/docs-lint.js +5 -2
  145. package/dist/lib/identities/assume.d.ts +51 -0
  146. package/dist/lib/identities/assume.d.ts.map +1 -0
  147. package/dist/lib/identities/assume.js +274 -0
  148. package/dist/lib/identities/index.d.ts +7 -7
  149. package/dist/lib/identities/index.d.ts.map +1 -1
  150. package/dist/lib/identities/index.js +24 -24
  151. package/dist/lib/instructions/templates.d.ts.map +1 -1
  152. package/dist/lib/instructions/templates.js +15 -2
  153. package/package.json +22 -6
  154. package/schemas/config.schema.json +88 -19
  155. package/src/commander.ts +6 -0
  156. package/src/commands/agents.ts +280 -14
  157. package/src/commands/backup.ts +17 -16
  158. package/src/commands/browse.ts +32 -0
  159. package/src/commands/claude-desktop.ts +215 -0
  160. package/src/commands/context.ts +174 -1
  161. package/src/commands/doctor.ts +2 -3
  162. package/src/commands/eml.ts +22 -4
  163. package/src/commands/harness.ts +147 -0
  164. package/src/commands/presence.ts +111 -5
  165. package/src/commands/relay.ts +160 -0
  166. package/src/commands/sync.ts +4 -0
  167. package/src/commands/workflow.ts +62 -19
  168. package/src/core/agents/canonical-emit.ts +41 -3
  169. package/src/core/agents/cli.ts +4 -2
  170. package/src/core/agents/render/prompt-context.ts +48 -3
  171. package/src/core/agents/render/session-context.ts +27 -1
  172. package/src/core/agents/rules/commit-conflict.ts +4 -33
  173. package/src/core/agents/session-events.ts +15 -39
  174. package/src/core/agents/state/heartbeat-projector.ts +10 -1
  175. package/src/core/agents/state/heartbeat-writer.ts +3 -2
  176. package/src/core/agents/state/names.ts +68 -9
  177. package/src/core/agents/state/pidmap.ts +59 -2
  178. package/src/core/agents/state/stale-sweep.ts +6 -11
  179. package/src/core/config.ts +248 -24
  180. package/src/core/context/index.ts +575 -0
  181. package/src/core/harnesses/bench.ts +214 -0
  182. package/src/core/harnesses/index.ts +31 -0
  183. package/src/core/harnesses/profiles.ts +141 -0
  184. package/src/core/harnesses/registry.ts +140 -0
  185. package/src/core/harnesses/types.ts +90 -0
  186. package/src/core/hooks/cli.ts +331 -62
  187. package/src/core/hooks/events/schema.ts +68 -0
  188. package/src/core/hooks/harness/events.ts +3 -0
  189. package/src/core/hooks/harness/parse.ts +7 -1
  190. package/src/core/presence/blob.ts +125 -0
  191. package/src/core/presence/git.ts +191 -0
  192. package/src/core/presence/index.ts +274 -0
  193. package/src/core/presence/relay-client.ts +322 -0
  194. package/src/core/presence/relay-protocol.ts +246 -0
  195. package/src/core/workflow/billing.ts +8 -2
  196. package/src/core/workflow/engine.ts +182 -16
  197. package/src/core/workflow/harnesses.ts +14 -19
  198. package/src/core/workflow/index.ts +43 -0
  199. package/src/core/workflow/proof.ts +434 -0
  200. package/src/core/workflow/spawn-claude.ts +39 -20
  201. package/src/core/workflow/spawn-codex.ts +47 -28
  202. package/src/core/workflow/spawn-cursor.ts +37 -18
  203. package/src/core/workflow/types.ts +176 -2
  204. package/src/lib/browser/client.ts +37 -0
  205. package/src/lib/browser/index.ts +1 -0
  206. package/src/lib/browser/launch-args.ts +33 -0
  207. package/src/lib/claude-desktop.ts +293 -0
  208. package/src/lib/docs-lint.ts +5 -2
  209. package/src/lib/identities/assume.ts +363 -0
  210. package/src/lib/identities/index.ts +28 -24
  211. package/src/lib/instructions/templates.ts +16 -2
@@ -0,0 +1,217 @@
1
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { basename, dirname, join } from "node:path";
4
+ const SESSIONS_DIRNAME = "claude-code-sessions";
5
+ function isWsl() {
6
+ if (process.env.WSL_DISTRO_NAME)
7
+ return true;
8
+ try {
9
+ return readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft");
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ /**
16
+ * Candidate desktop-app data directories for this machine, most specific
17
+ * first. Only directories that exist AND contain a claude-code-sessions/
18
+ * subdirectory are returned. Precedence: explicit arg, then
19
+ * HARNERY_CLAUDE_DESKTOP_DIR, then platform defaults (on WSL that means
20
+ * scanning every /mnt/c/Users/<user>/AppData/Roaming/Claude).
21
+ */
22
+ export function findDesktopDataDirs(explicit) {
23
+ const candidates = [];
24
+ if (explicit)
25
+ candidates.push(explicit);
26
+ else if (process.env.HARNERY_CLAUDE_DESKTOP_DIR) {
27
+ candidates.push(process.env.HARNERY_CLAUDE_DESKTOP_DIR);
28
+ }
29
+ else {
30
+ const home = homedir();
31
+ if (process.platform === "darwin") {
32
+ candidates.push(join(home, "Library", "Application Support", "Claude"));
33
+ }
34
+ else if (process.platform === "win32") {
35
+ if (process.env.APPDATA)
36
+ candidates.push(join(process.env.APPDATA, "Claude"));
37
+ candidates.push(join(home, "AppData", "Roaming", "Claude"));
38
+ }
39
+ else {
40
+ candidates.push(join(home, ".config", "Claude"));
41
+ if (isWsl()) {
42
+ for (const usersRoot of ["/mnt/c/Users"]) {
43
+ if (!existsSync(usersRoot))
44
+ continue;
45
+ for (const user of safeReaddir(usersRoot)) {
46
+ candidates.push(join(usersRoot, user, "AppData", "Roaming", "Claude"));
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
52
+ const seen = new Set();
53
+ const out = [];
54
+ for (const dir of candidates) {
55
+ if (seen.has(dir))
56
+ continue;
57
+ seen.add(dir);
58
+ if (existsSync(join(dir, SESSIONS_DIRNAME)))
59
+ out.push(dir);
60
+ }
61
+ return out;
62
+ }
63
+ function safeReaddir(dir) {
64
+ try {
65
+ return readdirSync(dir);
66
+ }
67
+ catch {
68
+ return [];
69
+ }
70
+ }
71
+ function isDir(p) {
72
+ try {
73
+ return statSync(p).isDirectory();
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
79
+ function readEntry(file, accountUuid, envId) {
80
+ let raw;
81
+ try {
82
+ raw = JSON.parse(readFileSync(file, "utf8"));
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ if (typeof raw !== "object" || raw === null)
88
+ return null;
89
+ const d = raw;
90
+ const str = (k) => (typeof d[k] === "string" ? d[k] : null);
91
+ const num = (k) => (typeof d[k] === "number" ? d[k] : null);
92
+ return {
93
+ file,
94
+ accountUuid,
95
+ envId,
96
+ sessionId: str("sessionId"),
97
+ cliSessionId: str("cliSessionId"),
98
+ cwd: str("cwd"),
99
+ title: str("title"),
100
+ model: str("model"),
101
+ isArchived: d.isArchived === true,
102
+ createdAt: num("createdAt"),
103
+ lastActivityAt: num("lastActivityAt"),
104
+ };
105
+ }
106
+ /** Enumerate every account directory + its session entries under one data dir. */
107
+ export function listAccounts(dataDir) {
108
+ const root = join(dataDir, SESSIONS_DIRNAME);
109
+ const accounts = [];
110
+ for (const accountUuid of safeReaddir(root)) {
111
+ const accountPath = join(root, accountUuid);
112
+ if (!isDir(accountPath))
113
+ continue;
114
+ const entries = [];
115
+ for (const envId of safeReaddir(accountPath)) {
116
+ const envPath = join(accountPath, envId);
117
+ if (!isDir(envPath))
118
+ continue;
119
+ for (const f of safeReaddir(envPath)) {
120
+ if (!f.endsWith(".json"))
121
+ continue;
122
+ const entry = readEntry(join(envPath, f), accountUuid, envId);
123
+ if (entry)
124
+ entries.push(entry);
125
+ }
126
+ }
127
+ entries.sort((a, b) => (b.lastActivityAt ?? 0) - (a.lastActivityAt ?? 0));
128
+ accounts.push({ accountUuid, path: accountPath, entries });
129
+ }
130
+ accounts.sort((a, b) => (b.entries[0]?.lastActivityAt ?? 0) - (a.entries[0]?.lastActivityAt ?? 0) ||
131
+ a.accountUuid.localeCompare(b.accountUuid));
132
+ return accounts;
133
+ }
134
+ /**
135
+ * The account the runtime environment's Claude Code CLI is signed into,
136
+ * read from ~/.claude.json (best-effort; null when unavailable). Lets the
137
+ * command label an otherwise-opaque account UUID with an email address.
138
+ */
139
+ export function readCliAccount() {
140
+ try {
141
+ const raw = JSON.parse(readFileSync(join(homedir(), ".claude.json"), "utf8"));
142
+ const oa = raw.oauthAccount;
143
+ if (!oa || typeof oa.accountUuid !== "string")
144
+ return null;
145
+ return {
146
+ accountUuid: oa.accountUuid,
147
+ email: typeof oa.emailAddress === "string" ? oa.emailAddress : null,
148
+ };
149
+ }
150
+ catch {
151
+ return null;
152
+ }
153
+ }
154
+ export function entryMatchesSelector(entry, selector) {
155
+ if (entry.cliSessionId === selector || entry.sessionId === selector)
156
+ return true;
157
+ return entry.title !== null && entry.title.toLowerCase().includes(selector.toLowerCase());
158
+ }
159
+ /**
160
+ * Plan the copies that would make each target account list the selected
161
+ * sessions. Union semantics: every entry a source account has and a target
162
+ * account lacks (keyed by cliSessionId, falling back to filename) becomes a
163
+ * copy action. Idempotent by construction — planning again after applying
164
+ * yields zero actions.
165
+ */
166
+ export function planMirror(accounts, opts = {}) {
167
+ const matchPrefix = (uuid, prefixes) => !prefixes || prefixes.length === 0 || prefixes.some((p) => uuid.startsWith(p));
168
+ const targets = accounts.filter((a) => matchPrefix(a.accountUuid, opts.to));
169
+ const sources = accounts.filter((a) => matchPrefix(a.accountUuid, opts.from));
170
+ const actions = [];
171
+ let skippedExisting = 0;
172
+ let skippedArchived = 0;
173
+ for (const target of targets) {
174
+ const have = new Set();
175
+ for (const e of target.entries) {
176
+ if (e.cliSessionId)
177
+ have.add(e.cliSessionId);
178
+ have.add(basename(e.file));
179
+ }
180
+ for (const source of sources) {
181
+ if (source.accountUuid === target.accountUuid)
182
+ continue;
183
+ for (const entry of source.entries) {
184
+ if (opts.sessions?.length && !opts.sessions.some((s) => entryMatchesSelector(entry, s))) {
185
+ continue;
186
+ }
187
+ const key = entry.cliSessionId ?? basename(entry.file);
188
+ if (have.has(key) || have.has(basename(entry.file))) {
189
+ skippedExisting++;
190
+ continue;
191
+ }
192
+ if (entry.isArchived && !opts.includeArchived) {
193
+ skippedArchived++;
194
+ continue;
195
+ }
196
+ have.add(key);
197
+ actions.push({
198
+ from: entry.file,
199
+ to: join(target.path, entry.envId, basename(entry.file)),
200
+ entry,
201
+ targetAccountUuid: target.accountUuid,
202
+ });
203
+ }
204
+ }
205
+ }
206
+ return { actions, skippedExisting, skippedArchived };
207
+ }
208
+ /** Apply a plan: verbatim file copies (never rewrites entry contents). */
209
+ export function applyMirror(plan) {
210
+ let copied = 0;
211
+ for (const action of plan.actions) {
212
+ mkdirSync(dirname(action.to), { recursive: true });
213
+ copyFileSync(action.from, action.to);
214
+ copied++;
215
+ }
216
+ return { copied };
217
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"docs-lint.d.ts","sourceRoot":"","sources":["../../src/lib/docs-lint.ts"],"names":[],"mappings":"AAcA,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC,GAAG,IAAI,CAKP;AAaD;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3C,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAuHD,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMrD;AAsQD,wBAAsB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBlE"}
1
+ {"version":3,"file":"docs-lint.d.ts","sourceRoot":"","sources":["../../src/lib/docs-lint.ts"],"names":[],"mappings":"AAcA,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC,GAAG,IAAI,CAKP;AAaD;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3C,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA0HD,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMrD;AAsQD,wBAAsB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBlE"}
@@ -27,8 +27,10 @@ import { basename, join } from "node:path";
27
27
  /** Files allowed at a submodule root level. Includes:
28
28
  * - In-repo conventions: README.md, CLAUDE.md, LLM-BRIEFING.md, AGENTS.md
29
29
  * - GitHub OSS conventions: CHANGELOG.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md,
30
- * SECURITY.md, SUPPORT.md, AUTHORS.md, MAINTAINERS.md, PULL_REQUEST_TEMPLATE.md
31
- * (these are recognized by the GitHub UI, and renaming them breaks the integration)
30
+ * LICENSE.md, SECURITY.md, SUPPORT.md, AUTHORS.md, MAINTAINERS.md,
31
+ * PULL_REQUEST_TEMPLATE.md (these are recognized by the GitHub UI, and
32
+ * renaming them breaks the integration; LICENSE.md also appears inside
33
+ * vendored upstream trees, where renaming would damage provenance)
32
34
  */
33
35
  const ROOT_FILE_ALLOWLIST = new Set([
34
36
  "README.md",
@@ -39,6 +41,7 @@ const ROOT_FILE_ALLOWLIST = new Set([
39
41
  "CHANGELOG.md",
40
42
  "CONTRIBUTING.md",
41
43
  "CODE_OF_CONDUCT.md",
44
+ "LICENSE.md",
42
45
  "SECURITY.md",
43
46
  "SUPPORT.md",
44
47
  "AUTHORS.md",
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Bind a live session to a durable agent persona.
3
+ *
4
+ * The operation is serialized because "is this name live?" and "claim it"
5
+ * must be one critical section. Authoritative state is written twice on
6
+ * purpose: `.name-history` heals a missing heartbeat, while the canonical
7
+ * `identity.assumed` event makes replay and derived readers converge.
8
+ *
9
+ * Local collision policy: a fresh heartbeat alone is not enough to block.
10
+ * If the namesake has no live pid-map process (crashed session, healed
11
+ * zombie, or abandoned harness), reclaim that heartbeat and continue.
12
+ * Refuse only when another process is still alive, or when cached remote
13
+ * presence reports the name.
14
+ */
15
+ export type IdentityAssumeErrorCode = "identity_busy" | "identity_in_use" | "identity_not_found" | "invalid_identity" | "no_heartbeat" | "not_session" | "projection_failed";
16
+ export declare class IdentityAssumeError extends Error {
17
+ readonly code: IdentityAssumeErrorCode;
18
+ constructor(code: IdentityAssumeErrorCode, message: string);
19
+ }
20
+ export interface IdentityConflict {
21
+ instance_id: string;
22
+ name: string;
23
+ scope: "local" | "remote";
24
+ machine?: string;
25
+ }
26
+ export interface IdentityAssumeResult {
27
+ changed: boolean;
28
+ instance_id: string;
29
+ session_id: string;
30
+ previous_name: string | null;
31
+ previous_agent_id: string | null;
32
+ name: string;
33
+ agent_id: string;
34
+ identity_created: boolean;
35
+ event_id: string | null;
36
+ /** Prior local holder swept because it had no live process. */
37
+ reclaimed_instance_id: string | null;
38
+ }
39
+ /** Best-effort collision read across local heartbeats and cached remote
40
+ * presence. No network call occurs; absent presence degrades to local-only. */
41
+ export declare function findIdentityConflict(coordRoot: string, instanceId: string, name: string, nowMs?: number): IdentityConflict | null;
42
+ /**
43
+ * Drop a local namesake whose harness process is gone. Fresh heartbeats can
44
+ * linger after a crash (or after heartbeat heal without a live pid-map), and
45
+ * `identity assume` is the supported takeover path — operators should not
46
+ * need a separate kill/sweep step.
47
+ */
48
+ export declare function reclaimAbandonedLocalConflict(coordRoot: string, conflict: IdentityConflict): boolean;
49
+ /** Assume `target` for one live main session. Safe to retry. */
50
+ export declare function assumeIdentity(coordRoot: string, instanceId: string, target: string): IdentityAssumeResult;
51
+ //# sourceMappingURL=assume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assume.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/assume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA2BH,MAAM,MAAM,uBAAuB,GAC/B,eAAe,GACf,iBAAiB,GACjB,oBAAoB,GACpB,kBAAkB,GAClB,cAAc,GACd,aAAa,GACb,mBAAmB,CAAC;AAExB,qBAAa,mBAAoB,SAAQ,KAAK;aAE1B,IAAI,EAAE,uBAAuB;gBAA7B,IAAI,EAAE,uBAAuB,EAC7C,OAAO,EAAE,MAAM;CAKlB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+DAA+D;IAC/D,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAOD;+EAC+E;AAC/E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,SAAa,GACjB,gBAAgB,GAAG,IAAI,CAiCzB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CA2CT;AAyED,gEAAgE;AAChE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,oBAAoB,CAyGtB"}
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Bind a live session to a durable agent persona.
3
+ *
4
+ * The operation is serialized because "is this name live?" and "claim it"
5
+ * must be one critical section. Authoritative state is written twice on
6
+ * purpose: `.name-history` heals a missing heartbeat, while the canonical
7
+ * `identity.assumed` event makes replay and derived readers converge.
8
+ *
9
+ * Local collision policy: a fresh heartbeat alone is not enough to block.
10
+ * If the namesake has no live pid-map process (crashed session, healed
11
+ * zombie, or abandoned harness), reclaim that heartbeat and continue.
12
+ * Refuse only when another process is still alive, or when cached remote
13
+ * presence reports the name.
14
+ */
15
+ import { randomUUID } from "node:crypto";
16
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
17
+ import { join } from "node:path";
18
+ import { emitAndProject } from "../../core/agents/cli-emit.js";
19
+ import { emit } from "../../core/agents/events/emit.js";
20
+ import { readHeartbeat } from "../../core/agents/state/heartbeat-writer.js";
21
+ import { recordNameAssumption } from "../../core/agents/state/names.js";
22
+ import { instanceHasLivePid, removePidmapRowsForInstance } from "../../core/agents/state/pidmap.js";
23
+ import { coordFreshnessSeconds } from "../../core/config.js";
24
+ import { readRemoteMachines } from "../../core/presence/index.js";
25
+ import { bareName, ensureIdentity, lookupById, lookupByName } from "./index.js";
26
+ const ASSUME_LOCK = "identity-assume.lock";
27
+ const ASSUME_LOCK_STALE_MS = 30_000;
28
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
29
+ export class IdentityAssumeError extends Error {
30
+ code;
31
+ constructor(code, message) {
32
+ super(message);
33
+ this.code = code;
34
+ this.name = "IdentityAssumeError";
35
+ }
36
+ }
37
+ function heartbeatIsFresh(hb, cutoffMs) {
38
+ const ts = Date.parse(hb.last_heartbeat);
39
+ return Number.isFinite(ts) && ts >= cutoffMs;
40
+ }
41
+ /** Best-effort collision read across local heartbeats and cached remote
42
+ * presence. No network call occurs; absent presence degrades to local-only. */
43
+ export function findIdentityConflict(coordRoot, instanceId, name, nowMs = Date.now()) {
44
+ const wanted = name.toLowerCase();
45
+ const cutoffMs = nowMs - coordFreshnessSeconds(coordRoot) * 1000;
46
+ const activeDir = join(coordRoot, ".harnery", "active");
47
+ if (existsSync(activeDir)) {
48
+ for (const file of readdirSync(activeDir)) {
49
+ if (!file.endsWith(".json"))
50
+ continue;
51
+ try {
52
+ const hb = JSON.parse(readFileSync(join(activeDir, file), "utf8"));
53
+ if (hb.instance_id === instanceId || !heartbeatIsFresh(hb, cutoffMs))
54
+ continue;
55
+ if ((hb.name ?? "").toLowerCase() === wanted) {
56
+ return { instance_id: hb.instance_id, name: hb.name ?? name, scope: "local" };
57
+ }
58
+ }
59
+ catch {
60
+ // Malformed heartbeats are handled by stale sweep, not this command.
61
+ }
62
+ }
63
+ }
64
+ for (const remote of readRemoteMachines(coordRoot)) {
65
+ for (const agent of remote.agents) {
66
+ if (agent.instance_id === instanceId)
67
+ continue;
68
+ if ((agent.name ?? "").toLowerCase() === wanted) {
69
+ return {
70
+ instance_id: agent.instance_id,
71
+ name: agent.name ?? name,
72
+ scope: "remote",
73
+ machine: remote.machine,
74
+ };
75
+ }
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ /**
81
+ * Drop a local namesake whose harness process is gone. Fresh heartbeats can
82
+ * linger after a crash (or after heartbeat heal without a live pid-map), and
83
+ * `identity assume` is the supported takeover path — operators should not
84
+ * need a separate kill/sweep step.
85
+ */
86
+ export function reclaimAbandonedLocalConflict(coordRoot, conflict) {
87
+ if (conflict.scope !== "local")
88
+ return false;
89
+ if (instanceHasLivePid(coordRoot, conflict.instance_id))
90
+ return false;
91
+ const hbPath = join(coordRoot, ".harnery", "active", `${conflict.instance_id}.json`);
92
+ let harness = "claude-code";
93
+ let sessionId = conflict.instance_id;
94
+ let ageSecs;
95
+ if (existsSync(hbPath)) {
96
+ try {
97
+ const hb = JSON.parse(readFileSync(hbPath, "utf8"));
98
+ harness = harnessOf(hb.platform);
99
+ sessionId = hb.session_id || conflict.instance_id;
100
+ const ts = Date.parse(hb.last_heartbeat);
101
+ if (Number.isFinite(ts))
102
+ ageSecs = Math.max(0, Math.floor((Date.now() - ts) / 1000));
103
+ }
104
+ catch {
105
+ /* content unreadable — still reclaim the file */
106
+ }
107
+ try {
108
+ unlinkSync(hbPath);
109
+ }
110
+ catch {
111
+ return false;
112
+ }
113
+ }
114
+ removePidmapRowsForInstance(coordRoot, conflict.instance_id);
115
+ try {
116
+ emit(coordRoot, {
117
+ event_type: "health.heartbeat_swept",
118
+ instance_id: conflict.instance_id,
119
+ session_id: sessionId,
120
+ harness,
121
+ source: "agent-coord",
122
+ data: {
123
+ reason: "stale",
124
+ ...(ageSecs !== undefined ? { age_secs: ageSecs } : {}),
125
+ reclaimed_by: "identity.assume",
126
+ },
127
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
128
+ });
129
+ }
130
+ catch {
131
+ /* telemetry only */
132
+ }
133
+ return true;
134
+ }
135
+ function resolveTarget(coordRoot, input) {
136
+ const trimmed = input.trim();
137
+ if (!trimmed) {
138
+ throw new IdentityAssumeError("invalid_identity", "identity name cannot be empty");
139
+ }
140
+ if (UUID_RE.test(trimmed)) {
141
+ const identity = lookupById(trimmed, coordRoot);
142
+ if (!identity) {
143
+ throw new IdentityAssumeError("identity_not_found", `no durable identity matching '${trimmed}'`);
144
+ }
145
+ return { identity, name: identity.name };
146
+ }
147
+ const name = bareName(trimmed);
148
+ if (!name) {
149
+ throw new IdentityAssumeError("invalid_identity", "identity name cannot be empty");
150
+ }
151
+ const existing = lookupByName(name, coordRoot);
152
+ return { identity: existing, name: existing?.name ?? name };
153
+ }
154
+ function acquireLock(coordRoot) {
155
+ const dir = join(coordRoot, ".harnery");
156
+ const path = join(dir, ASSUME_LOCK);
157
+ mkdirSync(dir, { recursive: true });
158
+ const token = `${process.pid}:${randomUUID()}`;
159
+ for (let attempt = 0; attempt < 2; attempt++) {
160
+ try {
161
+ writeFileSync(path, token, { encoding: "utf8", flag: "wx" });
162
+ return () => {
163
+ try {
164
+ if (readFileSync(path, "utf8") === token)
165
+ unlinkSync(path);
166
+ }
167
+ catch {
168
+ // The critical section completed; a missing lock needs no recovery.
169
+ }
170
+ };
171
+ }
172
+ catch (error) {
173
+ if (error.code !== "EEXIST")
174
+ throw error;
175
+ try {
176
+ if (Date.now() - statSync(path).mtimeMs > ASSUME_LOCK_STALE_MS) {
177
+ unlinkSync(path);
178
+ continue;
179
+ }
180
+ }
181
+ catch {
182
+ continue;
183
+ }
184
+ break;
185
+ }
186
+ }
187
+ throw new IdentityAssumeError("identity_busy", "another identity assumption is in progress; retry in a moment");
188
+ }
189
+ function harnessOf(platform) {
190
+ if (platform === "cursor")
191
+ return "cursor";
192
+ if (platform === "codex")
193
+ return "codex";
194
+ return "claude-code";
195
+ }
196
+ /** Assume `target` for one live main session. Safe to retry. */
197
+ export function assumeIdentity(coordRoot, instanceId, target) {
198
+ const release = acquireLock(coordRoot);
199
+ try {
200
+ const hb = readHeartbeat(coordRoot, instanceId);
201
+ if (!hb) {
202
+ throw new IdentityAssumeError("no_heartbeat", `no live heartbeat for instance '${instanceId}'`);
203
+ }
204
+ if (hb.kind && hb.kind !== "session") {
205
+ throw new IdentityAssumeError("not_session", `identity assumption is limited to main sessions (current kind: ${hb.kind})`);
206
+ }
207
+ const targetIdentity = resolveTarget(coordRoot, target);
208
+ let reclaimedInstanceId = null;
209
+ let conflict = findIdentityConflict(coordRoot, instanceId, targetIdentity.name);
210
+ if (conflict && reclaimAbandonedLocalConflict(coordRoot, conflict)) {
211
+ reclaimedInstanceId = conflict.instance_id;
212
+ conflict = findIdentityConflict(coordRoot, instanceId, targetIdentity.name);
213
+ }
214
+ if (conflict) {
215
+ const where = conflict.scope === "remote" ? ` on ${conflict.machine}` : "";
216
+ throw new IdentityAssumeError("identity_in_use", `agent-${targetIdentity.name} is already live${where} (${conflict.instance_id}); end or stale-sweep that session before assuming the identity`);
217
+ }
218
+ const identity = targetIdentity.identity ?? ensureIdentity(targetIdentity.name, coordRoot);
219
+ const created = !targetIdentity.identity;
220
+ const previousName = hb.name || null;
221
+ const previousAgentId = hb.agent_id || null;
222
+ const history = recordNameAssumption(coordRoot, instanceId, identity.name, identity.agent_id, "session");
223
+ const changed = history.changed || previousName !== identity.name || previousAgentId !== identity.agent_id;
224
+ if (!changed) {
225
+ return {
226
+ changed: false,
227
+ instance_id: instanceId,
228
+ session_id: hb.session_id,
229
+ previous_name: previousName,
230
+ previous_agent_id: previousAgentId,
231
+ name: identity.name,
232
+ agent_id: identity.agent_id,
233
+ identity_created: false,
234
+ event_id: null,
235
+ reclaimed_instance_id: reclaimedInstanceId,
236
+ };
237
+ }
238
+ const emitted = emitAndProject({
239
+ event_type: "identity.assumed",
240
+ instance_id: instanceId,
241
+ session_id: hb.session_id,
242
+ harness: harnessOf(hb.platform),
243
+ data: {
244
+ name: identity.name,
245
+ agent_id: identity.agent_id,
246
+ ...(previousName ? { previous_name: previousName } : {}),
247
+ ...(previousAgentId ? { previous_agent_id: previousAgentId } : {}),
248
+ ...(reclaimedInstanceId ? { reclaimed_instance_id: reclaimedInstanceId } : {}),
249
+ },
250
+ }, { coordRoot });
251
+ if (!emitted?.projected) {
252
+ throw new IdentityAssumeError("projection_failed", "the durable name binding was recorded but event projection failed; rerun the command to heal it");
253
+ }
254
+ const projected = readHeartbeat(coordRoot, instanceId);
255
+ if (projected?.name !== identity.name || projected.agent_id !== identity.agent_id) {
256
+ throw new IdentityAssumeError("projection_failed", "identity.assumed was emitted but the heartbeat did not converge; rerun the command");
257
+ }
258
+ return {
259
+ changed: true,
260
+ instance_id: instanceId,
261
+ session_id: hb.session_id,
262
+ previous_name: previousName,
263
+ previous_agent_id: previousAgentId,
264
+ name: identity.name,
265
+ agent_id: identity.agent_id,
266
+ identity_created: created,
267
+ event_id: emitted.envelope.event_id,
268
+ reclaimed_instance_id: reclaimedInstanceId,
269
+ };
270
+ }
271
+ finally {
272
+ release();
273
+ }
274
+ }
@@ -39,12 +39,12 @@ export declare function bareName(raw: string): string;
39
39
  /** Re-add the "agent-" prefix for display contexts. */
40
40
  export declare function displayName(name: string): string;
41
41
  /** Read one identity by id. Null if missing. */
42
- export declare function lookupById(agentId: string): AgentIdentity | null;
42
+ export declare function lookupById(agentId: string, coordRoot?: string): AgentIdentity | null;
43
43
  /** Read one identity by display name (case-insensitive on bare name).
44
44
  * Scans the directory; O(N) on identity count. */
45
- export declare function lookupByName(name: string): AgentIdentity | null;
45
+ export declare function lookupByName(name: string, coordRoot?: string): AgentIdentity | null;
46
46
  /** All known identities, sorted by created_at ascending. */
47
- export declare function listIdentities(): AgentIdentity[];
47
+ export declare function listIdentities(coordRoot?: string): AgentIdentity[];
48
48
  /**
49
49
  * Find an identity by name, or mint one. Returns the resolved identity.
50
50
  * Idempotent: calling twice with the same name returns the same record.
@@ -55,15 +55,15 @@ export declare function listIdentities(): AgentIdentity[];
55
55
  * surface whichever happened to be read first; the second is orphaned.
56
56
  * For agent personas (added at human cadence) this race is theoretical.
57
57
  */
58
- export declare function ensureIdentity(name: string): AgentIdentity;
58
+ export declare function ensureIdentity(name: string, coordRoot?: string): AgentIdentity;
59
59
  /** Persist an identity (tmp + rename). Creates the dir if missing. */
60
- export declare function writeIdentity(id: AgentIdentity): void;
60
+ export declare function writeIdentity(id: AgentIdentity, coordRoot?: string): void;
61
61
  /**
62
62
  * Rename an existing identity. The prior name lands in aliases[] so name
63
63
  * lookup still resolves correctly. The agent_id is stable across renames,
64
64
  * which is the whole point of the registry.
65
65
  */
66
- export declare function renameIdentity(agentId: string, newName: string): AgentIdentity;
66
+ export declare function renameIdentity(agentId: string, newName: string, coordRoot?: string): AgentIdentity;
67
67
  /**
68
68
  * Resolve a string to an agent_id. Accepts:
69
69
  * - A UUID (already an id), verified to exist in registry
@@ -73,5 +73,5 @@ export declare function renameIdentity(agentId: string, newName: string): AgentI
73
73
  * Does NOT mint. Callers that want mint-on-miss should call ensureIdentity()
74
74
  * with a name, then use the returned agent_id.
75
75
  */
76
- export declare function resolveAgentId(input: string): string | null;
76
+ export declare function resolveAgentId(input: string, coordRoot?: string): string | null;
77
77
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAeH,eAAO,MAAM,uBAAuB,EAAG,CAAU,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAqCD,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAMhE;AAED;kDACkD;AAClD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAc/D;AAED,4DAA4D;AAC5D,wBAAgB,cAAc,IAAI,aAAa,EAAE,CAWhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAY1D;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CAMrD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAc9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/identities/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAeH,eAAO,MAAM,uBAAuB,EAAG,CAAU,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAqCD,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAMpF;AAED;kDACkD;AAClD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAcnF;AAED,4DAA4D;AAC5D,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAWlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAY9E;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAMzE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,aAAa,CAcf;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU/E"}