@anthropic-ai/sdk 0.118.0 → 0.120.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 (250) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/client.d.mts +8 -2
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +8 -2
  5. package/client.d.ts.map +1 -1
  6. package/client.js +6 -0
  7. package/client.js.map +1 -1
  8. package/client.mjs +6 -0
  9. package/client.mjs.map +1 -1
  10. package/helpers/beta/environments.d.mts +5 -4
  11. package/helpers/beta/environments.d.mts.map +1 -1
  12. package/helpers/beta/environments.d.ts +5 -4
  13. package/helpers/beta/environments.d.ts.map +1 -1
  14. package/helpers/beta/environments.js +5 -4
  15. package/helpers/beta/environments.js.map +1 -1
  16. package/helpers/beta/environments.mjs +5 -4
  17. package/helpers/beta/environments.mjs.map +1 -1
  18. package/internal/file-store.d.mts +136 -0
  19. package/internal/file-store.d.mts.map +1 -0
  20. package/internal/file-store.d.ts +136 -0
  21. package/internal/file-store.d.ts.map +1 -0
  22. package/internal/file-store.js +531 -0
  23. package/internal/file-store.js.map +1 -0
  24. package/internal/file-store.mjs +523 -0
  25. package/internal/file-store.mjs.map +1 -0
  26. package/lib/environments/poller.d.mts +6 -0
  27. package/lib/environments/poller.d.mts.map +1 -1
  28. package/lib/environments/poller.d.ts +6 -0
  29. package/lib/environments/poller.d.ts.map +1 -1
  30. package/lib/environments/poller.js +46 -1
  31. package/lib/environments/poller.js.map +1 -1
  32. package/lib/environments/poller.mjs +46 -1
  33. package/lib/environments/poller.mjs.map +1 -1
  34. package/lib/environments/worker.d.mts +89 -12
  35. package/lib/environments/worker.d.mts.map +1 -1
  36. package/lib/environments/worker.d.ts +89 -12
  37. package/lib/environments/worker.d.ts.map +1 -1
  38. package/lib/environments/worker.js +336 -67
  39. package/lib/environments/worker.js.map +1 -1
  40. package/lib/environments/worker.mjs +336 -68
  41. package/lib/environments/worker.mjs.map +1 -1
  42. package/lib/tools/BetaRunnableTool.d.mts +4 -1
  43. package/lib/tools/BetaRunnableTool.d.mts.map +1 -1
  44. package/lib/tools/BetaRunnableTool.d.ts +4 -1
  45. package/lib/tools/BetaRunnableTool.d.ts.map +1 -1
  46. package/lib/tools/BetaRunnableTool.js +7 -2
  47. package/lib/tools/BetaRunnableTool.js.map +1 -1
  48. package/lib/tools/BetaRunnableTool.mjs +7 -2
  49. package/lib/tools/BetaRunnableTool.mjs.map +1 -1
  50. package/lib/tools/BetaToolRunner.d.mts.map +1 -1
  51. package/lib/tools/BetaToolRunner.d.ts.map +1 -1
  52. package/lib/tools/BetaToolRunner.js +3 -1
  53. package/lib/tools/BetaToolRunner.js.map +1 -1
  54. package/lib/tools/BetaToolRunner.mjs +3 -1
  55. package/lib/tools/BetaToolRunner.mjs.map +1 -1
  56. package/package.json +1 -1
  57. package/resources/beta/agents/agents.d.mts +322 -27
  58. package/resources/beta/agents/agents.d.mts.map +1 -1
  59. package/resources/beta/agents/agents.d.ts +322 -27
  60. package/resources/beta/agents/agents.d.ts.map +1 -1
  61. package/resources/beta/agents/agents.js.map +1 -1
  62. package/resources/beta/agents/agents.mjs.map +1 -1
  63. package/resources/beta/agents/index.d.mts +1 -1
  64. package/resources/beta/agents/index.d.mts.map +1 -1
  65. package/resources/beta/agents/index.d.ts +1 -1
  66. package/resources/beta/agents/index.d.ts.map +1 -1
  67. package/resources/beta/agents/index.js.map +1 -1
  68. package/resources/beta/agents/index.mjs.map +1 -1
  69. package/resources/beta/beta.d.mts +6 -6
  70. package/resources/beta/beta.d.mts.map +1 -1
  71. package/resources/beta/beta.d.ts +6 -6
  72. package/resources/beta/beta.d.ts.map +1 -1
  73. package/resources/beta/beta.js.map +1 -1
  74. package/resources/beta/beta.mjs.map +1 -1
  75. package/resources/beta/environments/work.d.mts +5 -1
  76. package/resources/beta/environments/work.d.mts.map +1 -1
  77. package/resources/beta/environments/work.d.ts +5 -1
  78. package/resources/beta/environments/work.d.ts.map +1 -1
  79. package/resources/beta/environments/work.js +0 -17
  80. package/resources/beta/environments/work.js.map +1 -1
  81. package/resources/beta/environments/work.mjs +0 -17
  82. package/resources/beta/environments/work.mjs.map +1 -1
  83. package/resources/beta/files.d.mts +22 -22
  84. package/resources/beta/files.d.mts.map +1 -1
  85. package/resources/beta/files.d.ts +22 -22
  86. package/resources/beta/files.d.ts.map +1 -1
  87. package/resources/beta/files.js +4 -4
  88. package/resources/beta/files.js.map +1 -1
  89. package/resources/beta/files.mjs +4 -4
  90. package/resources/beta/files.mjs.map +1 -1
  91. package/resources/beta/index.d.mts +3 -3
  92. package/resources/beta/index.d.mts.map +1 -1
  93. package/resources/beta/index.d.ts +3 -3
  94. package/resources/beta/index.d.ts.map +1 -1
  95. package/resources/beta/index.js.map +1 -1
  96. package/resources/beta/index.mjs.map +1 -1
  97. package/resources/beta/messages/index.d.mts +1 -1
  98. package/resources/beta/messages/index.d.mts.map +1 -1
  99. package/resources/beta/messages/index.d.ts +1 -1
  100. package/resources/beta/messages/index.d.ts.map +1 -1
  101. package/resources/beta/messages/index.js.map +1 -1
  102. package/resources/beta/messages/index.mjs.map +1 -1
  103. package/resources/beta/messages/messages.d.mts +1202 -5
  104. package/resources/beta/messages/messages.d.mts.map +1 -1
  105. package/resources/beta/messages/messages.d.ts +1202 -5
  106. package/resources/beta/messages/messages.d.ts.map +1 -1
  107. package/resources/beta/messages/messages.js.map +1 -1
  108. package/resources/beta/messages/messages.mjs.map +1 -1
  109. package/resources/files.d.mts +105 -0
  110. package/resources/files.d.mts.map +1 -0
  111. package/resources/files.d.ts +105 -0
  112. package/resources/files.d.ts.map +1 -0
  113. package/resources/files.js +52 -0
  114. package/resources/files.js.map +1 -0
  115. package/resources/files.mjs +48 -0
  116. package/resources/files.mjs.map +1 -0
  117. package/resources/index.d.mts +3 -1
  118. package/resources/index.d.mts.map +1 -1
  119. package/resources/index.d.ts +3 -1
  120. package/resources/index.d.ts.map +1 -1
  121. package/resources/index.js +5 -1
  122. package/resources/index.js.map +1 -1
  123. package/resources/index.mjs +2 -0
  124. package/resources/index.mjs.map +1 -1
  125. package/resources/messages/index.d.mts +1 -1
  126. package/resources/messages/index.d.mts.map +1 -1
  127. package/resources/messages/index.d.ts +1 -1
  128. package/resources/messages/index.d.ts.map +1 -1
  129. package/resources/messages/index.js.map +1 -1
  130. package/resources/messages/index.mjs.map +1 -1
  131. package/resources/messages/messages.d.mts +1267 -7
  132. package/resources/messages/messages.d.mts.map +1 -1
  133. package/resources/messages/messages.d.ts +1267 -7
  134. package/resources/messages/messages.d.ts.map +1 -1
  135. package/resources/messages/messages.js.map +1 -1
  136. package/resources/messages/messages.mjs.map +1 -1
  137. package/resources/skills/index.d.mts +3 -0
  138. package/resources/skills/index.d.mts.map +1 -0
  139. package/resources/skills/index.d.ts +3 -0
  140. package/resources/skills/index.d.ts.map +1 -0
  141. package/resources/skills/index.js +9 -0
  142. package/resources/skills/index.js.map +1 -0
  143. package/resources/skills/index.mjs +4 -0
  144. package/resources/skills/index.mjs.map +1 -0
  145. package/resources/skills/skills.d.mts +129 -0
  146. package/resources/skills/skills.d.mts.map +1 -0
  147. package/resources/skills/skills.d.ts +129 -0
  148. package/resources/skills/skills.d.ts.map +1 -0
  149. package/resources/skills/skills.js +44 -0
  150. package/resources/skills/skills.js.map +1 -0
  151. package/resources/skills/skills.mjs +39 -0
  152. package/resources/skills/skills.mjs.map +1 -0
  153. package/resources/skills/versions.d.mts +104 -0
  154. package/resources/skills/versions.d.mts.map +1 -0
  155. package/resources/skills/versions.d.ts +104 -0
  156. package/resources/skills/versions.d.ts.map +1 -0
  157. package/resources/skills/versions.js +41 -0
  158. package/resources/skills/versions.js.map +1 -0
  159. package/resources/skills/versions.mjs +37 -0
  160. package/resources/skills/versions.mjs.map +1 -0
  161. package/resources/skills.d.mts +2 -0
  162. package/resources/skills.d.mts.map +1 -0
  163. package/resources/skills.d.ts +2 -0
  164. package/resources/skills.d.ts.map +1 -0
  165. package/resources/skills.js +6 -0
  166. package/resources/skills.js.map +1 -0
  167. package/resources/skills.mjs +3 -0
  168. package/resources/skills.mjs.map +1 -0
  169. package/src/client.ts +172 -0
  170. package/src/helpers/beta/environments.ts +5 -4
  171. package/src/internal/file-store.ts +550 -0
  172. package/src/lib/environments/poller.ts +47 -1
  173. package/src/lib/environments/worker.ts +419 -79
  174. package/src/lib/tools/BetaRunnableTool.ts +9 -2
  175. package/src/lib/tools/BetaToolRunner.ts +6 -1
  176. package/src/resources/beta/agents/agents.ts +435 -30
  177. package/src/resources/beta/agents/index.ts +17 -0
  178. package/src/resources/beta/beta.ts +160 -6
  179. package/src/resources/beta/environments/work.ts +7 -0
  180. package/src/resources/beta/files.ts +27 -27
  181. package/src/resources/beta/index.ts +80 -3
  182. package/src/resources/beta/messages/index.ts +60 -0
  183. package/src/resources/beta/messages/messages.ts +1865 -415
  184. package/src/resources/files.ts +163 -0
  185. package/src/resources/index.ts +83 -0
  186. package/src/resources/messages/index.ts +66 -0
  187. package/src/resources/messages/messages.ts +1648 -115
  188. package/src/resources/skills/index.ts +21 -0
  189. package/src/resources/skills/skills.ts +194 -0
  190. package/src/resources/skills/versions.ts +160 -0
  191. package/src/resources/skills.ts +3 -0
  192. package/src/tools/agent-toolset/fs-util.ts +40 -24
  193. package/src/tools/agent-toolset/memories.ts +1017 -0
  194. package/src/tools/agent-toolset/node.browser.ts +68 -0
  195. package/src/tools/agent-toolset/node.ts +139 -53
  196. package/src/tools/agent-toolset/skills.ts +29 -9
  197. package/src/tools/agent-toolset/sync-interval.ts +30 -0
  198. package/src/version.ts +1 -1
  199. package/tools/agent-toolset/fs-util.d.mts +23 -10
  200. package/tools/agent-toolset/fs-util.d.mts.map +1 -1
  201. package/tools/agent-toolset/fs-util.d.ts +23 -10
  202. package/tools/agent-toolset/fs-util.d.ts.map +1 -1
  203. package/tools/agent-toolset/fs-util.js +40 -25
  204. package/tools/agent-toolset/fs-util.js.map +1 -1
  205. package/tools/agent-toolset/fs-util.mjs +38 -25
  206. package/tools/agent-toolset/fs-util.mjs.map +1 -1
  207. package/tools/agent-toolset/memories.d.mts +173 -0
  208. package/tools/agent-toolset/memories.d.mts.map +1 -0
  209. package/tools/agent-toolset/memories.d.ts +173 -0
  210. package/tools/agent-toolset/memories.d.ts.map +1 -0
  211. package/tools/agent-toolset/memories.js +902 -0
  212. package/tools/agent-toolset/memories.js.map +1 -0
  213. package/tools/agent-toolset/memories.mjs +895 -0
  214. package/tools/agent-toolset/memories.mjs.map +1 -0
  215. package/tools/agent-toolset/node.browser.d.mts +31 -0
  216. package/tools/agent-toolset/node.browser.d.mts.map +1 -1
  217. package/tools/agent-toolset/node.browser.d.ts +31 -0
  218. package/tools/agent-toolset/node.browser.d.ts.map +1 -1
  219. package/tools/agent-toolset/node.browser.js +59 -1
  220. package/tools/agent-toolset/node.browser.js.map +1 -1
  221. package/tools/agent-toolset/node.browser.mjs +54 -0
  222. package/tools/agent-toolset/node.browser.mjs.map +1 -1
  223. package/tools/agent-toolset/node.d.mts +54 -22
  224. package/tools/agent-toolset/node.d.mts.map +1 -1
  225. package/tools/agent-toolset/node.d.ts +54 -22
  226. package/tools/agent-toolset/node.d.ts.map +1 -1
  227. package/tools/agent-toolset/node.js +83 -44
  228. package/tools/agent-toolset/node.js.map +1 -1
  229. package/tools/agent-toolset/node.mjs +77 -44
  230. package/tools/agent-toolset/node.mjs.map +1 -1
  231. package/tools/agent-toolset/skills.d.mts +16 -7
  232. package/tools/agent-toolset/skills.d.mts.map +1 -1
  233. package/tools/agent-toolset/skills.d.ts +16 -7
  234. package/tools/agent-toolset/skills.d.ts.map +1 -1
  235. package/tools/agent-toolset/skills.js +27 -9
  236. package/tools/agent-toolset/skills.js.map +1 -1
  237. package/tools/agent-toolset/skills.mjs +27 -9
  238. package/tools/agent-toolset/skills.mjs.map +1 -1
  239. package/tools/agent-toolset/sync-interval.d.mts +19 -0
  240. package/tools/agent-toolset/sync-interval.d.mts.map +1 -0
  241. package/tools/agent-toolset/sync-interval.d.ts +19 -0
  242. package/tools/agent-toolset/sync-interval.d.ts.map +1 -0
  243. package/tools/agent-toolset/sync-interval.js +29 -0
  244. package/tools/agent-toolset/sync-interval.js.map +1 -0
  245. package/tools/agent-toolset/sync-interval.mjs +25 -0
  246. package/tools/agent-toolset/sync-interval.mjs.map +1 -0
  247. package/version.d.mts +1 -1
  248. package/version.d.ts +1 -1
  249. package/version.js +1 -1
  250. package/version.mjs +1 -1
