@rubytech/create-maxy-code 0.1.484 → 0.1.486

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 (92) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/docs/superpowers/plans/2026-07-21-graph-caption-resolver.md +124 -0
  3. package/payload/platform/docs/superpowers/plans/2026-07-21-task-1877-bash-schema-enforcement.md +107 -0
  4. package/payload/platform/docs/superpowers/plans/2026-07-21-task-1887-reconcile-allowed-top-level.md +205 -0
  5. package/payload/platform/lib/graph-style/dist/index.d.ts +4 -1
  6. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  7. package/payload/platform/lib/graph-style/dist/index.js +109 -1
  8. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  9. package/payload/platform/lib/graph-style/src/__tests__/caption-coverage.test.ts +117 -0
  10. package/payload/platform/lib/graph-style/src/index.ts +81 -1
  11. package/payload/platform/plugins/admin/hooks/__tests__/fs-schema-guard-bash.test.sh +159 -0
  12. package/payload/platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh +18 -6
  13. package/payload/platform/plugins/admin/hooks/fs-schema-guard-bash-post.sh +141 -0
  14. package/payload/platform/plugins/admin/hooks/fs-schema-guard-bash-pre.sh +66 -0
  15. package/payload/platform/plugins/admin/hooks/fs-schema-guard.sh +33 -1
  16. package/payload/platform/plugins/admin/skills/professional-document/SKILL.md +3 -3
  17. package/payload/platform/plugins/cloudflare/PLUGIN.md +2 -0
  18. package/payload/platform/plugins/cloudflare/bin/portal-enrol.mjs +23 -2
  19. package/payload/platform/plugins/cloudflare/mcp/__tests__/authorize.test.ts +2 -2
  20. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-directory-listing.test.ts +49 -2
  21. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-enrol.test.ts +57 -3
  22. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-indexed-download.test.ts +44 -2
  23. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-session-grant.test.ts +67 -0
  24. package/payload/platform/plugins/cloudflare/mcp/__tests__/template-config.test.ts +26 -0
  25. package/payload/platform/plugins/cloudflare/skills/data-portal/SKILL.md +42 -3
  26. package/payload/platform/plugins/cloudflare/skills/data-portal/schema.sql +10 -1
  27. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/session.ts +19 -5
  28. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/download.ts +19 -2
  29. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/files.ts +8 -2
  30. package/payload/platform/plugins/cloudflare/skills/data-portal/template/index.html +44 -13
  31. package/payload/platform/plugins/cloudflare/skills/data-portal/template/portal.css +220 -6
  32. package/payload/platform/plugins/cloudflare/skills/data-portal/template/portal.js +216 -17
  33. package/payload/platform/plugins/cloudflare/skills/data-portal/template/wrangler.toml +4 -3
  34. package/payload/platform/plugins/email/.claude-plugin/plugin.json +1 -1
  35. package/payload/platform/plugins/email/PLUGIN.md +5 -1
  36. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-select.test.d.ts +2 -0
  37. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-select.test.d.ts.map +1 -0
  38. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-select.test.js +50 -0
  39. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-select.test.js.map +1 -0
  40. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-text.test.d.ts +2 -0
  41. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-text.test.d.ts.map +1 -0
  42. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-text.test.js +51 -0
  43. package/payload/platform/plugins/email/mcp/dist/__tests__/attachment-text.test.js.map +1 -0
  44. package/payload/platform/plugins/email/mcp/dist/__tests__/email-fetch-attachment.test.d.ts +2 -0
  45. package/payload/platform/plugins/email/mcp/dist/__tests__/email-fetch-attachment.test.d.ts.map +1 -0
  46. package/payload/platform/plugins/email/mcp/dist/__tests__/email-fetch-attachment.test.js +89 -0
  47. package/payload/platform/plugins/email/mcp/dist/__tests__/email-fetch-attachment.test.js.map +1 -0
  48. package/payload/platform/plugins/email/mcp/dist/index.js +28 -0
  49. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  50. package/payload/platform/plugins/email/mcp/dist/lib/attachment-text.d.ts +22 -0
  51. package/payload/platform/plugins/email/mcp/dist/lib/attachment-text.d.ts.map +1 -0
  52. package/payload/platform/plugins/email/mcp/dist/lib/attachment-text.js +55 -0
  53. package/payload/platform/plugins/email/mcp/dist/lib/attachment-text.js.map +1 -0
  54. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +32 -0
  55. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
  56. package/payload/platform/plugins/email/mcp/dist/lib/imap.js +75 -1
  57. package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
  58. package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-attachment.d.ts +19 -0
  59. package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-attachment.d.ts.map +1 -0
  60. package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-attachment.js +49 -0
  61. package/payload/platform/plugins/email/mcp/dist/tools/email-fetch-attachment.js.map +1 -0
  62. package/payload/platform/plugins/email/references/email-reference.md +7 -1
  63. package/payload/platform/plugins/memory/references/schema-construction.md +18 -12
  64. package/payload/platform/plugins/memory/references/schema-estate-agent.md +11 -6
  65. package/payload/platform/scripts/__tests__/account-schema-owned-dirs.test.sh +75 -6
  66. package/payload/platform/scripts/lib/account-schema-owned-dirs.py +111 -22
  67. package/payload/platform/scripts/lib/provision-account-dir.sh +8 -1
  68. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts +39 -0
  69. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map +1 -0
  70. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js +299 -0
  71. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map +1 -0
  72. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  73. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  74. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  75. package/payload/platform/services/claude-session-manager/dist/index.js +15 -0
  76. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  77. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  78. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +4 -0
  79. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  80. package/payload/platform/templates/account-schema/SCHEMA.md +17 -0
  81. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  82. package/payload/server/{chunk-XGNRSM57.js → chunk-HN4HFTXE.js} +6 -0
  83. package/payload/server/maxy-edge.js +1 -1
  84. package/payload/server/public/assets/{admin-rScqRq-R.js → admin-BoVCP4Mw.js} +1 -1
  85. package/payload/server/public/assets/{data-TOWuhMFb.js → data-CtOxa94P.js} +1 -1
  86. package/payload/server/public/assets/{graph-labels-Axa04w8A.js → graph-labels-C8-sIKuv.js} +1 -1
  87. package/payload/server/public/assets/{graph-BEGs_P2m.js → graph-mJ9ky5dc.js} +1 -1
  88. package/payload/server/public/assets/{page-6CZ8R57f.js → page-Cv0qUwMG.js} +1 -1
  89. package/payload/server/public/data.html +3 -3
  90. package/payload/server/public/graph.html +2 -2
  91. package/payload/server/public/index.html +3 -3
  92. package/payload/server/server.js +125 -34
