aura-code 0.6.3 → 0.10.1

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 (265) hide show
  1. package/README.md +47 -164
  2. package/dist/agent/affect.d.ts +13 -0
  3. package/dist/agent/affect.js +34 -0
  4. package/dist/agent/affect.js.map +1 -0
  5. package/dist/agent/compactor.d.ts +27 -4
  6. package/dist/agent/compactor.js +185 -54
  7. package/dist/agent/compactor.js.map +1 -1
  8. package/dist/agent/confess.d.ts +35 -0
  9. package/dist/agent/confess.js +296 -0
  10. package/dist/agent/confess.js.map +1 -0
  11. package/dist/agent/context.d.ts +0 -4
  12. package/dist/agent/context.js +0 -38
  13. package/dist/agent/context.js.map +1 -1
  14. package/dist/agent/domain-expertise.d.ts +22 -0
  15. package/dist/agent/domain-expertise.js +110 -0
  16. package/dist/agent/domain-expertise.js.map +1 -0
  17. package/dist/agent/executive-queue.d.ts +26 -0
  18. package/dist/agent/executive-queue.js +50 -0
  19. package/dist/agent/executive-queue.js.map +1 -0
  20. package/dist/agent/generational-flush.d.ts +28 -0
  21. package/dist/agent/generational-flush.js +48 -0
  22. package/dist/agent/generational-flush.js.map +1 -0
  23. package/dist/agent/loop-profile.d.ts +50 -0
  24. package/dist/agent/loop-profile.js +88 -0
  25. package/dist/agent/loop-profile.js.map +1 -0
  26. package/dist/agent/loop.d.ts +14 -5
  27. package/dist/agent/loop.js +167 -39
  28. package/dist/agent/loop.js.map +1 -1
  29. package/dist/agent/memory-consolidate.d.ts +14 -0
  30. package/dist/agent/memory-consolidate.js +141 -0
  31. package/dist/agent/memory-consolidate.js.map +1 -0
  32. package/dist/agent/mixture.d.ts +33 -0
  33. package/dist/agent/mixture.js +138 -0
  34. package/dist/agent/mixture.js.map +1 -0
  35. package/dist/agent/spawner.js +2 -2
  36. package/dist/agent/spawner.js.map +1 -1
  37. package/dist/agent/system-prompt.d.ts +1 -1
  38. package/dist/agent/system-prompt.js +50 -22
  39. package/dist/agent/system-prompt.js.map +1 -1
  40. package/dist/agent/unified-memory.d.ts +15 -0
  41. package/dist/agent/unified-memory.js +164 -0
  42. package/dist/agent/unified-memory.js.map +1 -0
  43. package/dist/checkpoints/engine.d.ts +44 -0
  44. package/dist/checkpoints/engine.js +324 -0
  45. package/dist/checkpoints/engine.js.map +1 -0
  46. package/dist/cli/command-palette.d.ts +26 -0
  47. package/dist/cli/command-palette.js +133 -0
  48. package/dist/cli/command-palette.js.map +1 -0
  49. package/dist/cli/context-health.d.ts +51 -0
  50. package/dist/cli/context-health.js +187 -0
  51. package/dist/cli/context-health.js.map +1 -0
  52. package/dist/cli/diamond.d.ts +67 -0
  53. package/dist/cli/diamond.js +222 -12
  54. package/dist/cli/diamond.js.map +1 -1
  55. package/dist/cli/dic.d.ts +2 -0
  56. package/dist/cli/dic.js +106 -0
  57. package/dist/cli/dic.js.map +1 -0
  58. package/dist/cli/diff-view.d.ts +18 -0
  59. package/dist/cli/diff-view.js +114 -0
  60. package/dist/cli/diff-view.js.map +1 -0
  61. package/dist/cli/display.d.ts +18 -4
  62. package/dist/cli/display.js +74 -151
  63. package/dist/cli/display.js.map +1 -1
  64. package/dist/cli/help-data.d.ts +7 -0
  65. package/dist/cli/help-data.js +80 -0
  66. package/dist/cli/help-data.js.map +1 -0
  67. package/dist/cli/index.js +1002 -852
  68. package/dist/cli/index.js.map +1 -1
  69. package/dist/cli/markdown.d.ts +5 -0
  70. package/dist/cli/markdown.js +128 -0
  71. package/dist/cli/markdown.js.map +1 -0
  72. package/dist/cli/model-select.d.ts +39 -0
  73. package/dist/cli/model-select.js +65 -0
  74. package/dist/cli/model-select.js.map +1 -0
  75. package/dist/cli/tui.d.ts +34 -0
  76. package/dist/cli/tui.js +1176 -0
  77. package/dist/cli/tui.js.map +1 -0
  78. package/dist/config/defaults.d.ts +6 -17
  79. package/dist/config/defaults.js +25 -46
  80. package/dist/config/defaults.js.map +1 -1
  81. package/dist/config/project-config.d.ts +2 -6
  82. package/dist/config/project-config.js +2 -2
  83. package/dist/config/project-config.js.map +1 -1
  84. package/dist/doctor/checks.d.ts +18 -0
  85. package/dist/doctor/checks.js +524 -0
  86. package/dist/doctor/checks.js.map +1 -0
  87. package/dist/doctor/index.d.ts +4 -0
  88. package/dist/doctor/index.js +229 -0
  89. package/dist/doctor/index.js.map +1 -0
  90. package/dist/doctor/repair.d.ts +19 -0
  91. package/dist/doctor/repair.js +126 -0
  92. package/dist/doctor/repair.js.map +1 -0
  93. package/dist/doctor/types.d.ts +38 -0
  94. package/dist/doctor/types.js +10 -0
  95. package/dist/doctor/types.js.map +1 -0
  96. package/dist/dream/dream.d.ts +79 -59
  97. package/dist/dream/dream.js +324 -144
  98. package/dist/dream/dream.js.map +1 -1
  99. package/dist/dream/episode.d.ts +17 -0
  100. package/dist/dream/episode.js +116 -0
  101. package/dist/dream/episode.js.map +1 -0
  102. package/dist/kanban/engine.d.ts +26 -0
  103. package/dist/kanban/engine.js +208 -0
  104. package/dist/kanban/engine.js.map +1 -0
  105. package/dist/kanban/types.d.ts +19 -0
  106. package/dist/kanban/types.js +9 -1
  107. package/dist/kanban/types.js.map +1 -1
  108. package/dist/machina/render-html.js +4 -2
  109. package/dist/machina/render-html.js.map +1 -1
  110. package/dist/machina/render-terminal.js +11 -4
  111. package/dist/machina/render-terminal.js.map +1 -1
  112. package/dist/machina/repair.d.ts +23 -0
  113. package/dist/machina/repair.js +98 -0
  114. package/dist/machina/repair.js.map +1 -0
  115. package/dist/machina/spec.js +12 -12
  116. package/dist/machina/spec.js.map +1 -1
  117. package/dist/machina/verify.d.ts +13 -1
  118. package/dist/machina/verify.js +12 -2
  119. package/dist/machina/verify.js.map +1 -1
  120. package/dist/mining/extract.d.ts +34 -0
  121. package/dist/mining/extract.js +229 -0
  122. package/dist/mining/extract.js.map +1 -0
  123. package/dist/mining/refine.d.ts +28 -0
  124. package/dist/mining/refine.js +256 -0
  125. package/dist/mining/refine.js.map +1 -0
  126. package/dist/perception/extractor.js +5 -3
  127. package/dist/perception/extractor.js.map +1 -1
  128. package/dist/perception/graph-store.d.ts +0 -11
  129. package/dist/perception/graph-store.js +0 -33
  130. package/dist/perception/graph-store.js.map +1 -1
  131. package/dist/perception/index.d.ts +1 -1
  132. package/dist/perception/index.js +1 -2
  133. package/dist/perception/index.js.map +1 -1
  134. package/dist/plugins/commands.d.ts +38 -0
  135. package/dist/plugins/commands.js +134 -0
  136. package/dist/plugins/commands.js.map +1 -0
  137. package/dist/plugins/frontmatter.d.ts +14 -0
  138. package/dist/plugins/frontmatter.js +78 -0
  139. package/dist/plugins/frontmatter.js.map +1 -0
  140. package/dist/plugins/hooks.d.ts +12 -0
  141. package/dist/plugins/hooks.js +148 -0
  142. package/dist/plugins/hooks.js.map +1 -0
  143. package/dist/plugins/loader.d.ts +7 -0
  144. package/dist/plugins/loader.js +255 -0
  145. package/dist/plugins/loader.js.map +1 -0
  146. package/dist/plugins/market.d.ts +23 -0
  147. package/dist/plugins/market.js +281 -0
  148. package/dist/plugins/market.js.map +1 -0
  149. package/dist/plugins/types.d.ts +90 -0
  150. package/dist/plugins/types.js +20 -0
  151. package/dist/plugins/types.js.map +1 -0
  152. package/dist/providers/anthropic-oauth-draft.d.ts +119 -0
  153. package/dist/providers/anthropic-oauth-draft.js +414 -0
  154. package/dist/providers/anthropic-oauth-draft.js.map +1 -0
  155. package/dist/providers/anthropic.d.ts +4 -1
  156. package/dist/providers/anthropic.js +35 -7
  157. package/dist/providers/anthropic.js.map +1 -1
  158. package/dist/providers/factory.d.ts +43 -19
  159. package/dist/providers/factory.js +183 -129
  160. package/dist/providers/factory.js.map +1 -1
  161. package/dist/providers/google.js +9 -22
  162. package/dist/providers/google.js.map +1 -1
  163. package/dist/providers/live-models.d.ts +23 -0
  164. package/dist/providers/live-models.js +145 -0
  165. package/dist/providers/live-models.js.map +1 -0
  166. package/dist/providers/openai-compatible.d.ts +1 -12
  167. package/dist/providers/openai-compatible.js +71 -108
  168. package/dist/providers/openai-compatible.js.map +1 -1
  169. package/dist/providers/resilient-factory.js +1 -1
  170. package/dist/providers/resilient-factory.js.map +1 -1
  171. package/dist/repl/queue.d.ts +22 -0
  172. package/dist/repl/queue.js +165 -0
  173. package/dist/repl/queue.js.map +1 -0
  174. package/dist/repl/side-channel.d.ts +23 -0
  175. package/dist/repl/side-channel.js +63 -0
  176. package/dist/repl/side-channel.js.map +1 -0
  177. package/dist/research/council.d.ts +2 -0
  178. package/dist/research/council.js +29 -4
  179. package/dist/research/council.js.map +1 -1
  180. package/dist/ruby/alternator.d.ts +11 -30
  181. package/dist/ruby/alternator.js +59 -38
  182. package/dist/ruby/alternator.js.map +1 -1
  183. package/dist/ruby/episode-capture.d.ts +0 -10
  184. package/dist/ruby/episode-capture.js +0 -33
  185. package/dist/ruby/episode-capture.js.map +1 -1
  186. package/dist/ruby/types.js +1 -1
  187. package/dist/ruby/types.js.map +1 -1
  188. package/dist/safety/path-jail.d.ts +17 -0
  189. package/dist/safety/path-jail.js +100 -0
  190. package/dist/safety/path-jail.js.map +1 -0
  191. package/dist/safety/permissions.d.ts +12 -21
  192. package/dist/safety/permissions.js +81 -216
  193. package/dist/safety/permissions.js.map +1 -1
  194. package/dist/safety/ssrf.d.ts +29 -0
  195. package/dist/safety/ssrf.js +185 -0
  196. package/dist/safety/ssrf.js.map +1 -0
  197. package/dist/server/index.js +64 -10
  198. package/dist/server/index.js.map +1 -1
  199. package/dist/setup/first-run.d.ts +0 -24
  200. package/dist/setup/first-run.js +10 -344
  201. package/dist/setup/first-run.js.map +1 -1
  202. package/dist/setup/key-store.d.ts +12 -0
  203. package/dist/setup/key-store.js +108 -0
  204. package/dist/setup/key-store.js.map +1 -0
  205. package/dist/setup/provider-registry.js +31 -18
  206. package/dist/setup/provider-registry.js.map +1 -1
  207. package/dist/setup/provider-test.d.ts +7 -0
  208. package/dist/setup/provider-test.js +73 -10
  209. package/dist/setup/provider-test.js.map +1 -1
  210. package/dist/setup/provider-wizard.d.ts +4 -1
  211. package/dist/setup/provider-wizard.js +92 -26
  212. package/dist/setup/provider-wizard.js.map +1 -1
  213. package/dist/setup/xiaomi.d.ts +1 -1
  214. package/dist/setup/xiaomi.js +3 -3
  215. package/dist/setup/xiaomi.js.map +1 -1
  216. package/dist/tools/browser.js +14 -10
  217. package/dist/tools/browser.js.map +1 -1
  218. package/dist/tools/clipboard.js +7 -1
  219. package/dist/tools/clipboard.js.map +1 -1
  220. package/dist/tools/dictate.d.ts +60 -0
  221. package/dist/tools/dictate.js +983 -0
  222. package/dist/tools/dictate.js.map +1 -0
  223. package/dist/tools/dictate_patched.js +1057 -0
  224. package/dist/tools/edit-file.js +10 -2
  225. package/dist/tools/edit-file.js.map +1 -1
  226. package/dist/tools/http-request.js +14 -4
  227. package/dist/tools/http-request.js.map +1 -1
  228. package/dist/tools/image-read.js +34 -2
  229. package/dist/tools/image-read.js.map +1 -1
  230. package/dist/tools/index.d.ts +16 -1
  231. package/dist/tools/index.js +59 -8
  232. package/dist/tools/index.js.map +1 -1
  233. package/dist/tools/mcp.js +12 -0
  234. package/dist/tools/mcp.js.map +1 -1
  235. package/dist/tools/read-file.js +10 -14
  236. package/dist/tools/read-file.js.map +1 -1
  237. package/dist/tools/telegram-audio-policy.d.ts +30 -0
  238. package/dist/tools/telegram-audio-policy.js +49 -0
  239. package/dist/tools/telegram-audio-policy.js.map +1 -0
  240. package/dist/tools/telegram-bot.js +1136 -537
  241. package/dist/tools/telegram-bot.js.map +1 -1
  242. package/dist/tools/telegram-voice.d.ts +18 -5
  243. package/dist/tools/telegram-voice.js +54 -12
  244. package/dist/tools/telegram-voice.js.map +1 -1
  245. package/dist/tools/telegram.d.ts +3 -3
  246. package/dist/tools/telegram.js +5 -84
  247. package/dist/tools/telegram.js.map +1 -1
  248. package/dist/tools/tools.d.ts +2 -14
  249. package/dist/tools/tools.js +79 -144
  250. package/dist/tools/tools.js.map +1 -1
  251. package/dist/tools/web-fetch.js +39 -7
  252. package/dist/tools/web-fetch.js.map +1 -1
  253. package/dist/tools/web-search.d.ts +0 -20
  254. package/dist/tools/web-search.js +40 -137
  255. package/dist/tools/web-search.js.map +1 -1
  256. package/dist/util/errors.js +1 -15
  257. package/dist/util/errors.js.map +1 -1
  258. package/dist/util/json-repair.d.ts +11 -0
  259. package/dist/util/json-repair.js +31 -0
  260. package/dist/util/json-repair.js.map +1 -0
  261. package/dist/util/rate-limiter.js +2 -8
  262. package/dist/util/rate-limiter.js.map +1 -1
  263. package/dist/viz/index.js +793 -792
  264. package/dist/viz/index.js.map +1 -1
  265. package/package.json +12 -32