@@ -7,6 +7,8 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.FILE_CREATE_MODE = exports.DIR_CREATE_MODE = void 0;
10
+ exports.isWithin = isWithin;
11
+ exports.containingRoot = containingRoot;
10
12
  exports.errnoCode = errnoCode;
11
13
  exports.canonicalize = canonicalize;
12
14
  exports.confineToRoot = confineToRoot;
@@ -21,14 +23,25 @@ const ToolError_1 = require("../../lib/tools/ToolError.js");
21
23
  exports.DIR_CREATE_MODE = 0o755;
22
24
  /** Mode for files the file tools create. */
23
25
  exports.FILE_CREATE_MODE = 0o644;
24
- /** `realpath` `p`, or return `p` unchanged when it cannot be resolved. */
25
- async function realpathOrSelf(p) {
26
- try {
27
- return await fs.realpath(p);
28
- }
29
- catch {
30
- return p;
26
+ /** True when `p` is `root` itself or lexically contained within it. */
27
+ function isWithin(root, p) {
28
+ const rel = path.relative(root, p);
29
+ return rel === '' || (!rel.startsWith('..' + path.sep) && rel !== '..' && !path.isAbsolute(rel));
30
+ }
31
+ /**
32
+ * The first entry of `roots` whose canonical form contains the
33
+ * already-canonical `target`, returned as configured; `undefined` when none
34
+ * does. Each root goes through {@link canonicalize} at check time, exactly like
35
+ * the workdir in {@link confineToRoot}, so granting access (`allowedRoots`)
36
+ * and refusing writes (`readOnlyRoots`) can never resolve the same entry two
37
+ * different ways.
38
+ */
39
+ async function containingRoot(roots, target) {
40
+ for (const root of roots) {
41
+ if (isWithin(await canonicalize(path.resolve(root)), target))
42
+ return root;
31
43
  }
44
+ return undefined;
32
45
  }
33
46
  /** Matches Linux MAXSYMLINKS, the threshold at which `realpath` itself reports ELOOP. */
34
47
  const MAX_SYMLINK_HOPS = 40;
@@ -87,17 +100,19 @@ async function canonicalize(abs) {
87
100
  }
88
101
  }
89
102
  /**
90
- * Resolve `p` and confine it to `root`.
103
+ * Resolve `p` against `root` and confine it to `root` or one of `allowedRoots`
104
+ * (absolute paths, resolved at check time exactly like `root`).
91
105
  *
92
106
  * Absolute and relative inputs go through the same canonicalise-then-contain
93
- * check — an absolute path that lands inside `root` is permitted, only paths
94
- * that resolve *outside* are rejected. Every symlink in `p` (including the
95
- * leaf, even a dangling one) is resolved before the confinement check, and the
96
- * resolved path is what the caller then operates on, so a symlink inside `root`
97
- * that points outside it can neither pass the check nor be followed afterwards.
98
- * `..` is collapsed lexically before any symlink is followed. A path that cannot
99
- * be resolved (symlink loop, unreadable component) is rejected with a
100
- * `ToolError` naming `p`, never the host's absolute path.
107
+ * check — an absolute path that lands inside a permitted root is accepted,
108
+ * only paths that resolve *outside* all of them are rejected. Every symlink in
109
+ * `p` (including the leaf, even a dangling one) is resolved before the
110
+ * confinement check, and the resolved path is what the caller then operates
111
+ * on, so a symlink inside `root` that points outside it can neither pass the
112
+ * check nor be followed afterwards. `..` is collapsed lexically before any
113
+ * symlink is followed. A path that cannot be resolved (symlink loop, unreadable
114
+ * component) is rejected with a `ToolError` naming `p`, never the host's
115
+ * absolute path.
101
116
  *
102
117
  * Residual TOCTOU: a component could still be swapped for a symlink between this
103
118
  * call and the eventual `fs` operation. Closing that fully needs per-component
@@ -105,22 +120,22 @@ async function canonicalize(abs) {
105
120
  * sandbox is still recommended for the toolset as a whole.
106
121
  */
107
122
  async function confineToRoot(root, p, opts) {
108
- const allowOutside = opts?.allowOutside ?? false;
109
- const realRoot = await realpathOrSelf(path.resolve(root));
110
- const abs = path.resolve(realRoot, p);
111
- if (allowOutside)
112
- return abs;
123
+ const allowedRoots = opts?.allowedRoots ?? [];
124
+ const realRoot = await canonicalize(path.resolve(root));
113
125
  let real;
114
126
  try {
115
- real = await canonicalize(abs);
127
+ real = await canonicalize(path.resolve(realRoot, p));
116
128
  }
117
129
  catch (err) {
118
130
  throw new ToolError_1.ToolError(fsErrorMessage(err, `path ${JSON.stringify(p)}`));
119
131
  }
120
- if (real !== realRoot && !real.startsWith(realRoot + path.sep)) {
121
- throw new ToolError_1.ToolError(`path ${JSON.stringify(p)} escapes workdir`);
132
+ if (isWithin(realRoot, real) || (await containingRoot(allowedRoots, real)) !== undefined) {
133
+ return real;
122
134
  }
123
- return real;
135
+ const permitted = allowedRoots.length ?
136
+ "the session's working directory and its other permitted directories"
137
+ : "the session's working directory";
138
+ throw new ToolError_1.ToolError(`path ${JSON.stringify(p)} is outside ${permitted}`);
124
139
  }
125
140
  /**
126
141
  * Atomically write `content` to `targetPath`: write a sibling temp file, fsync
@@ -1 +1 @@
1
- {"version":3,"file":"fs-util.js","sourceRoot":"","sources":["../../src/tools/agent-toolset/fs-util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fs-util.js","sourceRoot":"","sources":["../../src/tools/agent-toolset/fs-util.ts"],"names":[],"mappings":"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"}
@@ -12,14 +12,25 @@ import { ToolError } from "../../lib/tools/ToolError.mjs";
12
12
  export const DIR_CREATE_MODE = 0o755;
13
13
  /** Mode for files the file tools create. */
14
14
  export const FILE_CREATE_MODE = 0o644;
15
- /** `realpath` `p`, or return `p` unchanged when it cannot be resolved. */
16
- async function realpathOrSelf(p) {
17
- try {
18
- return await fs.realpath(p);
19
- }
20
- catch {
21
- return p;
15
+ /** True when `p` is `root` itself or lexically contained within it. */
16
+ export function isWithin(root, p) {
17
+ const rel = path.relative(root, p);
18
+ return rel === '' || (!rel.startsWith('..' + path.sep) && rel !== '..' && !path.isAbsolute(rel));
19
+ }
20
+ /**
21
+ * The first entry of `roots` whose canonical form contains the
22
+ * already-canonical `target`, returned as configured; `undefined` when none
23
+ * does. Each root goes through {@link canonicalize} at check time, exactly like
24
+ * the workdir in {@link confineToRoot}, so granting access (`allowedRoots`)
25
+ * and refusing writes (`readOnlyRoots`) can never resolve the same entry two
26
+ * different ways.
27
+ */
28
+ export async function containingRoot(roots, target) {
29
+ for (const root of roots) {
30
+ if (isWithin(await canonicalize(path.resolve(root)), target))
31
+ return root;
22
32
  }
33
+ return undefined;
23
34
  }
24
35
  /** Matches Linux MAXSYMLINKS, the threshold at which `realpath` itself reports ELOOP. */
25
36
  const MAX_SYMLINK_HOPS = 40;
@@ -78,17 +89,19 @@ export async function canonicalize(abs) {
78
89
  }
79
90
  }
80
91
  /**
81
- * Resolve `p` and confine it to `root`.
92
+ * Resolve `p` against `root` and confine it to `root` or one of `allowedRoots`
93
+ * (absolute paths, resolved at check time exactly like `root`).
82
94
  *
83
95
  * Absolute and relative inputs go through the same canonicalise-then-contain
84
- * check — an absolute path that lands inside `root` is permitted, only paths
85
- * that resolve *outside* are rejected. Every symlink in `p` (including the
86
- * leaf, even a dangling one) is resolved before the confinement check, and the
87
- * resolved path is what the caller then operates on, so a symlink inside `root`
88
- * that points outside it can neither pass the check nor be followed afterwards.
89
- * `..` is collapsed lexically before any symlink is followed. A path that cannot
90
- * be resolved (symlink loop, unreadable component) is rejected with a
91
- * `ToolError` naming `p`, never the host's absolute path.
96
+ * check — an absolute path that lands inside a permitted root is accepted,
97
+ * only paths that resolve *outside* all of them are rejected. Every symlink in
98
+ * `p` (including the leaf, even a dangling one) is resolved before the
99
+ * confinement check, and the resolved path is what the caller then operates
100
+ * on, so a symlink inside `root` that points outside it can neither pass the
101
+ * check nor be followed afterwards. `..` is collapsed lexically before any
102
+ * symlink is followed. A path that cannot be resolved (symlink loop, unreadable
103
+ * component) is rejected with a `ToolError` naming `p`, never the host's
104
+ * absolute path.
92
105
  *
93
106
  * Residual TOCTOU: a component could still be swapped for a symlink between this
94
107
  * call and the eventual `fs` operation. Closing that fully needs per-component
@@ -96,22 +109,22 @@ export async function canonicalize(abs) {
96
109
  * sandbox is still recommended for the toolset as a whole.
97
110
  */
98
111
  export async function confineToRoot(root, p, opts) {
99
- const allowOutside = opts?.allowOutside ?? false;
100
- const realRoot = await realpathOrSelf(path.resolve(root));
101
- const abs = path.resolve(realRoot, p);
102
- if (allowOutside)
103
- return abs;
112
+ const allowedRoots = opts?.allowedRoots ?? [];
113
+ const realRoot = await canonicalize(path.resolve(root));
104
114
  let real;
105
115
  try {
106
- real = await canonicalize(abs);
116
+ real = await canonicalize(path.resolve(realRoot, p));
107
117
  }
108
118
  catch (err) {
109
119
  throw new ToolError(fsErrorMessage(err, `path ${JSON.stringify(p)}`));
110
120
  }
111
- if (real !== realRoot && !real.startsWith(realRoot + path.sep)) {
112
- throw new ToolError(`path ${JSON.stringify(p)} escapes workdir`);
121
+ if (isWithin(realRoot, real) || (await containingRoot(allowedRoots, real)) !== undefined) {
122
+ return real;
113
123
  }
114
- return real;
124
+ const permitted = allowedRoots.length ?
125
+ "the session's working directory and its other permitted directories"
126
+ : "the session's working directory";
127
+ throw new ToolError(`path ${JSON.stringify(p)} is outside ${permitted}`);
115
128
  }
116
129
  /**
117
130
  * Atomically write `content` to `targetPath`: write a sibling temp file, fsync
@@ -1 +1 @@
1
- {"version":3,"file":"fs-util.mjs","sourceRoot":"","sources":["../../src/tools/agent-toolset/fs-util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fs-util.mjs","sourceRoot":"","sources":["../../src/tools/agent-toolset/fs-util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Session-level memory-store download and sync.
3
+ *
4
+ * A session may have several memory stores attached. This module resolves
5
+ * where each store's folder goes on disk, opens a {@link LocalFileStore}
6
+ * there, and reconciles each folder with its remote store — the merge rules
7
+ * live on {@link SessionMemoryStores}.
8
+ *
9
+ * Node-only (it sits on the filesystem-backed FileStore); like `skills.ts`,
10
+ * it is reachable through the shimmed `node.ts` entry point.
11
+ */
12
+ import type { Anthropic } from "../../client.mjs";
13
+ import { AnthropicError } from "../../core/error.mjs";
14
+ import type { BetaManagedAgentsSession } from "../../resources/beta/sessions/sessions.mjs";
15
+ export { DEFAULT_MEMORY_SYNC_INTERVAL_MS, MIN_MEMORY_SYNC_INTERVAL_MS } from "./sync-interval.mjs";
16
+ /**
17
+ * Whether a locally deleted file may delete its memory on the server:
18
+ * `"enabled"` sends the delete, `"log_only"` runs the checks but only logs,
19
+ * `"disabled"` never deletes.
20
+ */
21
+ export type MemoryDeleteMode = 'enabled' | 'log_only' | 'disabled';
22
+ /**
23
+ * Time bound the worker puts on each teardown pass — the final
24
+ * {@link SessionMemoryStores.finish}, then {@link SessionMemoryStores.flushWrites} —
25
+ * so a slow server cannot stall teardown.
26
+ */
27
+ export declare const MEMORY_FLUSH_TIMEOUT_MS = 30000;
28
+ /**
29
+ * Marker file stamped into every store folder; a sync trusts the folder only
30
+ * when it matches. Never itself syncs.
31
+ */
32
+ export declare const MARKER_PATH = ".anthropic-memory-store";
33
+ /** How long a file must stay missing locally before its server delete goes out. */
34
+ export declare const DELETE_CORROBORATION_MS = 30000;
35
+ /**
36
+ * How many uploads one store's flush keeps in flight. At ~0.3s per upload,
37
+ * 32 clears the server's 2000-memories-per-store cap inside
38
+ * {@link MEMORY_FLUSH_TIMEOUT_MS}.
39
+ */
40
+ export declare const UPLOAD_CONCURRENCY = 32;
41
+ /**
42
+ * A session's memory stores could not be mounted.
43
+ *
44
+ * Thrown by {@link SessionMemoryStores.download} when a store cannot be
45
+ * materialised on disk, and by the environment worker when a work item for a
46
+ * session that has memory stores carried no sessions token to reach them with.
47
+ */
48
+ export declare class SessionMemoryError extends AnthropicError {
49
+ constructor(message: string, cause?: unknown);
50
+ }
51
+ export interface SessionMemoryStoresOptions {
52
+ /** Base directory for the `{workdir}/memory/<name>` fallback store location. */
53
+ workdir: string;
54
+ /**
55
+ * How often (milliseconds) {@link SessionMemoryStores.syncIfDue} actually
56
+ * syncs. Defaults to {@link DEFAULT_MEMORY_SYNC_INTERVAL_MS} (15s); values
57
+ * below {@link MIN_MEMORY_SYNC_INTERVAL_MS} (5s) are rejected.
58
+ */
59
+ syncIntervalMs?: number;
60
+ /** See {@link MemoryDeleteMode}. Defaults to `"enabled"`. */
61
+ syncDeletions?: MemoryDeleteMode;
62
+ }
63
+ /**
64
+ * The memory stores attached to one session, materialised on disk.
65
+ *
66
+ * {@link SessionMemoryStores.download} opens a {@link LocalFileStore} at each
67
+ * attached store's directory (its `mount_path`, or a workdir fallback — see
68
+ * {@link SessionMemoryStores.download}), pulls its memories, and records each
69
+ * one's `content_sha256` as the sync baseline. Each sync
70
+ * ({@link SessionMemoryStores.syncIfDue} on the worker's cadence,
71
+ * {@link SessionMemoryStores.finish} once at the end) reconciles disk against
72
+ * server, per store and per path:
73
+ *
74
+ * - a memory changed only remotely is written to disk;
75
+ * - a file changed only locally is uploaded — an update with a
76
+ * `content_sha256` precondition, or a create for a new file;
77
+ * - a file changed on both sides logs a warning and takes the server version;
78
+ * - a file the server refuses (too large, invalid content) is skipped —
79
+ * warned once and retried only after the file changes; other files keep
80
+ * syncing;
81
+ * - a file deleted locally is deleted on the server after a delay and a
82
+ * re-check — never on the first sync that notices, and only up to a
83
+ * per-sync cap. `syncDeletions` gates it;
84
+ * - a memory deleted on the server is deleted on disk — unless the local
85
+ * file holds un-pushed edits: a writable store re-creates the memory
86
+ * from the file, a read-only one keeps the file unsynced;
87
+ * - a store attached read-only pulls but never pushes.
88
+ *
89
+ * A download pulls the whole store, so it lists with content included. The
90
+ * recurring syncs instead run two phases: a content-free listing (paths and
91
+ * shas) drives the merge decisions, then only the memories actually being
92
+ * written to disk are fetched, a bounded number at a time. A sync that finds
93
+ * nothing changed moves no content at all.
94
+ *
95
+ * A file whose write to disk failed is never in the baseline, so its absence
96
+ * reads as a failed download — it is pulled again, never deleted. A write
97
+ * never re-creates a store folder that vanished mid-sync: it fails, and the
98
+ * next sync's scan finds whatever is at the path by then — nothing
99
+ * (re-downloaded) or someone else's files (left alone) — under the rules
100
+ * below.
101
+ *
102
+ * A store folder that loses its {@link MARKER_PATH} marker, is emptied,
103
+ * or vanishes is re-downloaded rather than treated as a mass local
104
+ * delete; a folder whose marker names another store is left as found —
105
+ * nothing pushed, nothing deleted.
106
+ *
107
+ * Two things about the store's directory make
108
+ * {@link SessionMemoryStores.download} refuse the session outright, with
109
+ * {@link SessionMemoryError}: a `mount_path` that is not a clean absolute
110
+ * path, and a directory already sitting at that path.
111
+ *
112
+ * {@link SessionMemoryStores.download} throws on the first store it cannot
113
+ * materialise. The syncs never throw: mid-session, one bad store or one bad
114
+ * file is logged and the rest continue. Instances are not safe for concurrent
115
+ * use. The worker builds one on its token-scoped sub-client (the memory
116
+ * endpoints reject the environment key): `syncIfDue` after each tool call,
117
+ * `finish` once at a clean end, a bounded {@link SessionMemoryStores.flushWrites}
118
+ * in every teardown, `dispose` last.
119
+ */
120
+ export declare class SessionMemoryStores {
121
+ #private;
122
+ constructor(client: Anthropic, opts: SessionMemoryStoresOptions);
123
+ /**
124
+ * Every attached store's root directory.
125
+ *
126
+ * The worker lists these as the file tools' allowed roots so a store
127
+ * mounted outside the workdir stays reachable.
128
+ */
129
+ get roots(): string[];
130
+ /**
131
+ * Root directories of stores attached read-only.
132
+ *
133
+ * The file tools consult this to refuse writes into read-only stores.
134
+ */
135
+ get readOnlyRoots(): string[];
136
+ /**
137
+ * Download every attached store's memories to disk.
138
+ *
139
+ * `session` arrives already fetched — one snapshot shared with the skills
140
+ * download, so the two cannot disagree about the resources.
141
+ */
142
+ download(session: BetaManagedAgentsSession): Promise<void>;
143
+ /**
144
+ * The session's last sync — skips the delete wait, so calling it twice
145
+ * would undo the protection; it throws instead.
146
+ */
147
+ finish(): Promise<void>;
148
+ /** @internal — reconcile every store once; the tests' deterministic driver */
149
+ syncAll(final: boolean): Promise<void>;
150
+ /** Sync when `syncIntervalMs` has elapsed since the last one. Never throws. */
151
+ syncIfDue(): Promise<void>;
152
+ /**
153
+ * Upload new and changed files; send no deletes and pull nothing.
154
+ *
155
+ * The push-only rescue pass for a session ending on an error or
156
+ * cancel — best-effort, bounded by the caller: once `signal` aborts no
157
+ * further upload starts, each store cut off part-way logs how many
158
+ * changed files it had not finished uploading, and this resolves without
159
+ * waiting for requests already in flight. Each store uploads up to
160
+ * {@link UPLOAD_CONCURRENCY} files at a time. Skips read-only stores,
161
+ * refused files, files the server already holds, and folders that fail
162
+ * the marker check. Never throws.
163
+ */
164
+ flushWrites(signal?: AbortSignal): Promise<void>;
165
+ /**
166
+ * Remove every store directory that {@link SessionMemoryStores.download}
167
+ * created. Pre-existing directories are left alone — that is
168
+ * {@link FileStore.dispose}'s own rule. A folder that fails the marker
169
+ * check is kept too — sync left it as found, so must dispose.
170
+ */
171
+ dispose(): Promise<void>;
172
+ }
173
+ //# sourceMappingURL=memories.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memories.d.mts","sourceRoot":"","sources":["../../src/tools/agent-toolset/memories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,yBAAqB;AAC9C,OAAO,EAAE,cAAc,EAAE,6BAAyB;AAKlD,OAAO,KAAK,EAAE,wBAAwB,EAAE,mDAA+C;AAQvF,OAAO,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,4BAAwB;AAE/F;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,WAAW,4BAA4B,CAAC;AAQrD,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAgB9C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAoBrC;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;gBACxC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAO7C;AAsCD,MAAM,WAAW,0BAA0B;IACzC,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,qBAAa,mBAAmB;;gBAUlB,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,0BAA0B;IAU/D;;;;;OAKG;IACH,IAAI,KAAK,IAAI,MAAM,EAAE,CAEpB;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IA0BD;;;;;OAKG;IACG,QAAQ,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DhE;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B,8EAA8E;IACxE,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA8F5C,+EAA+E;IACzE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAKhC;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkEtD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAsb/B"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Session-level memory-store download and sync.
3
+ *
4
+ * A session may have several memory stores attached. This module resolves
5
+ * where each store's folder goes on disk, opens a {@link LocalFileStore}
6
+ * there, and reconciles each folder with its remote store — the merge rules
7
+ * live on {@link SessionMemoryStores}.
8
+ *
9
+ * Node-only (it sits on the filesystem-backed FileStore); like `skills.ts`,
10
+ * it is reachable through the shimmed `node.ts` entry point.
11
+ */
12
+ import type { Anthropic } from "../../client.js";
13
+ import { AnthropicError } from "../../core/error.js";
14
+ import type { BetaManagedAgentsSession } from "../../resources/beta/sessions/sessions.js";
15
+ export { DEFAULT_MEMORY_SYNC_INTERVAL_MS, MIN_MEMORY_SYNC_INTERVAL_MS } from "./sync-interval.js";
16
+ /**
17
+ * Whether a locally deleted file may delete its memory on the server:
18
+ * `"enabled"` sends the delete, `"log_only"` runs the checks but only logs,
19
+ * `"disabled"` never deletes.
20
+ */
21
+ export type MemoryDeleteMode = 'enabled' | 'log_only' | 'disabled';
22
+ /**
23
+ * Time bound the worker puts on each teardown pass — the final
24
+ * {@link SessionMemoryStores.finish}, then {@link SessionMemoryStores.flushWrites} —
25
+ * so a slow server cannot stall teardown.
26
+ */
27
+ export declare const MEMORY_FLUSH_TIMEOUT_MS = 30000;
28
+ /**
29
+ * Marker file stamped into every store folder; a sync trusts the folder only
30
+ * when it matches. Never itself syncs.
31
+ */
32
+ export declare const MARKER_PATH = ".anthropic-memory-store";
33
+ /** How long a file must stay missing locally before its server delete goes out. */
34
+ export declare const DELETE_CORROBORATION_MS = 30000;
35
+ /**
36
+ * How many uploads one store's flush keeps in flight. At ~0.3s per upload,
37
+ * 32 clears the server's 2000-memories-per-store cap inside
38
+ * {@link MEMORY_FLUSH_TIMEOUT_MS}.
39
+ */
40
+ export declare const UPLOAD_CONCURRENCY = 32;
41
+ /**
42
+ * A session's memory stores could not be mounted.
43
+ *
44
+ * Thrown by {@link SessionMemoryStores.download} when a store cannot be
45
+ * materialised on disk, and by the environment worker when a work item for a
46
+ * session that has memory stores carried no sessions token to reach them with.
47
+ */
48
+ export declare class SessionMemoryError extends AnthropicError {
49
+ constructor(message: string, cause?: unknown);
50
+ }
51
+ export interface SessionMemoryStoresOptions {
52
+ /** Base directory for the `{workdir}/memory/<name>` fallback store location. */
53
+ workdir: string;
54
+ /**
55
+ * How often (milliseconds) {@link SessionMemoryStores.syncIfDue} actually
56
+ * syncs. Defaults to {@link DEFAULT_MEMORY_SYNC_INTERVAL_MS} (15s); values
57
+ * below {@link MIN_MEMORY_SYNC_INTERVAL_MS} (5s) are rejected.
58
+ */
59
+ syncIntervalMs?: number;
60
+ /** See {@link MemoryDeleteMode}. Defaults to `"enabled"`. */
61
+ syncDeletions?: MemoryDeleteMode;
62
+ }
63
+ /**
64
+ * The memory stores attached to one session, materialised on disk.
65
+ *
66
+ * {@link SessionMemoryStores.download} opens a {@link LocalFileStore} at each
67
+ * attached store's directory (its `mount_path`, or a workdir fallback — see
68
+ * {@link SessionMemoryStores.download}), pulls its memories, and records each
69
+ * one's `content_sha256` as the sync baseline. Each sync
70
+ * ({@link SessionMemoryStores.syncIfDue} on the worker's cadence,
71
+ * {@link SessionMemoryStores.finish} once at the end) reconciles disk against
72
+ * server, per store and per path:
73
+ *
74
+ * - a memory changed only remotely is written to disk;
75
+ * - a file changed only locally is uploaded — an update with a
76
+ * `content_sha256` precondition, or a create for a new file;
77
+ * - a file changed on both sides logs a warning and takes the server version;
78
+ * - a file the server refuses (too large, invalid content) is skipped —
79
+ * warned once and retried only after the file changes; other files keep
80
+ * syncing;
81
+ * - a file deleted locally is deleted on the server after a delay and a
82
+ * re-check — never on the first sync that notices, and only up to a
83
+ * per-sync cap. `syncDeletions` gates it;
84
+ * - a memory deleted on the server is deleted on disk — unless the local
85
+ * file holds un-pushed edits: a writable store re-creates the memory
86
+ * from the file, a read-only one keeps the file unsynced;
87
+ * - a store attached read-only pulls but never pushes.
88
+ *
89
+ * A download pulls the whole store, so it lists with content included. The
90
+ * recurring syncs instead run two phases: a content-free listing (paths and
91
+ * shas) drives the merge decisions, then only the memories actually being
92
+ * written to disk are fetched, a bounded number at a time. A sync that finds
93
+ * nothing changed moves no content at all.
94
+ *
95
+ * A file whose write to disk failed is never in the baseline, so its absence
96
+ * reads as a failed download — it is pulled again, never deleted. A write
97
+ * never re-creates a store folder that vanished mid-sync: it fails, and the
98
+ * next sync's scan finds whatever is at the path by then — nothing
99
+ * (re-downloaded) or someone else's files (left alone) — under the rules
100
+ * below.
101
+ *
102
+ * A store folder that loses its {@link MARKER_PATH} marker, is emptied,
103
+ * or vanishes is re-downloaded rather than treated as a mass local
104
+ * delete; a folder whose marker names another store is left as found —
105
+ * nothing pushed, nothing deleted.
106
+ *
107
+ * Two things about the store's directory make
108
+ * {@link SessionMemoryStores.download} refuse the session outright, with
109
+ * {@link SessionMemoryError}: a `mount_path` that is not a clean absolute
110
+ * path, and a directory already sitting at that path.
111
+ *
112
+ * {@link SessionMemoryStores.download} throws on the first store it cannot
113
+ * materialise. The syncs never throw: mid-session, one bad store or one bad
114
+ * file is logged and the rest continue. Instances are not safe for concurrent
115
+ * use. The worker builds one on its token-scoped sub-client (the memory
116
+ * endpoints reject the environment key): `syncIfDue` after each tool call,
117
+ * `finish` once at a clean end, a bounded {@link SessionMemoryStores.flushWrites}
118
+ * in every teardown, `dispose` last.
119
+ */
120
+ export declare class SessionMemoryStores {
121
+ #private;
122
+ constructor(client: Anthropic, opts: SessionMemoryStoresOptions);
123
+ /**
124
+ * Every attached store's root directory.
125
+ *
126
+ * The worker lists these as the file tools' allowed roots so a store
127
+ * mounted outside the workdir stays reachable.
128
+ */
129
+ get roots(): string[];
130
+ /**
131
+ * Root directories of stores attached read-only.
132
+ *
133
+ * The file tools consult this to refuse writes into read-only stores.
134
+ */
135
+ get readOnlyRoots(): string[];
136
+ /**
137
+ * Download every attached store's memories to disk.
138
+ *
139
+ * `session` arrives already fetched — one snapshot shared with the skills
140
+ * download, so the two cannot disagree about the resources.
141
+ */
142
+ download(session: BetaManagedAgentsSession): Promise<void>;
143
+ /**
144
+ * The session's last sync — skips the delete wait, so calling it twice
145
+ * would undo the protection; it throws instead.
146
+ */
147
+ finish(): Promise<void>;
148
+ /** @internal — reconcile every store once; the tests' deterministic driver */
149
+ syncAll(final: boolean): Promise<void>;
150
+ /** Sync when `syncIntervalMs` has elapsed since the last one. Never throws. */
151
+ syncIfDue(): Promise<void>;
152
+ /**
153
+ * Upload new and changed files; send no deletes and pull nothing.
154
+ *
155
+ * The push-only rescue pass for a session ending on an error or
156
+ * cancel — best-effort, bounded by the caller: once `signal` aborts no
157
+ * further upload starts, each store cut off part-way logs how many
158
+ * changed files it had not finished uploading, and this resolves without
159
+ * waiting for requests already in flight. Each store uploads up to
160
+ * {@link UPLOAD_CONCURRENCY} files at a time. Skips read-only stores,
161
+ * refused files, files the server already holds, and folders that fail
162
+ * the marker check. Never throws.
163
+ */
164
+ flushWrites(signal?: AbortSignal): Promise<void>;
165
+ /**
166
+ * Remove every store directory that {@link SessionMemoryStores.download}
167
+ * created. Pre-existing directories are left alone — that is
168
+ * {@link FileStore.dispose}'s own rule. A folder that fails the marker
169
+ * check is kept too — sync left it as found, so must dispose.
170
+ */
171
+ dispose(): Promise<void>;
172
+ }
173
+ //# sourceMappingURL=memories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memories.d.ts","sourceRoot":"","sources":["../../src/tools/agent-toolset/memories.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,wBAAqB;AAC9C,OAAO,EAAE,cAAc,EAAE,4BAAyB;AAKlD,OAAO,KAAK,EAAE,wBAAwB,EAAE,kDAA+C;AAQvF,OAAO,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,2BAAwB;AAE/F;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,WAAW,4BAA4B,CAAC;AAQrD,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAgB9C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAoBrC;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;gBACxC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAO7C;AAsCD,MAAM,WAAW,0BAA0B;IACzC,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,qBAAa,mBAAmB;;gBAUlB,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,0BAA0B;IAU/D;;;;;OAKG;IACH,IAAI,KAAK,IAAI,MAAM,EAAE,CAEpB;IAED;;;;OAIG;IACH,IAAI,aAAa,IAAI,MAAM,EAAE,CAE5B;IA0BD;;;;;OAKG;IACG,QAAQ,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DhE;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B,8EAA8E;IACxE,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA8F5C,+EAA+E;IACzE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAKhC;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkEtD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAsb/B"}