@@ -24,9 +24,35 @@ MARK_END = "<!-- plugin-owned-dirs:end -->"
24
24
  ONT_START = "<!-- ontology-buckets:start -->"
25
25
  ONT_END = "<!-- ontology-buckets:end -->"
26
26
 
27
+ # Base top-level names shipped in the account template plus `.quarantine`. This
28
+ # set is prune-protection only: a reconcile never *adds* a missing seed entry,
29
+ # it only shields a listed base dir from being flagged stale. Source (verbatim):
30
+ # docs/superpowers/plans/2026-06-23-account-filesystem-schema.md allowed-top-level.
31
+ FIXED_SEED = frozenset({
32
+ "projects", "contacts", "documents", "url-get", "output", "generated",
33
+ "extracted", "uploads", "agents", "specialists", "sites", "public",
34
+ "cache", "secrets", "state", "logs", "tmp", "SCHEMA.md", "account.json",
35
+ "AGENTS.md", ".claude", ".git", ".quarantine",
36
+ })
37
+
27
38
  LABEL_DIR_OVERRIDES = {"Site": "customer-sites"}
28
39
 
29
40
 
41
+ def _dir_holds_files(account_dir, name):
42
+ """True iff account_dir/<name> carries file content: a non-empty regular
43
+ file, or a directory whose subtree contains at least one regular file.
44
+ Absent path, empty dir, or a dir tree with no files -> False (prunable)."""
45
+ path = os.path.join(account_dir, name)
46
+ if not os.path.exists(path):
47
+ return False
48
+ if os.path.isfile(path):
49
+ return os.path.getsize(path) > 0
50
+ for _root, _dirs, files in os.walk(path):
51
+ if files:
52
+ return True
53
+ return False
54
+
55
+
30
56
  def _label_to_dir(label):
31
57
  """Map a Neo4j label to its file-schema bucket dir: kebab-case-plural,
32
58
  lowercased. camelCase word boundaries split on case. One override:
@@ -147,11 +173,14 @@ def resolve(project_dir):
147
173
 
148
174
 
149
175
  def _top_level_labels(schema_path):
150
- """Extract operator-entry labels from the entity table under the
176
+ """Extract (label, owner) rows from the entity table under the
151
177
  '## Top-level node types' heading of a vertical schema file. A row is
152
178
  included iff its 'Schema.org Type' cell is a schema:-namespaced type
153
- (excludes transport labels such as WhatsAppGroup -> cdm:Channel). Returns
154
- labels in table order. No such heading -> empty list."""
179
+ (excludes transport labels such as WhatsAppGroup -> cdm:Channel). `owner`
180
+ is the containment parent from the 'Owner' column: None when the table has
181
+ no Owner column, '' when the column is present but the cell is blank (a root
182
+ entity), else the parent label (a contained entity). Returns rows in table
183
+ order. No such heading -> empty list."""
155
184
  try:
156
185
  with open(schema_path) as f:
157
186
  lines = f.read().split("\n")
@@ -176,6 +205,8 @@ def _top_level_labels(schema_path):
176
205
  cols = [c.strip() for c in lines[hdr].strip().strip("|").split("|")]
177
206
  label_i = cols.index("Neo4j Label")
178
207
  type_i = cols.index("Schema.org Type")
208
+ owner_i = cols.index("Owner") if "Owner" in cols else None
209
+ need = max(label_i, type_i, owner_i if owner_i is not None else 0)
179
210
  out = []
180
211
  for k in range(hdr + 2, len(lines)): # +2 skips the header separator row
181
212
  row = lines[k]
@@ -184,19 +215,24 @@ def _top_level_labels(schema_path):
184
215
  if "|" not in row or not row.strip():
185
216
  break
186
217
  cells = [c.strip() for c in row.strip().strip("|").split("|")]
187
- if len(cells) <= max(label_i, type_i):
218
+ if len(cells) <= need:
188
219
  continue
189
220
  label = cells[label_i].strip("`").strip()
190
221
  stype = cells[type_i].strip("`").strip()
191
- if label and stype.startswith("schema:"):
192
- out.append(label)
222
+ if not (label and stype.startswith("schema:")):
223
+ continue
224
+ owner = None if owner_i is None else cells[owner_i].strip("`").strip()
225
+ out.append((label, owner))
193
226
  return out
194
227
 
195
228
 
196
229
  def resolve_domain_buckets(project_dir):
197
230
  """Domain operator-entity buckets derived from the brand's vertical