@@ -32,197 +32,19 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
35
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.PermissionSystem = exports.ShellCommandValidator = void 0;
36
+ exports.PermissionSystem = void 0;
37
+ exports.setSharedReadline = setSharedReadline;
38
+ exports.getSharedReadline = getSharedReadline;
39
+ exports.setConfirmHandler = setConfirmHandler;
40
40
  exports.confirm = confirm;
41
- const fs = __importStar(require("fs"));
42
- const path = __importStar(require("path"));
43
- const readline_1 = __importDefault(require("readline"));
41
+ const readline = __importStar(require("readline"));
44
42
  const defaults_js_1 = require("../config/defaults.js");
45
- // ─────────────────────────────────────────────────────────────────────────────
46
- // ShellCommandValidator — prevents recursive commands from traversing into
47
- // unresponsive FUSE/network mounts where I/O can cause D-state hangs.
48
- // ─────────────────────────────────────────────────────────────────────────────
49
- /** Extract search-path arguments from find/grep/rg command strings. */
50
- function extractSearchPaths(base, args) {
51
- if (base === 'find') {
52
- // find [path] [expression] — first non-flag arg is the search path
53
- for (const a of args) {
54
- if (!a.startsWith('-') && a !== '!' && a !== '(' && a !== ')')
55
- return [a];
56
- }
57
- return ['.'];
58
- }
59
- // grep / rg: look for paths after --, or the last non-flag arg that looks like a path
60
- const paths = [];
61
- let afterDoubleDash = false;
62
- for (const a of args) {
63
- if (a === '--') {
64
- afterDoubleDash = true;
65
- continue;
66
- }
67
- if (afterDoubleDash && !a.startsWith('-')) {
68
- paths.push(a);
69
- continue;
70
- }
71
- // Flags with values: skip the value part
72
- if (a === '-e' || a === '-f' || a === '--regexp' || a === '--file')
73
- continue;
74
- if (a.startsWith('--max-count') || a.startsWith('--glob') || a.startsWith('--include') || a.startsWith('--exclude'))
75
- continue;
76
- if (a.startsWith('-') || a === '--')
77
- continue;
78
- // Only for -r/-R (recursive) commands — collect potential path args
79
- paths.push(a);
80
- }
81
- return paths.length > 0 ? paths : [];
82
- }
83
- /** Detect whether a recursive search command targets a given path. */
84
- function hasRecursiveFlag(args) {
85
- return args.some(a => a === '-r' || a === '-R' || a === '--recursive' ||
86
- (a.startsWith('-') && !a.startsWith('--') && (a.includes('r') || a.includes('R'))));
87
- }
88
- class ShellCommandValidator {
89
- blockedPrefixes;
90
- constructor() {
91
- // Merge static blocklist with dynamically discovered FUSE mounts
92
- this.blockedPrefixes = [...defaults_js_1.BLOCKED_TRAVERSAL_PATHS];
93
- this.discoverFuseMounts();
94
- }
95
- discoverFuseMounts() {
96
- try {
97
- const mounts = fs.readFileSync('/proc/mounts', 'utf8');
98
- for (const line of mounts.split('\n')) {
99
- const parts = line.split(' ');
100
- if (parts.length >= 3 && defaults_js_1.FUSE_MOUNT_PATTERN.test(parts[2])) {
101
- const mountPoint = parts[1];
102
- if (mountPoint && !mountPoint.endsWith('/')) {
103
- this.blockedPrefixes.push(mountPoint + '/');
104
- }
105
- else if (mountPoint) {
106
- this.blockedPrefixes.push(mountPoint);
107
- }
108
- }
109
- }
110
- }
111
- catch {
112
- // /proc/mounts not available (non-Linux, permissions) — static list only
113
- }
114
- }
115
- validateCommand(cmd, projectRoot, config) {
116
- const tokens = tokenize(cmd);
117
- if (tokens.length === 0)
118
- return { allowed: true };
119
- const base = path.basename(tokens[0]);
120
- if (!['find', 'grep', 'rg'].includes(base))
121
- return { allowed: true };
122
- // rg is recursive by default; grep/find require explicit -r flag
123
- const isRecursive = base === 'find' || base === 'rg' || hasRecursiveFlag(tokens.slice(1));
124
- if (!isRecursive)
125
- return { allowed: true };
126
- const searchPaths = extractSearchPaths(base, tokens.slice(1));
127
- const normalizedRoot = projectRoot.endsWith('/') ? projectRoot : projectRoot + '/';
128
- const allowed = config?.allowedMountPaths ?? [];
129
- for (const raw of searchPaths) {
130
- // Expand ~ to HOME
131
- const expanded = raw === '~' || raw.startsWith('~/')
132
- ? path.join(process.env.HOME ?? '/tmp', raw.slice(1))
133
- : raw;
134
- const resolved = path.resolve(projectRoot, expanded);
135
- const normalizedResolved = resolved.endsWith('/') ? resolved : resolved + '/';
136
- // 1) Check blocked mount prefixes first — allowedMountPaths override both
137
- // the mount block AND the root boundary (user explicitly opted in).
138
- let whitelisted = false;
139
- for (const prefix of this.blockedPrefixes) {
140
- if (normalizedResolved.startsWith(prefix)) {
141
- const isExplicitlyAllowed = allowed.some(a => {
142
- const normAllowed = a.endsWith('/') ? a : a + '/';
143
- return normalizedResolved.startsWith(normAllowed);
144
- });
145
- if (isExplicitlyAllowed) {
146
- whitelisted = true;
147
- break;
148
- }
149
- return {
150
- allowed: false,
151
- reason: `Blocked: '${base}' would traverse into '${raw}' which matches a ` +
152
- `blocked mount prefix (${prefix}). This can cause hangs on unresponsive ` +
153
- `FUSE/network filesystems. Add '${raw}' to allowedMountPaths in .aura.json ` +
154
- `to override.`,
155
- };
156
- }
157
- }
158
- // 2) Must be inside project root (skip if explicitly whitelisted above)
159
- if (!whitelisted && !normalizedResolved.startsWith(normalizedRoot) && normalizedResolved !== normalizedRoot) {
160
- return {
161
- allowed: false,
162
- reason: `Blocked: '${base}' search path '${raw}' resolves outside project root (${projectRoot}). ` +
163
- `To search outside the project, run the command directly in your terminal.`,
164
- };
165
- }
166
- }
167
- return { allowed: true };
168
- }
169
- }
170
- exports.ShellCommandValidator = ShellCommandValidator;
171
- /**
172
- * Minimal shell tokenizer that handles quotes and backslash escapes.
173
- * Splits a command string into tokens without invoking a shell.
174
- */
175
- function tokenize(cmd) {
176
- const tokens = [];
177
- let current = '';
178
- let inSingle = false;
179
- let inDouble = false;
180
- let escape = false;
181
- for (const ch of cmd) {
182
- if (escape) {
183
- current += ch;
184
- escape = false;
185
- continue;
186
- }
187
- if (ch === '\\' && !inSingle) {
188
- escape = true;
189
- continue;
190
- }
191
- if (ch === "'" && !inDouble) {
192
- inSingle = !inSingle;
193
- continue;
194
- }
195
- if (ch === '"' && !inSingle) {
196
- inDouble = !inDouble;
197
- continue;
198
- }
199
- if (/\s/.test(ch) && !inSingle && !inDouble) {
200
- if (current.length > 0) {
201
- tokens.push(current);
202
- current = '';
203
- }
204
- continue;
205
- }
206
- current += ch;
207
- }
208
- if (current.length > 0)
209
- tokens.push(current);
210
- return tokens;
211
- }
212
- // ─────────────────────────────────────────────────────────────────────────────
213
- // PermissionSystem
214
- // ─────────────────────────────────────────────────────────────────────────────
215
43
  class PermissionSystem {
216
44
  level;
217
45
  sessionApprovals = new Set();
218
- validator;
219
- projectRoot;
220
- config;
221
- constructor(level = 'normal', projectRoot, config) {
46
+ constructor(level = 'normal') {
222
47
  this.level = level;
223
- this.projectRoot = projectRoot ?? process.cwd();
224
- this.config = config;
225
- this.validator = new ShellCommandValidator();
226
48
  }
227
49
  check(toolName, input) {
228
50
  // Read-only mode: only allow read operations
@@ -240,76 +62,119 @@ class PermissionSystem {
240
62
  if (this.isDangerous(cmd)) {
241
63
  return { allowed: false, reason: `Dangerous command blocked: ${cmd}` };
242
64
  }
243
- const scopeCheck = this.validator.validateCommand(cmd, this.projectRoot, this.config);
244
- if (!scopeCheck.allowed)
245
- return scopeCheck;
65
+ }
66
+ if (toolName === 'mcp' && String(input.action ?? '') === 'connect') {
67
+ const cmd = this.mcpConnectCommand(input);
68
+ if (this.isDangerous(cmd)) {
69
+ return { allowed: false, reason: `Dangerous command blocked: ${cmd}` };
70
+ }
246
71
  }
247
72
  return { allowed: true };
248
73
  }
74
+ // mcp 'connect' spawns an arbitrary external server process — the same
75
+ // trust boundary as run_shell, so it gets the same dangerous-pattern
76
+ // screen plus an unconditional confirm (a server spawn is never on the
77
+ // safe list; once connected, its tools run without further prompts).
78
+ if (toolName === 'mcp' && String(input.action ?? '') === 'connect') {
79
+ const cmd = this.mcpConnectCommand(input);
80
+ if (this.isDangerous(cmd)) {
81
+ return { allowed: false, reason: `Dangerous command blocked: ${cmd}` };
82
+ }
83
+ return { allowed: true, needsConfirm: true };
84
+ }
249
85
  // Normal mode: safe ops auto-approved, destructive need confirm
250
86
  if (toolName === 'run_shell') {
251
87
  const cmd = String(input.command ?? '');
252
88
  if (this.isDangerous(cmd)) {
253
89
  return { allowed: false, reason: `Dangerous command blocked: ${cmd}` };
254
90
  }
255
- const scopeCheck = this.validator.validateCommand(cmd, this.projectRoot, this.config);
256
- if (!scopeCheck.allowed)
257
- return scopeCheck;
258
91
  if (!this.isSafe(cmd)) {
259
92
  return { allowed: true, needsConfirm: true };
260
93
  }
261
94
  }
262
- if (toolName === 'write_file' || toolName === 'edit_file') {
95
+ if (toolName === 'write_file') {
263
96
  const path = String(input.path ?? '');
264
- const key = `${toolName}:${path}`;
97
+ const key = `write:${path}`;
265
98
  if (this.sessionApprovals.has(key))
266
99
  return { allowed: true };
267
- return { allowed: true, needsConfirm: true };
100
+ return { allowed: true };
268
101
  }
269
102
  return { allowed: true };
270
103
  }
271
104
  approveForSession(key) {
272
105
  this.sessionApprovals.add(key);
273
106
  }
107
+ /** Current enforcement level. */
108
+ getLevel() {
109
+ return this.level;
110
+ }
274
111
  /**
275
- * Change the permission level mid-session. Used by `:approve all` since
276
- * RubyAlternator stores a reference to this same instance rather than its
277
- * own copy, calling this also takes effect for any in-flight or future
278
- * Ruby-alternated attempts, with no extra wiring needed.
112
+ * Change the level at runtime — used by the REPL `:approve` command to flip
113
+ * a session into auto-approve (no per-command confirm) and back. Dangerous
114
+ * commands are STILL blocked in 'auto'; this only removes the y/N prompt for
115
+ * ordinary destructive-but-safe operations.
279
116
  */
280
117
  setLevel(level) {
281
118
  this.level = level;
282
119
  }
283
- getLevel() {
284
- return this.level;
120
+ mcpConnectCommand(input) {
121
+ const args = Array.isArray(input.args_list) ? input.args_list.join(' ') : '';
122
+ return `${String(input.command ?? '')} ${args}`.trim();
285
123
  }
286
124
  isDangerous(cmd) {
287
125
  return defaults_js_1.DANGEROUS_PATTERNS.some(p => p.test(cmd));
288
126
  }
289
127
  isSafe(cmd) {
290
- const lower = cmd.toLowerCase().trim();
291
- return defaults_js_1.SAFE_SHELL_COMMANDS.some(s => lower.startsWith(s));
128
+ const trimmed = cmd.trim();
129
+ // A command containing shell control operators can't be judged safe from
130
+ // its prefix alone — `cat x; python3 -c '…'` starts with a safe command
131
+ // but chains an interpreter. Force confirmation for anything with
132
+ // chaining (`;` `&` `|`), redirection (`>` `<`), or command substitution
133
+ // (`$(…)`, backticks). This is the structural fix for prefix-smuggling.
134
+ if (/[;&|<>`]/.test(trimmed) || trimmed.includes('$('))
135
+ return false;
136
+ const lower = trimmed.toLowerCase();
137
+ // Anchor to a whole-command match so `curlx …` doesn't match `curl` and
138
+ // `lscpu` doesn't match `ls`.
139
+ return defaults_js_1.SAFE_SHELL_COMMANDS.some(s => lower === s || lower.startsWith(s + ' '));
292
140
  }
293
141
  }
294
142
  exports.PermissionSystem = PermissionSystem;
143
+ // Shared readline from the interactive REPL. confirm() must reuse it when
144
+ // set: a second interface on the same stdin echoes every keypress twice, and
145
+ // closing it pauses stdin without the REPL's interface knowing — its next
146
+ // prompt never resumes the stream, the event loop drains, and the process
147
+ // exits right after printing the prompt.
148
+ let sharedRl = null;
149
+ function setSharedReadline(rl) {
150
+ sharedRl = rl;
151
+ }
152
+ function getSharedReadline() {
153
+ return sharedRl;
154
+ }
155
+ // The TUI owns stdin in raw mode via its own 'data' handler — a plain
156
+ // readline.Interface (below) forces stdin out of raw mode the moment it
157
+ // attaches and never restores it, so a confirm() prompt during TUI mode
158
+ // used to fight the TUI's own input handling for every keystroke (garbled
159
+ // echo, dropped characters, leftover fragments on screen). setSharedReadline
160
+ // was meant to prevent a *second* readline.Interface, but the TUI doesn't
161
+ // use readline at all — it needs its own raw-mode-safe prompt. cli/index.ts
162
+ // registers one via setConfirmHandler() when TUI mode starts; confirm()
163
+ // prefers it over readline whenever it's set.
164
+ let confirmHandler = null;
165
+ function setConfirmHandler(fn) {
166
+ confirmHandler = fn;
167
+ }
295
168
  /** Ask user to confirm in the terminal. Returns true if approved. */
296
169
  async function confirm(message) {
297
- process.stdout.write(`\n⚠️ ${message} [y/N] `);
298
- // Temporarily remove existing stdin data listeners (e.g. from REPL readline)
299
- // to ensure only ONE reader is active at a time — prevents input doubling.
300
- const existingListeners = process.stdin.rawListeners('data');
301
- for (const listener of existingListeners) {
302
- process.stdin.removeListener('data', listener);
303
- }
170
+ if (confirmHandler)
171
+ return confirmHandler(message);
172
+ const rl = sharedRl ?? readline.createInterface({ input: process.stdin, output: process.stdout });
304
173
  return new Promise(resolve => {
305
- const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
306
- rl.question('', (answer) => {
307
- rl.close();
308
- // Restore original listeners so REPL readline continues working
309
- for (const listener of existingListeners) {
310
- process.stdin.on('data', listener);
311
- }
312
- resolve(answer.trim().toLowerCase() === 'y' || answer.trim().toLowerCase() === 'yes');
174
+ rl.question(`\n⚠️ ${message} [y/N] `, answer => {
175
+ if (rl !== sharedRl)
176
+ rl.close();
177
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
313
178
  });
314
179
  });
315
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/safety/permissions.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2QA,0BAmBC;AA9RD,uCAAyB;AACzB,2CAA6B;AAC7B,wDAAgC;AAChC,uDAG+B;AAc/B,gFAAgF;AAChF,2EAA2E;AAC3E,sEAAsE;AACtE,gFAAgF;AAEhF,uEAAuE;AACvE,SAAS,kBAAkB,CAAC,IAAY,EAAE,IAAc;IACtD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,mEAAmE;QACnE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;gBAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IACD,sFAAsF;IACtF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAAC,eAAe,GAAG,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QACrD,IAAI,eAAe,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACvE,yCAAyC;QACzC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,UAAU,IAAI,CAAC,KAAK,QAAQ;YAAE,SAAS;QAC7E,IAAI,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,SAAS;QAC9H,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,SAAS;QAC9C,oEAAoE;QACpE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACvC,CAAC;AAED,sEAAsE;AACtE,SAAS,gBAAgB,CAAC,IAAc;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACnB,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,aAAa;QAC/C,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CACnF,CAAC;AACJ,CAAC;AAED,MAAa,qBAAqB;IACxB,eAAe,CAAW;IAElC;QACE,iEAAiE;QACjE,IAAI,CAAC,eAAe,GAAG,CAAC,GAAG,qCAAuB,CAAC,CAAC;QACpD,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;YACvD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC9B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,gCAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC5B,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC5C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;oBAC9C,CAAC;yBAAM,IAAI,UAAU,EAAE,CAAC;wBACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACxC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;QAC3E,CAAC;IACH,CAAC;IAED,eAAe,CAAC,GAAW,EAAE,WAAmB,EAAE,MAAyB;QACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAElD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAErE,iEAAiE;QACjE,MAAM,WAAW,GAAG,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,IAAI,CAAC,WAAW;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAE3C,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,cAAc,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC;QACnF,MAAM,OAAO,GAAG,MAAM,EAAE,iBAAiB,IAAI,EAAE,CAAC;QAEhD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,mBAAmB;YACnB,MAAM,QAAQ,GAAG,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;gBAClD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrD,CAAC,CAAC,GAAG,CAAC;YAER,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACrD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC;YAE9E,0EAA0E;YAC1E,uEAAuE;YACvE,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC1C,IAAI,kBAAkB,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1C,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;wBAC3C,MAAM,WAAW,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;wBAClD,OAAO,kBAAkB,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;oBACpD,CAAC,CAAC,CAAC;oBACH,IAAI,mBAAmB,EAAE,CAAC;wBAAC,WAAW,GAAG,IAAI,CAAC;wBAAC,MAAM;oBAAC,CAAC;oBACvD,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,MAAM,EAAE,aAAa,IAAI,0BAA0B,GAAG,oBAAoB;4BACxE,yBAAyB,MAAM,0CAA0C;4BACzE,kCAAkC,GAAG,uCAAuC;4BAC5E,cAAc;qBACjB,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,wEAAwE;YACxE,IAAI,CAAC,WAAW,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,kBAAkB,KAAK,cAAc,EAAE,CAAC;gBAC5G,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,aAAa,IAAI,kBAAkB,GAAG,oCAAoC,WAAW,KAAK;wBAChG,2EAA2E;iBAC9E,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AApFD,sDAoFC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,IAAI,EAAE,CAAC;YACd,MAAM,GAAG,KAAK,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAAC,MAAM,GAAG,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QAC1D,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAAC,QAAQ,GAAG,CAAC,QAAQ,CAAC;YAAC,SAAS;QAAC,CAAC;QAChE,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAAC,QAAQ,GAAG,CAAC,QAAQ,CAAC;YAAC,SAAS;QAAC,CAAC;QAChE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;YAAC,CAAC;YAC/D,SAAS;QACX,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF,MAAa,gBAAgB;IACnB,KAAK,CAAkB;IACvB,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,SAAS,CAAwB;IACjC,WAAW,CAAS;IACpB,MAAM,CAAoB;IAElC,YAAY,QAAyB,QAAQ,EAAE,WAAoB,EAAE,MAAyB;QAC5F,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,QAAgB,EAAE,KAA8B;QACpD,6CAA6C;QAC7C,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,CAAC,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;YACpF,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,QAAQ,iCAAiC,EAAE,CAAC;YACxF,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,0DAA0D;QAC1D,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;gBAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;gBACxC,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,GAAG,EAAE,EAAE,CAAC;gBACzE,CAAC;gBACD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtF,IAAI,CAAC,UAAU,CAAC,OAAO;oBAAE,OAAO,UAAU,CAAC;YAC7C,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,gEAAgE;QAChE,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YACxC,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,GAAG,EAAE,EAAE,CAAC;YACzE,CAAC;YACD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACtF,IAAI,CAAC,UAAU,CAAC,OAAO;gBAAE,OAAO,UAAU,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;YAC/C,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QAC/C,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,iBAAiB,CAAC,GAAW;QAC3B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAsB;QAC7B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEO,WAAW,CAAC,GAAW;QAC7B,OAAO,gCAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAEO,MAAM,CAAC,GAAW;QACxB,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QACvC,OAAO,iCAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;CACF;AAtFD,4CAsFC;AAED,qEAAqE;AAC9D,KAAK,UAAU,OAAO,CAAC,OAAe;IAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,OAAO,SAAS,CAAC,CAAC;IAChD,6EAA6E;IAC7E,2EAA2E;IAC3E,MAAM,iBAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAoC,CAAC;IAChG,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,MAAM,EAAE,GAAG,kBAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACtF,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE;YACzB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,gEAAgE;YAChE,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;gBACzC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACrC,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/safety/permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * SSRF guard for the outbound HTTP tools (web_fetch, http_request).
3
+ *
4
+ * Without this, the agent can be steered — including by prompt injection in a
5
+ * fetched page — to reach loopback services, RFC-1918 hosts, or the cloud
6
+ * metadata endpoint (169.254.169.254) to steal IAM credentials, then exfil
7
+ * them back out. We reject private/loopback/link-local targets, restrict the
8
+ * protocol to http/https, and re-validate on every redirect hop.
9
+ */
10
+ export declare class SsrfError extends Error {
11
+ constructor(message: string);
12
+ }
13
+ /** True if the literal IP is one we refuse to connect to. Unknown → blocked. */
14
+ export declare function isBlockedIp(ip: string): boolean;
15
+ /**
16
+ * Validate a URL for outbound use: http/https only, and its host must not
17
+ * resolve to a blocked address. Returns the parsed URL on success.
18
+ */
19
+ export declare function assertUrlAllowed(rawUrl: string): Promise<URL>;
20
+ export interface SafeFetchOptions {
21
+ maxRedirects?: number;
22
+ }
23
+ /**
24
+ * fetch() wrapper that enforces {@link assertUrlAllowed} before the request
25
+ * and on every redirect hop. Redirects are followed manually (redirect:
26
+ * 'manual') so a public URL can't 302 to a private/metadata address without
27
+ * being re-checked.
28
+ */
29
+ export declare function safeFetch(rawUrl: string, init: RequestInit, opts?: SafeFetchOptions): Promise<Response>;
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SsrfError = void 0;
37
+ exports.isBlockedIp = isBlockedIp;
38
+ exports.assertUrlAllowed = assertUrlAllowed;
39
+ exports.safeFetch = safeFetch;
40
+ const dns = __importStar(require("dns"));
41
+ const net = __importStar(require("net"));
42
+ /**
43
+ * SSRF guard for the outbound HTTP tools (web_fetch, http_request).
44
+ *
45
+ * Without this, the agent can be steered — including by prompt injection in a
46
+ * fetched page — to reach loopback services, RFC-1918 hosts, or the cloud
47
+ * metadata endpoint (169.254.169.254) to steal IAM credentials, then exfil
48
+ * them back out. We reject private/loopback/link-local targets, restrict the
49
+ * protocol to http/https, and re-validate on every redirect hop.
50
+ */
51
+ class SsrfError extends Error {
52
+ constructor(message) {
53
+ super(message);
54
+ this.name = 'SsrfError';
55
+ }
56
+ }
57
+ exports.SsrfError = SsrfError;
58
+ const BLOCKED_HOSTNAMES = new Set([
59
+ 'localhost',
60
+ 'ip6-localhost',
61
+ 'ip6-loopback',
62
+ ]);
63
+ function isBlockedV4(ip) {
64
+ const parts = ip.split('.').map(Number);
65
+ if (parts.length !== 4 || parts.some((o) => !Number.isInteger(o) || o < 0 || o > 255)) {
66
+ return true; // malformed → block
67
+ }
68
+ const [a, b] = parts;
69
+ if (a === 0)
70
+ return true; // 0.0.0.0/8 "this host"
71
+ if (a === 10)
72
+ return true; // 10.0.0.0/8 private
73
+ if (a === 127)
74
+ return true; // 127.0.0.0/8 loopback
75
+ if (a === 169 && b === 254)
76
+ return true; // 169.254.0.0/16 link-local (incl. metadata)
77
+ if (a === 172 && b >= 16 && b <= 31)
78
+ return true; // 172.16.0.0/12 private
79
+ if (a === 192 && b === 168)
80
+ return true; // 192.168.0.0/16 private
81
+ if (a === 192 && b === 0 && parts[2] === 0)
82
+ return true; // 192.0.0.0/24 protocol assignments
83
+ if (a === 100 && b >= 64 && b <= 127)
84
+ return true; // 100.64.0.0/10 CGNAT
85
+ if (a === 198 && (b === 18 || b === 19))
86
+ return true; // 198.18.0.0/15 benchmarking
87
+ if (a >= 224)
88
+ return true; // 224.0.0.0/4 multicast + 240.0.0.0/4 reserved
89
+ return false;
90
+ }
91
+ function isBlockedV6(ip) {
92
+ let addr = ip.toLowerCase();
93
+ const zone = addr.indexOf('%');
94
+ if (zone >= 0)
95
+ addr = addr.slice(0, zone);
96
+ if (addr === '::1' || addr === '::')
97
+ return true; // loopback / unspecified
98
+ // IPv4-mapped (::ffff:a.b.c.d) — evaluate the embedded IPv4.
99
+ const mapped = addr.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
100
+ if (mapped)
101
+ return isBlockedV4(mapped[1]);
102
+ if (addr.startsWith('fe8') || addr.startsWith('fe9')
103
+ || addr.startsWith('fea') || addr.startsWith('feb'))
104
+ return true; // fe80::/10 link-local
105
+ if (addr.startsWith('fc') || addr.startsWith('fd'))
106
+ return true; // fc00::/7 unique-local
107
+ if (addr.startsWith('ff'))
108
+ return true; // ff00::/8 multicast
109
+ return false;
110
+ }
111
+ /** True if the literal IP is one we refuse to connect to. Unknown → blocked. */
112
+ function isBlockedIp(ip) {
113
+ const kind = net.isIP(ip);
114
+ if (kind === 4)
115
+ return isBlockedV4(ip);
116
+ if (kind === 6)
117
+ return isBlockedV6(ip);
118
+ return true;
119
+ }
120
+ /**
121
+ * Validate a URL for outbound use: http/https only, and its host must not
122
+ * resolve to a blocked address. Returns the parsed URL on success.
123
+ */
124
+ async function assertUrlAllowed(rawUrl) {
125
+ let url;
126
+ try {
127
+ url = new URL(rawUrl);
128
+ }
129
+ catch {
130
+ throw new SsrfError(`Invalid URL: ${rawUrl}`);
131
+ }
132
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
133
+ throw new SsrfError(`Blocked protocol: ${url.protocol} (only http/https allowed)`);
134
+ }
135
+ const host = url.hostname.replace(/^\[|\]$/g, ''); // strip IPv6 brackets
136
+ if (net.isIP(host)) {
137
+ if (isBlockedIp(host))
138
+ throw new SsrfError(`Blocked address: ${host}`);
139
+ return url;
140
+ }
141
+ if (BLOCKED_HOSTNAMES.has(host.toLowerCase())) {
142
+ throw new SsrfError(`Blocked host: ${host}`);
143
+ }
144
+ let addrs;
145
+ try {
146
+ addrs = await dns.promises.lookup(host, { all: true });
147
+ }
148
+ catch {
149
+ throw new SsrfError(`Could not resolve host: ${host}`);
150
+ }
151
+ if (addrs.length === 0)
152
+ throw new SsrfError(`Could not resolve host: ${host}`);
153
+ for (const a of addrs) {
154
+ if (isBlockedIp(a.address)) {
155
+ throw new SsrfError(`Host ${host} resolves to blocked address ${a.address}`);
156
+ }
157
+ }
158
+ return url;
159
+ }
160
+ /**
161
+ * fetch() wrapper that enforces {@link assertUrlAllowed} before the request
162
+ * and on every redirect hop. Redirects are followed manually (redirect:
163
+ * 'manual') so a public URL can't 302 to a private/metadata address without
164
+ * being re-checked.
165
+ */
166
+ async function safeFetch(rawUrl, init, opts = {}) {
167
+ const maxRedirects = opts.maxRedirects ?? 5;
168
+ let currentUrl = rawUrl;
169
+ let redirects = 0;
170
+ while (true) {
171
+ await assertUrlAllowed(currentUrl);
172
+ const response = await fetch(currentUrl, { ...init, redirect: 'manual' });
173
+ const isRedirect = response.status >= 300 && response.status < 400;
174
+ const location = response.headers.get('location');
175
+ if (isRedirect && location) {
176
+ if (redirects >= maxRedirects)
177
+ throw new SsrfError('Too many redirects');
178
+ redirects++;
179
+ currentUrl = new URL(location, currentUrl).toString();
180
+ continue;
181
+ }
182
+ return response;
183
+ }
184
+ }
185
+ //# sourceMappingURL=ssrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../src/safety/ssrf.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,kCAKC;AAMD,4CAiCC;AAYD,8BAuBC;AA9ID,yCAA2B;AAC3B,yCAA2B;AAE3B;;;;;;;;GAQG;AACH,MAAa,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AALD,8BAKC;AAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,WAAW;IACX,eAAe;IACf,cAAc;CACf,CAAC,CAAC;AAEH,SAAS,WAAW,CAAC,EAAU;IAC7B,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;QACtF,OAAO,IAAI,CAAC,CAAC,oBAAoB;IACnC,CAAC;IACD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAuB,wBAAwB;IACxE,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC,CAAsB,qBAAqB;IACrE,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAqB,uBAAuB;IACvE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAQ,6CAA6C;IAC7F,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,IAAI,CAAC,CAAC,wBAAwB;IAC1E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC,CAAQ,yBAAyB;IACzE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,oCAAoC;IAC7F,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC,CAAC,sBAAsB;IACzE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,6BAA6B;IACnF,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC,CAAsB,+CAA+C;IAC/F,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,EAAU;IAC7B,IAAI,IAAI,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,IAAI,IAAI,CAAC;QAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAE1C,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,CAAC,yBAAyB;IAE3E,6DAA6D;IAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC3D,IAAI,MAAM;QAAE,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1C,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;WAC/C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,uBAAuB;IAC3F,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAI,wBAAwB;IAC5F,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAA6B,qBAAqB;IACzF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,gFAAgF;AAChF,SAAgB,WAAW,CAAC,EAAU;IACpC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;IACvC,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,gBAAgB,CAAC,MAAc;IACnD,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QAAC,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IAC9B,MAAM,CAAC;QAAC,MAAM,IAAI,SAAS,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;IAAC,CAAC;IAExD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,SAAS,CAAC,qBAAqB,GAAG,CAAC,QAAQ,4BAA4B,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB;IAEzE,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,WAAW,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC;QACvE,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,SAAS,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,KAA4B,CAAC;IACjC,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IAC/E,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,SAAS,CAAC,QAAQ,IAAI,gCAAgC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAMD;;;;;GAKG;AACI,KAAK,UAAU,SAAS,CAC7B,MAAc,EACd,IAAiB,EACjB,OAAyB,EAAE;IAE3B,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;IAC5C,IAAI,UAAU,GAAG,MAAM,CAAC;IACxB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE1E,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC;QACnE,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,SAAS,IAAI,YAAY;gBAAE,MAAM,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;YACzE,SAAS,EAAE,CAAC;YACZ,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;YACtD,SAAS;QACX,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC"}