198
- ontology. Returns [{dir, label}] in table order, deduped by dir. Empty when
199
- the brand declares no vertical or the vertical file has no top-level
231
+ ontology. Returns [{dir, label, owner}] in table order, deduped by dir.
232
+ `owner` is None (the vertical table has no Owner column), '' (a root entity
233
+ that owns a top-level bucket), or the parent label (a contained entity that
234
+ gets no root bucket, its records living under the parent's folder). Empty
235
+ when the brand declares no vertical or the vertical file has no top-level
200
236
  section."""
201
237
  vertical = _read_vertical(project_dir)
202
238
  if not vertical:
@@ -204,15 +240,22 @@ def resolve_domain_buckets(project_dir):
204
240
  schema_path = os.path.join(project_dir, "plugins", "memory", "references", vertical + ".md")
205
241
  seen = set()
206
242
  out = []
207
- for label in _top_level_labels(schema_path):
243
+ for label, owner in _top_level_labels(schema_path):
208
244
  d = _label_to_dir(label)
209
245
  if d in seen:
210
246
  continue
211
247
  seen.add(d)
212
- out.append({"dir": d, "label": label})
248
+ out.append({"dir": d, "label": label, "owner": owner})
213
249
  return out
214
250
 
215
251
 
252
+ def _is_root(owner):
253
+ """A domain bucket is a root (own top-level dir) when its Owner is blank
254
+ ('') or the vertical declares no Owner column at all (None). A non-empty
255
+ owner names the containing parent, so the entity nests and emits no root."""
256
+ return owner is None or owner == ""
257
+
258
+
216
259
  def _allowed_block(text):
217
260
  """Return (list_of_entries, start_idx, end_idx) for the fenced
218
261
  allowed-top-level block. end_idx is the closing-fence line index."""
@@ -246,28 +289,49 @@ def merge(project_dir, account_dir):
246
289
  domain = resolve_domain_buckets(project_dir)
247
290
  schema_path = os.path.join(account_dir, "SCHEMA.md")
248
291
  if not os.path.isfile(schema_path):
249
- print(f"brand={brand} added=none domainBuckets=none")
292
+ print(f"brand={brand} added=none domainBuckets=none removed=none keptPopulated=none")
250
293
  return
251
294
  with open(schema_path) as f:
252
295
  text = f.read()
253
296
  entries, start, end = _allowed_block(text)
254
297
  added = []
255
298
  added_domain = []
299
+ removed = []
300
+ kept_populated = []
256
301
  if entries is not None:
257
302
  present = set(entries)
258
- lines = text.split("\n")
303
+ # Only ROOT domain buckets belong at the account root; a contained
304
+ # entity (non-blank Owner) nests under its owner and is not a target,
305
+ # so a pre-fix account's empty owned bucket prunes while a populated one
306
+ # is kept-and-logged like any other stale bucket.
307
+ target = FIXED_SEED | {e["dir"] for e in owned} | {b["dir"] for b in domain if _is_root(b["owner"])}
308
+ # Reconcile existing entries: keep in-target; keep populated strays
309
+ # (logged); drop empty/absent strays (logged).
310
+ new_entries = []
311
+ for entry in entries:
312
+ if entry in target:
313
+ new_entries.append(entry)
314
+ elif _dir_holds_files(account_dir, entry):
315
+ new_entries.append(entry)
316
+ kept_populated.append(entry)
317
+ else:
318
+ removed.append(entry)
319
+ # Append newly-projected owned then domain dirs not already present.
259
320
  insert = []
260
321
  for e in owned:
261
322
  if e["dir"] not in present and e["dir"] not in insert:
262
323
  insert.append(e["dir"])
263
324
  added.append(e["dir"])
264
325
  for b in domain:
326
+ if not _is_root(b["owner"]):
327
+ continue # contained entity: no root bucket, nests under its owner
265
328
  if b["dir"] not in present and b["dir"] not in insert:
266
329
  insert.append(b["dir"])
267
330
  added_domain.append(b["dir"])
268
- if insert:
269
- lines[end:end] = insert
270
- text = "\n".join(lines)
331
+ new_entries.extend(insert)
332
+ lines = text.split("\n")
333
+ lines[start + 1:end] = new_entries
334
+ text = "\n".join(lines)
271
335
  # Regenerate both descriptive regions wholesale (idempotent).
272
336
  text = _strip_region(text, MARK_START, MARK_END)
273
337
  text = _strip_region(text, ONT_START, ONT_END)
@@ -284,20 +348,33 @@ def merge(project_dir, account_dir):
284
348
  owned_dirs = {e["dir"] for e in owned}
285
349
  # A dir already claimed by a plugin (described in the plugin-owned region)
286
350
  # is not also described here, so a name collision cannot double-describe.
287
- domain_region = [b for b in domain if b["dir"] not in owned_dirs]
288
- if domain_region:
351
+ described = [b for b in domain if b["dir"] not in owned_dirs]
352
+ root_described = [b for b in described if _is_root(b["owner"])]
353
+ nested_described = [b for b in described if not _is_root(b["owner"])]
354
+ if root_described or nested_described:
289
355
  region = [ONT_START, "## Domain entity buckets (from the graph ontology)", "",
290
356
  "One bucket per top-level operator-entry node type of this brand's",
291
357
  "business ontology. File a job's artifacts under its entity folder;",
292
- "the folder may hold a subtree.", ""]
293
- for b in domain_region:
358
+ "the folder may hold a subtree. A contained entity has no root",
359
+ "bucket; its records live under the owning entity's folder.", ""]
360
+ for b in root_described:
294
361
  region.append(f"- `{b['dir']}/` - one folder per {b['label']} record.")
362
+ for b in nested_described:
363
+ parent_dir = _label_to_dir(b["owner"])
364
+ region.append(f"- `{b['label']}` records live under `{parent_dir}/` "
365
+ f"(owned by `{b['owner']}`), not a root bucket.")
295
366
  region.append(ONT_END)
296
367
  text = text.rstrip("\n") + "\n\n" + "\n".join(region) + "\n"
297
368
  with open(schema_path, "w") as f:
298
369
  f.write(text)
370
+ root_dirs = [b["dir"] for b in domain if _is_root(b["owner"])]
371
+ nested_pairs = [f"{b['label']}<-{b['owner']}" for b in domain if not _is_root(b["owner"])]
299
372
  print(f"brand={brand} added={','.join(added) if added else 'none'} "
300
- f"domainBuckets={','.join(added_domain) if added_domain else 'none'}")
373
+ f"domainBuckets={','.join(added_domain) if added_domain else 'none'} "
374
+ f"removed={','.join(removed) if removed else 'none'} "
375
+ f"keptPopulated={','.join(kept_populated) if kept_populated else 'none'} "
376
+ f"roots={','.join(root_dirs) if root_dirs else 'none'} "
377
+ f"nested={','.join(nested_pairs) if nested_pairs else 'none'}")
301
378
 
302
379
 
303
380
  def reconcile(project_dir, account_dir):
@@ -316,9 +393,21 @@ def reconcile(project_dir, account_dir):
316
393
  domain = resolve_domain_buckets(project_dir)
317
394
  if vertical and not domain:
318
395
  print(f"brand={brand} ontologyVertical={vertical} topLevelSection=absent")
396
+ # A vertical whose top-level table carries no Owner column cannot state
397
+ # containment; every entity falls back to root, but loudly, never silently.
398
+ if vertical and any(b["owner"] is None for b in domain):
399
+ print(f"brand={brand} ontologyVertical={vertical} owner-source=absent")
319
400
  for b in domain:
320
- is_present = "true" if b["dir"] in present else "false"
321
- print(f"brand={brand} ontologyEntity={b['label']} bucket={b['dir']} present={is_present}")
401
+ if _is_root(b["owner"]):
402
+ is_present = "true" if b["dir"] in present else "false"
403
+ print(f"brand={brand} ontologyEntity={b['label']} bucket={b['dir']} present={is_present}")
404
+ else:
405
+ # Contained entity: no root bucket expected. A bucket still listed at
406
+ # root is a pre-fix stray the standing fs-reconcile quarantines once
407
+ # the owned bucket leaves the allowed set (unless it holds files).
408
+ is_stray = "true" if b["dir"] in present else "false"
409
+ print(f"brand={brand} ontologyEntity={b['label']} owner={b['owner']} "
410
+ f"bucket={b['dir']} expectedAtRoot=false stray={is_stray}")
322
411
 
323
412
 
324
413
  def main():
@@ -86,7 +86,8 @@ provision_account_dir() {
86
86
  {
87
87
  "matcher": "Bash",
88
88
  "hooks": [
89
- { "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" }
89
+ { "type": "command", "command": "bash $HOOKS_PATH/archive-ingest-surface-gate.sh" },
90
+ { "type": "command", "command": "bash $HOOKS_PATH/fs-schema-guard-bash-pre.sh" }
90
91
  ]
91
92
  },
92
93
  {
@@ -115,6 +116,12 @@ provision_account_dir() {
115
116
  }
116
117
  ],
117
118
  "PostToolUse": [
119
+ {
120
+ "matcher": "Bash",
121
+ "hooks": [
122
+ { "type": "command", "command": "bash $HOOKS_PATH/fs-schema-guard-bash-post.sh" }
123
+ ]
124
+ },
118
125
  {
119
126
  "matcher": "Agent",
120
127
  "hooks": [
@@ -0,0 +1,39 @@
1
+ export interface ReconcileCounts {
2
+ strayTopLevel: number;
3
+ overDeep: number;
4
+ quarantined: number;
5
+ badName: number;
6
+ }
7
+ /** The single per-run summary line body. A non-zero count is the standing signal
8
+ * that an agent authored folders the hard guards could not prevent. Pure
9
+ * formatter so the emitter and its test share one wording. */
10
+ export declare function formatReconcileLine(c: ReconcileCounts): string;
11
+ /** Parse the fenced ```allowed-top-level block from an account's SCHEMA.md —
12
+ * the same structured set fs-schema-guard.sh parses with awk. Returns the
13
+ * entry names (blank lines dropped). An absent block yields an empty set. */
14
+ export declare function parseAllowedTopLevel(schemaText: string): Set<string>;
15
+ /** Reconcile one account dir. Reads its SCHEMA.md allowed set; an absent/empty
16
+ * set skips the account (fail open, like the hook — an un-seeded legacy account
17
+ * must not have its whole root quarantined). Moves stray top-level entries to
18
+ * .quarantine/ with a manifest line; counts over-deep files without moving. */
19
+ export declare function reconcileAccount(accountDir: string, now: () => number): ReconcileCounts;
20
+ export interface ReconcileDeps {
21
+ accountsRoot: string;
22
+ logger: (line: string) => void;
23
+ now?: () => number;
24
+ }
25
+ /** One reconcile pass over every account under the accounts root, then emit the
26
+ * single summary line. An account is any child dir with an account.json (the
27
+ * account marker the census uses). Per-account errors are swallowed so one bad
28
+ * account never aborts the run. */
29
+ export declare function runReconcile(deps: ReconcileDeps): void;
30
+ export interface AccountDirSchemaReconcile {
31
+ start(): void;
32
+ stop(): void;
33
+ }
34
+ /** Standing periodic reconcile. Unref'd interval so it never holds the process
35
+ * open; each tick re-runs the pass best-effort. */
36
+ export declare function createAccountDirSchemaReconcile(deps: ReconcileDeps & {
37
+ intervalMs: number;
38
+ }): AccountDirSchemaReconcile;
39
+ //# sourceMappingURL=account-dir-schema-reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-dir-schema-reconcile.d.ts","sourceRoot":"","sources":["../src/account-dir-schema-reconcile.ts"],"names":[],"mappings":"AA2EA,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;+DAE+D;AAC/D,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAE9D;AAED;;8EAE8E;AAC9E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAcpE;AA0FD;;;gFAGgF;AAChF,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,MAAM,GAAG,eAAe,CAwDvF;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;oCAGoC;AACpC,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAwBtD;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;CACb;AAED;oDACoD;AACpD,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,aAAa,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAC3C,yBAAyB,CAiB3B"}
@@ -0,0 +1,299 @@
1
+ // Task 1877 — standing account-dir schema reconcile. The Write/Edit/NotebookEdit
2
+ // path guard (fs-schema-guard.sh) never sees Bash, and the immediate Bash hooks
3
+ // (fs-schema-guard-bash-{pre,post}.sh) only catch strays a live command newly
4
+ // creates — neither can retroactively catch the backlog an agent authored before
5
+ // the hooks existed, nor a stray the agent ignored. Folder creation through Bash
6
+ // is a no-event failure: nothing emits a signal, and re-running the code does not
7
+ // surface it. This periodic audit is that signal.
8
+ //
9
+ // Per account, per run it detects (a) stray top-level entries — any account-root
10
+ // entry not in that account's allowed-top-level set — (b) over-deep files under
11
+ // the flat operator-data buckets, mirroring fs-schema-guard.sh's own depth rule
12
+ // exactly (projects/contacts/documents cap at 3 path segments; every other
13
+ // tool-owned bucket is unbounded and not walked), and (c) bad-named folders and
14
+ // files under those same buckets, mirroring the guard's name convention. Stray
15
+ // top-level entries are QUARANTINED (moved to <account>/.quarantine/ with a
16
+ // manifest recording the original path, reason, and quarantine path so the move
17
+ // is auditable and reversible); over-deep files and bad names are counted only.
18
+ // Nothing is deleted, nothing is silently rewritten, and re-filing quarantined
19
+ // content or renaming a bad name to its schema-correct home is the data-manager
20
+ // specialist's job on dispatch, not this pass.
21
+ //
22
+ // Shape mirrors the standing-audit family (rootless-client-audit.ts): a pure
23
+ // formatter (unit-tested) + an impure per-account collector + a start/stop
24
+ // factory whose setInterval is unref'd. Purely filesystem — no Neo4j, no graph
25
+ // writes, no deletes. Best-effort by construction: a per-account error is caught
26
+ // so one bad account never aborts the run.
27
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, appendFileSync, statSync, } from 'node:fs';
28
+ import { join, relative, sep } from 'node:path';
29
+ const TAG = '[fs-reconcile]';
30
+ const QUARANTINE_DIR = '.quarantine';
31
+ /** Platform control-plane entries the reconcile NEVER quarantines, regardless of
32
+ * what an account's SCHEMA.md allowed set says. provision-account-dir.sh makes
33
+ * the account dir a git root (`.git`) and writes its hook-enforcement settings
34
+ * into `.claude/`, and the account's identity lives in account.json; moving any
35
+ * of these into .quarantine would brick the account (lost git root, disabled
36
+ * hooks, unresolvable identity). SCHEMA.md is refreshed on every provision, but
37
+ * an account carrying a stale/older-template/hand-edited schema whose allowed
38
+ * block omits one of these must not have it moved. This is a fail-SAFE belt on
39
+ * the control plane, the mirror of the guard's fail-OPEN on a missing schema —
40
+ * operator strays are still quarantined; the account's own machinery is not. */
41
+ const PROTECTED_TOP_LEVEL = new Set([
42
+ '.git',
43
+ '.claude',
44
+ QUARANTINE_DIR,
45
+ 'SCHEMA.md',
46
+ 'account.json',
47
+ 'AGENTS.md',
48
+ ]);
49
+ /** Buckets whose depth fs-schema-guard.sh checks, with the same 3-segment cap.
50
+ * Every other top-level bucket is tool-owned and unbounded — not walked. This
51
+ * is the reuse of the guard's own `case` encoding the task calls for, not a
52
+ * re-derived list. */
53
+ const DEPTH_CHECKED_BUCKETS = ['projects', 'contacts', 'documents'];
54
+ const MAX_BUCKET_DEPTH = 3;
55
+ /** Operator-authored name convention (Task 1886), the same rule the write guard
56
+ * (fs-schema-guard.sh) applies at write time. Folders are lowercase letters,
57
+ * digits, and hyphens; files add lowercase dot-segments so a lowercase extension
58
+ * is allowed. Space-/case-/underscore-bearing names break shell paths, the
59
+ * data-portal URL minting, and case-sensitive matching. */
60
+ const FOLDER_NAME_RE = /^[a-z0-9-]+$/;
61
+ const FILE_NAME_RE = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
62
+ /** The single per-run summary line body. A non-zero count is the standing signal
63
+ * that an agent authored folders the hard guards could not prevent. Pure
64
+ * formatter so the emitter and its test share one wording. */
65
+ export function formatReconcileLine(c) {
66
+ return `${TAG} stray-top-level=${c.strayTopLevel} over-deep=${c.overDeep} quarantined=${c.quarantined} bad-name=${c.badName}`;
67
+ }
68
+ /** Parse the fenced ```allowed-top-level block from an account's SCHEMA.md —
69
+ * the same structured set fs-schema-guard.sh parses with awk. Returns the
70
+ * entry names (blank lines dropped). An absent block yields an empty set. */
71
+ export function parseAllowedTopLevel(schemaText) {
72
+ const lines = schemaText.split('\n');
73
+ const out = new Set();
74
+ let inBlock = false;
75
+ for (const line of lines) {
76
+ const t = line.trim();
77
+ if (!inBlock) {
78
+ if (t === '```allowed-top-level')
79
+ inBlock = true;
80
+ continue;
81
+ }
82
+ if (t === '```')
83
+ break;
84
+ if (t)
85
+ out.add(t);
86
+ }
87
+ return out;
88
+ }
89
+ /** Count regular files under a bucket whose account-relative path exceeds the
90
+ * segment cap. Mirrors fs-schema-guard.sh: `projects/Acme/a.txt` (3) is ok,
91
+ * `projects/Acme/deploy/a.txt` (4) is over-deep. Directories are not counted;
92
+ * the guard measures the write target (a file). */
93
+ function countOverDeepFiles(accountDir, bucket) {
94
+ const bucketRoot = join(accountDir, bucket);
95
+ if (!existsSync(bucketRoot))
96
+ return 0;
97
+ let count = 0;
98
+ const walk = (dir) => {
99
+ let entries;
100
+ try {
101
+ entries = readdirSync(dir);
102
+ }
103
+ catch {
104
+ return;
105
+ }
106
+ for (const name of entries) {
107
+ const full = join(dir, name);
108
+ let st;
109
+ try {
110
+ st = statSync(full);
111
+ }
112
+ catch {
113
+ continue;
114
+ }
115
+ if (st.isDirectory()) {
116
+ walk(full);
117
+ }
118
+ else if (st.isFile()) {
119
+ const rel = relative(accountDir, full);
120
+ const depth = rel.split(sep).length;
121
+ if (depth > MAX_BUCKET_DEPTH)
122
+ count++;
123
+ }
124
+ }
125
+ };
126
+ walk(bucketRoot);
127
+ return count;
128
+ }
129
+ /** Count entries under a bucket whose own basename breaks the name convention:
130
+ * directories against the folder rule, files against the file rule. Folders and
131
+ * files, at any depth under the operator-data buckets — the standing net for bad
132
+ * names the write guard could not prevent (Bash-authored, or predating the
133
+ * hook). Counted only, never renamed: rename is the data-manager's job, as with
134
+ * over-deep. A bad-named directory is counted and still descended, so a bad name
135
+ * nested inside it is also caught. */
136
+ function countBadNameEntries(accountDir, bucket) {
137
+ const bucketRoot = join(accountDir, bucket);
138
+ if (!existsSync(bucketRoot))
139
+ return 0;
140
+ let count = 0;
141
+ const walk = (dir) => {
142
+ let entries;
143
+ try {
144
+ entries = readdirSync(dir);
145
+ }
146
+ catch {
147
+ return;
148
+ }
149
+ for (const name of entries) {
150
+ // Dot-prefixed entries (.DS_Store, .gitkeep, ...) are skipped at every
151
+ // level system-wide; counting them would break the clean-run contract.
152
+ if (name.startsWith('.'))
153
+ continue;
154
+ const full = join(dir, name);
155
+ let st;
156
+ try {
157
+ st = statSync(full);
158
+ }
159
+ catch {
160
+ continue;
161
+ }
162
+ if (st.isDirectory()) {
163
+ if (!FOLDER_NAME_RE.test(name))
164
+ count++;
165
+ walk(full);
166
+ }
167
+ else if (st.isFile()) {
168
+ if (!FILE_NAME_RE.test(name))
169
+ count++;
170
+ }
171
+ }
172
+ };
173
+ walk(bucketRoot);
174
+ return count;
175
+ }
176
+ /** Pick a non-colliding destination name inside .quarantine for a stray. */
177
+ function quarantineDest(quarantineRoot, name) {
178
+ let candidate = join(quarantineRoot, name);
179
+ let n = 1;
180
+ while (existsSync(candidate)) {
181
+ candidate = join(quarantineRoot, `${name}.${n}`);
182
+ n++;
183
+ }
184
+ return candidate;
185
+ }
186
+ /** Reconcile one account dir. Reads its SCHEMA.md allowed set; an absent/empty
187
+ * set skips the account (fail open, like the hook — an un-seeded legacy account
188
+ * must not have its whole root quarantined). Moves stray top-level entries to
189
+ * .quarantine/ with a manifest line; counts over-deep files without moving. */
190
+ export function reconcileAccount(accountDir, now) {
191
+ const empty = { strayTopLevel: 0, overDeep: 0, quarantined: 0, badName: 0 };
192
+ const schemaPath = join(accountDir, 'SCHEMA.md');
193
+ if (!existsSync(schemaPath))
194
+ return empty;
195
+ let allowed;
196
+ try {
197
+ allowed = parseAllowedTopLevel(readFileSync(schemaPath, 'utf-8'));
198
+ }
199
+ catch {
200
+ return empty;
201
+ }
202
+ if (allowed.size === 0)
203
+ return empty;
204
+ let rootEntries;
205
+ try {
206
+ rootEntries = readdirSync(accountDir);
207
+ }
208
+ catch {
209
+ return empty;
210
+ }
211
+ const strays = rootEntries.filter((name) => !PROTECTED_TOP_LEVEL.has(name) && !allowed.has(name));
212
+ let quarantined = 0;
213
+ if (strays.length > 0) {
214
+ const quarantineRoot = join(accountDir, QUARANTINE_DIR);
215
+ const manifestPath = join(quarantineRoot, 'manifest.jsonl');
216
+ for (const name of strays) {
217
+ try {
218
+ mkdirSync(quarantineRoot, { recursive: true });
219
+ const dest = quarantineDest(quarantineRoot, name);
220
+ renameSync(join(accountDir, name), dest);
221
+ const record = {
222
+ name,
223
+ originalPath: name,
224
+ reason: 'top-level',
225
+ quarantinePath: relative(accountDir, dest),
226
+ movedAt: new Date(now()).toISOString(),
227
+ };
228
+ appendFileSync(manifestPath, JSON.stringify(record) + '\n');
229
+ quarantined++;
230
+ }
231
+ catch {
232
+ // Move failed (permissions, race). Counted as a detected stray below,
233
+ // not as quarantined — the summary line stays honest.
234
+ }
235
+ }
236
+ }
237
+ let overDeep = 0;
238
+ let badName = 0;
239
+ for (const bucket of DEPTH_CHECKED_BUCKETS) {
240
+ overDeep += countOverDeepFiles(accountDir, bucket);
241
+ badName += countBadNameEntries(accountDir, bucket);
242
+ }
243
+ return { strayTopLevel: strays.length, overDeep, quarantined, badName };
244
+ }
245
+ /** One reconcile pass over every account under the accounts root, then emit the
246
+ * single summary line. An account is any child dir with an account.json (the
247
+ * account marker the census uses). Per-account errors are swallowed so one bad
248
+ * account never aborts the run. */
249
+ export function runReconcile(deps) {
250
+ const now = deps.now ?? (() => Date.now());
251
+ const total = { strayTopLevel: 0, overDeep: 0, quarantined: 0, badName: 0 };
252
+ let entries;
253
+ try {
254
+ entries = readdirSync(deps.accountsRoot);
255
+ }
256
+ catch {
257
+ deps.logger(formatReconcileLine(total));
258
+ return;
259
+ }
260
+ for (const entry of entries) {
261
+ const accountDir = join(deps.accountsRoot, entry);
262
+ if (!existsSync(join(accountDir, 'account.json')))
263
+ continue;
264
+ try {
265
+ const c = reconcileAccount(accountDir, now);
266
+ total.strayTopLevel += c.strayTopLevel;
267
+ total.overDeep += c.overDeep;
268
+ total.quarantined += c.quarantined;
269
+ total.badName += c.badName;
270
+ }
271
+ catch {
272
+ // best-effort: skip an account that throws unexpectedly
273
+ }
274
+ }
275
+ deps.logger(formatReconcileLine(total));
276
+ }
277
+ /** Standing periodic reconcile. Unref'd interval so it never holds the process
278
+ * open; each tick re-runs the pass best-effort. */
279
+ export function createAccountDirSchemaReconcile(deps) {
280
+ let timer = null;
281
+ return {
282
+ start() {
283
+ if (timer)
284
+ return;
285
+ timer = setInterval(() => {
286
+ runReconcile(deps);
287
+ }, deps.intervalMs);
288
+ if (typeof timer.unref === 'function')
289
+ timer.unref();
290
+ },
291
+ stop() {
292
+ if (timer) {
293
+ clearInterval(timer);
294
+ timer = null;
295
+ }
296
+ },
297
+ };
298
+ }
299
+ //# sourceMappingURL=account-dir-schema-reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-dir-schema-reconcile.js","sourceRoot":"","sources":["../src/account-dir-schema-reconcile.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAyB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EA6TtD,CAAA"}
1
+ {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAyB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EA8TtD,CAAA"}
@@ -114,6 +114,7 @@ export const CANONICAL_MAXY_TOOL_NAMES = [
114
114
  "mcp__plugin_email_email__email-draft-edit",
115
115
  "mcp__plugin_email_email__email-draft-send",
116
116
  "mcp__plugin_email_email__email-fetch",
117
+ "mcp__plugin_email_email__email-fetch-attachment",
117
118
  "mcp__plugin_email_email__email-fetch-body",
118
119
  "mcp__plugin_email_email__email-graph-query",
119
120
  "mcp__plugin_email_email__email-ingest",
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,kEAAkE;AAClE,yDAAyD;AACzD,kFAAkF;AAClF,EAAE;AACF,yEAAyE;AACzE,6DAA6D;AAE7D,+EAA+E;AAC/E,MAAM,CAAC,MAAM,gBAAgB,GAAsB;IACjD,OAAO;IACP,KAAK;IACL,SAAS;IACT,WAAW;IACX,UAAU;IACV,OAAO;IACP,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,cAAc;IACd,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,gBAAgB;IAChB,UAAU;IACV,SAAS;IACT,cAAc;IACd,UAAU;IACV,MAAM;IACN,WAAW;CACZ,CAAA;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D,yCAAyC;IACzC,yCAAyC;IACzC,kDAAkD;IAClD,sDAAsD;IACtD,yCAAyC;IACzC,yCAAyC;IACzC,uCAAuC;IACvC,wCAAwC;IACxC,iDAAiD;IACjD,yCAAyC;IACzC,iDAAiD;IACjD,yCAAyC;IACzC,sCAAsC;IACtC,yCAAyC;IACzC,wCAAwC;IACxC,oCAAoC;IACpC,yCAAyC;IACzC,qCAAqC;IACrC,uCAAuC;IACvC,2CAA2C;IAC3C,4CAA4C;IAC5C,qCAAqC;IACrC,yCAAyC;IACzC,4CAA4C;IAC5C,0CAA0C;IAC1C,2CAA2C;IAC3C,oCAAoC;IACpC,sCAAsC;IACtC,0CAA0C;IAC1C,uCAAuC;IACvC,sCAAsC;IACtC,sDAAsD;IACtD,mDAAmD;IACnD,6CAA6C;IAC7C,wCAAwC;IACxC,yCAAyC;IACzC,qCAAqC;IACrC,uCAAuC;IACvC,sCAAsC;IACtC,wCAAwC;IACxC,+BAA+B;IAC/B,qCAAqC;IACrC,sCAAsC;IACtC,yCAAyC;IACzC,4CAA4C;IAC5C,uDAAuD;IACvD,+CAA+C;IAC/C,2CAA2C;IAC3C,gDAAgD;IAChD,oDAAoD;IACpD,4CAA4C;IAC5C,+CAA+C;IAC/C,+CAA+C;IAC/C,gDAAgD;IAChD,6CAA6C;IAC7C,6CAA6C;IAC7C,iDAAiD;IACjD,oDAAoD;IACpD,+CAA+C;IAC/C,2CAA2C;IAC3C,2CAA2C;IAC3C,+CAA+C;IAC/C,iDAAiD;IACjD,uDAAuD;IACvD,iDAAiD;IACjD,qDAAqD;IACrD,+CAA+C;IAC/C,+CAA+C;IAC/C,8CAA8C;IAC9C,+CAA+C;IAC/C,6CAA6C;IAC7C,+CAA+C;IAC/C,+CAA+C;IAC/C,6CAA6C;IAC7C,6CAA6C;IAC7C,uCAAuC;IACvC,sCAAsC;IACtC,2CAA2C;IAC3C,2CAA2C;IAC3C,sCAAsC;IACtC,2CAA2C;IAC3C,4CAA4C;IAC5C,uCAAuC;IACvC,4CAA4C;IAC5C,8CAA8C;IAC9C,qCAAqC;IACrC,sCAAsC;IACtC,uCAAuC;IACvC,qCAAqC;IACrC,sCAAsC;IACtC,uCAAuC;IACvC,8CAA8C;IAC9C,8CAA8C;IAC9C,8CAA8C;IAC9C,8CAA8C;IAC9C,8CAA8C;IAC9C,+CAA+C;IAC/C,gDAAgD;IAChD,gDAAgD;IAChD,oDAAoD;IACpD,yDAAyD;IACzD,2DAA2D;IAC3D,mDAAmD;IACnD,mDAAmD;IACnD,kDAAkD;IAClD,qDAAqD;IACrD,iDAAiD;IACjD,oDAAoD;IACpD,mDAAmD;IACnD,qDAAqD;IACrD,sDAAsD;IACtD,uDAAuD;IACvD,wDAAwD;IACxD,sDAAsD;IACtD,mDAAmD;IACnD,oDAAoD;IACpD,sDAAsD;IACtD,iEAAiE;IACjE,2DAA2D;IAC3D,yDAAyD;IACzD,yDAAyD;IACzD,sDAAsD;IACtD,uDAAuD;IACvD,yDAAyD;IACzD,sDAAsD;IACtD,uDAAuD;IACvD,2DAA2D;IAC3D,0DAA0D;IAC1D,wDAAwD;IACxD,qDAAqD;IACrD,sDAAsD;IACtD,gEAAgE;IAChE,qDAAqD;IACrD,oDAAoD;IACpD,iDAAiD;IACjD,kDAAkD;IAClD,wDAAwD;IACxD,oDAAoD;IACpD,wDAAwD;IACxD,wDAAwD;IACxD,qDAAqD;IACrD,uDAAuD;IACvD,sDAAsD;IACtD,mDAAmD;IACnD,oDAAoD;IACpD,qDAAqD;IACrD,kDAAkD;IAClD,mDAAmD;IACnD,qDAAqD;IACrD,0DAA0D;IAC1D,wDAAwD;IACxD,0DAA0D;IAC1D,sDAAsD;IACtD,sDAAsD;IACtD,sDAAsD;IACtD,mDAAmD;IACnD,8DAA8D;IAC9D,sDAAsD;IACtD,2CAA2C;IAC3C,+CAA+C;IAC/C,iDAAiD;IACjD,kDAAkD;IAClD,kDAAkD;IAClD,6CAA6C;IAC7C,6CAA6C;IAC7C,iEAAiE;IACjE,kEAAkE;IAClE,6DAA6D;IAC7D,8CAA8C;IAC9C,wDAAwD;IACxD,gDAAgD;IAChD,qDAAqD;IACrD,sDAAsD;IACtD,wDAAwD;IACxD,wCAAwC;IACxC,wCAAwC;IACxC,iDAAiD;IACjD,wDAAwD;IACxD,0DAA0D;IAC1D,0CAA0C;IAC1C,6CAA6C;IAC7C,wCAAwC;IACxC,mDAAmD;IACnD,+CAA+C;IAC/C,mDAAmD;IACnD,0CAA0C;IAC1C,kDAAkD;IAClD,8CAA8C;IAC9C,oDAAoD;IACpD,kDAAkD;IAClD,+CAA+C;IAC/C,mDAAmD;IACnD,2CAA2C;IAC3C,qDAAqD;IACrD,+CAA+C;IAC/C,sDAAsD;IACtD,gDAAgD;IAChD,2CAA2C;IAC3C,gDAAgD;IAChD,0CAA0C;IAC1C,0CAA0C;IAC1C,kDAAkD;IAClD,yCAAyC;IACzC,kDAAkD;IAClD,2CAA2C;IAC3C,yCAAyC;IACzC,2CAA2C;IAC3C,4CAA4C;IAC5C,mDAAmD;IACnD,uDAAuD;IACvD,4DAA4D;IAC5D,sDAAsD;IACtD,sDAAsD;IACtD,qDAAqD;IACrD,wDAAwD;IACxD,oDAAoD;IACpD,uDAAuD;IACvD,sDAAsD;IACtD,oDAAoD;IACpD,4CAA4C;IAC5C,iDAAiD;IACjD,iDAAiD;IACjD,sDAAsD;IACtD,kDAAkD;IAClD,sDAAsD;IACtD,gDAAgD;IAChD,uDAAuD;IACvD,iDAAiD;IACjD,kDAAkD;IAClD,gDAAgD;IAChD,mDAAmD;IACnD,mDAAmD;IACnD,6DAA6D;IAC7D,2DAA2D;IAC3D,2DAA2D;IAC3D,+DAA+D;IAC/D,+DAA+D;IAC/D,+DAA+D;IAC/D,0DAA0D;IAC1D,6DAA6D;IAC7D,6DAA6D;IAC7D,8DAA8D;IAC9D,8DAA8D;IAC9D,8DAA8D;IAC9D,qDAAqD;IACrD,sDAAsD;IACtD,2DAA2D;IAC3D,iDAAiD;IACjD,sDAAsD;IACtD,uDAAuD;IACvD,yDAAyD;IACzD,oDAAoD;IACpD,iEAAiE;IACjE,mDAAmD;IACnD,wDAAwD;IACxD,iDAAiD;IACjD,wDAAwD;IACxD,kDAAkD;IAClD,oDAAoD;IACpD,iDAAiD;IACjD,8DAA8D;IAC9D,4DAA4D;IAC5D,6DAA6D;IAC7D,gEAAgE;IAChE,iEAAiE;IACjE,iEAAiE;IACjE,qEAAqE;IACrE,mEAAmE;IACnE,qEAAqE;IACrE,kEAAkE;IAClE,mEAAmE;IACnE,kEAAkE;IAClE,wCAAwC;IACxC,gDAAgD;IAChD,0DAA0D;IAC1D,sCAAsC;IACtC,6DAA6D;IAC7D,kEAAkE;IAClE,8DAA8D;IAC9D,oEAAoE;IACpE,0DAA0D;IAC1D,kDAAkD;IAClD,gDAAgD;IAChD,kEAAkE;IAClE,uDAAuD;IACvD,oDAAoD;IACpD,oDAAoD;IACpD,qDAAqD;IACrD,oDAAoD;IACpD,kDAAkD;IAClD,+CAA+C;IAC/C,oDAAoD;IACpD,gDAAgD;IAChD,yCAAyC;IACzC,uCAAuC;IACvC,oCAAoC;IACpC,qCAAqC;IACrC,uCAAuC;IACvC,qCAAqC;IACrC,yCAAyC;IACzC,qCAAqC;IACrC,sCAAsC;IACtC,oCAAoC;IACpC,iCAAiC;IACjC,kCAAkC;IAClC,mCAAmC;IACnC,oCAAoC;IACpC,oCAAoC;IACpC,kDAAkD;IAClD,kDAAkD;IAClD,mDAAmD;IACnD,+CAA+C;IAC/C,gDAAgD;IAChD,gDAAgD;IAChD,kDAAkD;IAClD,oDAAoD;CACrD,CAAA"}
1
+ {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}