@vybestack/llxprt-code 0.10.0 → 0.11.0-nightly.260728.ffaa8d5d7

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 (126) hide show
  1. package/package.json +13 -13
  2. package/src/commands/mcp/add.ts +8 -4
  3. package/src/config/cliArgParser.ts +2 -0
  4. package/src/config/config.ts +2 -0
  5. package/src/config/configBuilder.ts +3 -0
  6. package/src/config/configError.ts +23 -0
  7. package/src/config/extensions/extensionEnablement.ts +62 -1
  8. package/src/config/interactiveContext.ts +2 -1
  9. package/src/config/intermediateConfig.ts +4 -0
  10. package/src/config/keyBindings.ts +29 -3
  11. package/src/config/policy.ts +7 -1
  12. package/src/config/postConfigRuntime.ts +20 -14
  13. package/src/config/settings-schema/schema-ui.ts +9 -0
  14. package/src/config/settingsLoader.ts +21 -17
  15. package/src/config/settingsSchema.ts +2 -2
  16. package/src/config/trustedFolders.ts +275 -58
  17. package/src/config/yargsOptions.ts +7 -0
  18. package/src/generated/git-commit.json +1 -1
  19. package/src/nonInteractiveCli.ts +1 -0
  20. package/src/nonInteractiveCliSupport.ts +171 -51
  21. package/src/runtime/interactiveToolScheduler.ts +6 -6
  22. package/src/services/BuiltinCommandLoader.ts +33 -25
  23. package/src/services/FileCommandLoader.ts +34 -7
  24. package/src/test-utils/async.ts +20 -0
  25. package/src/test-utils/render.tsx +10 -1
  26. package/src/ui/App.tsx +17 -10
  27. package/src/ui/AppContainerRuntime.tsx +7 -9
  28. package/src/ui/cliUiRuntime.ts +28 -0
  29. package/src/ui/commands/authCommand.ts +240 -3
  30. package/src/ui/commands/compressCommand.ts +9 -1
  31. package/src/ui/commands/directoryCommand.tsx +1 -1
  32. package/src/ui/commands/logoutCommand.ts +2 -2
  33. package/src/ui/commands/permissionsCommand.ts +77 -20
  34. package/src/ui/commands/policiesCommand.ts +6 -1
  35. package/src/ui/commands/quotaCommand.ts +501 -0
  36. package/src/ui/commands/statsCommand.ts +2 -2
  37. package/src/ui/commands/statsQuota.ts +1 -1
  38. package/src/ui/commands/subagentCommand.ts +59 -27
  39. package/src/ui/components/AuthDialog.tsx +3 -3
  40. package/src/ui/components/Composer.tsx +1 -0
  41. package/src/ui/components/DialogManager.tsx +9 -2
  42. package/src/ui/components/FolderTrustDialog.tsx +71 -60
  43. package/src/ui/components/PermissionsModifyTrustDialog.tsx +211 -146
  44. package/src/ui/components/ProfileCreateWizard/constants.ts +13 -1
  45. package/src/ui/components/QueuedMessagesPanel.tsx +388 -0
  46. package/src/ui/components/inputPromptHooks.ts +2 -0
  47. package/src/ui/components/inputPromptKeyHandlers.ts +14 -0
  48. package/src/ui/components/inputPromptTypes.ts +6 -0
  49. package/src/ui/components/messages/AiMessage.tsx +24 -12
  50. package/src/ui/components/messages/ToolMessage.tsx +26 -40
  51. package/src/ui/containers/AppContainer/builders/buildUIActions.ts +3 -1
  52. package/src/ui/containers/AppContainer/builders/buildUIState.ts +5 -4
  53. package/src/ui/containers/AppContainer/hooks/useAppBootstrap.ts +3 -33
  54. package/src/ui/containers/AppContainer/hooks/useAppDialogs.ts +2 -14
  55. package/src/ui/containers/AppContainer/hooks/useAppInput.ts +31 -25
  56. package/src/ui/containers/AppContainer/hooks/useAppLayout.ts +90 -60
  57. package/src/ui/containers/AppContainer/hooks/useDisplayPreferences.ts +10 -0
  58. package/src/ui/containers/AppContainer/hooks/useInputHandling.ts +3 -17
  59. package/src/ui/containers/AppContainer/hooks/useKeybindings.ts +51 -38
  60. package/src/ui/containers/AppContainer/hooks/useSteer.ts +51 -0
  61. package/src/ui/contexts/KeypressContext.tsx +13 -2
  62. package/src/ui/contexts/ShellCommandDisplayContext.tsx +103 -0
  63. package/src/ui/contexts/TodoContext.tsx +0 -13
  64. package/src/ui/contexts/TodoProvider.tsx +1 -34
  65. package/src/ui/contexts/UIActionsContext.tsx +2 -1
  66. package/src/ui/contexts/UIStateContext.tsx +3 -2
  67. package/src/ui/hooks/agentStream/streamUtils.ts +0 -24
  68. package/src/ui/hooks/agentStream/thoughtState.ts +110 -30
  69. package/src/ui/hooks/agentStream/types.ts +1 -0
  70. package/src/ui/hooks/agentStream/useAgentEventStream.ts +8 -17
  71. package/src/ui/hooks/agentStream/useAgentStream.ts +2 -2
  72. package/src/ui/hooks/agentStream/useAgentStreamLifecycle.ts +4 -5
  73. package/src/ui/hooks/agentStream/useAgentStreamOrchestration.ts +12 -5
  74. package/src/ui/hooks/agentStream/useQueuedSubmissions.ts +99 -0
  75. package/src/ui/hooks/agentStream/useStreamEventHandlers.ts +4 -13
  76. package/src/ui/hooks/agentStream/useStreamState.ts +60 -41
  77. package/src/ui/hooks/agentStream/useSubmitQuery.ts +284 -59
  78. package/src/ui/hooks/slashCommandProcessorSupport.ts +4 -0
  79. package/src/ui/hooks/useAgentStream-test-helpers.ts +1 -0
  80. package/src/ui/hooks/useAutoAcceptIndicator.ts +13 -0
  81. package/src/ui/hooks/useFolderTrust.ts +118 -81
  82. package/src/ui/hooks/useGitBranchName.ts +79 -33
  83. package/src/ui/hooks/useIdeTrustListener.ts +5 -19
  84. package/src/ui/hooks/usePermissionsModifyTrust.ts +223 -85
  85. package/src/ui/hooks/useReactToolScheduler.ts +13 -17
  86. package/src/ui/hooks/useTodoPausePreserver.ts +0 -55
  87. package/src/ui/layouts/DefaultAppLayout.tsx +2 -0
  88. package/src/ui/layouts/DefaultAppLayoutHelpers.tsx +37 -162
  89. package/src/ui/layouts/InlineContent.tsx +198 -0
  90. package/src/ui/trustDialogHelpers.ts +190 -0
  91. package/src/utils/cleanup-state.ts +115 -0
  92. package/src/utils/cleanup.ts +32 -34
  93. package/src/utils/sandbox-containers.ts +183 -53
  94. package/src/utils/sandbox-exec.ts +9 -3
  95. package/src/zed-integration/acp-terminal-shell-host.ts +112 -0
  96. package/src/zed-integration/acp-types.ts +35 -0
  97. package/src/zed-integration/fileSystemService.ts +1 -1
  98. package/src/zed-integration/runZedIntegration.ts +142 -0
  99. package/src/zed-integration/zed-agent-event-handler.ts +179 -0
  100. package/src/zed-integration/zed-agent-setup.ts +43 -0
  101. package/src/zed-integration/zed-command-registry.ts +167 -0
  102. package/src/zed-integration/zed-config-options.ts +280 -0
  103. package/src/zed-integration/zed-content-utils.ts +2 -2
  104. package/src/zed-integration/zed-helpers.ts +132 -0
  105. package/src/zed-integration/zed-initialize.ts +64 -0
  106. package/src/zed-integration/zed-plan-update.ts +20 -0
  107. package/src/zed-integration/zed-prompt-command.ts +77 -0
  108. package/src/zed-integration/zed-session-config.ts +119 -0
  109. package/src/zed-integration/zed-session-errors.ts +337 -0
  110. package/src/zed-integration/zed-session-events.ts +216 -0
  111. package/src/zed-integration/zed-session-info.ts +255 -0
  112. package/src/zed-integration/zed-session-lifecycle.ts +186 -0
  113. package/src/zed-integration/zed-session-listing.ts +153 -0
  114. package/src/zed-integration/zed-session-loader.ts +193 -0
  115. package/src/zed-integration/zed-session-pagination.ts +240 -0
  116. package/src/zed-integration/zed-session-replay.ts +564 -0
  117. package/src/zed-integration/zed-stream-batcher.ts +236 -0
  118. package/src/zed-integration/zed-terminal-manager.ts +416 -0
  119. package/src/zed-integration/zed-terminal-setup.ts +72 -0
  120. package/src/zed-integration/zed-test-helpers.ts +349 -4
  121. package/src/zed-integration/zed-tool-handler.ts +47 -5
  122. package/src/zed-integration/zedIntegration.ts +538 -587
  123. package/src/services/todo-continuation/todoContinuationService.ts +0 -610
  124. package/src/ui/containers/AppContainer/hooks/useIdeRestartHotkey.ts +0 -33
  125. package/src/ui/containers/AppContainer/hooks/useTodoContinuationFlow.ts +0 -160
  126. package/src/ui/hooks/useTodoContinuation.ts +0 -299
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ import { randomUUID } from 'node:crypto';
7
8
  import * as fs from 'node:fs';
8
9
  import * as path from 'node:path';
9
10
  import {
@@ -13,7 +14,9 @@ import {
13
14
  getIdeTrust,
14
15
  } from '@vybestack/llxprt-code-core';
15
16
  import stripJsonComments from 'strip-json-comments';
17
+ import { debugLogger } from '@vybestack/llxprt-code-telemetry';
16
18
  import type { Settings } from './settings.js';
19
+ import { formatConfigFileErrors } from './configError.js';
17
20
  import { USER_SETTINGS_DIR } from './paths.js';
18
21
 
19
22
  export const TRUSTED_FOLDERS_FILENAME = 'trustedFolders.json';
@@ -43,6 +46,13 @@ export interface TrustRule {
43
46
  trustLevel: TrustLevel;
44
47
  }
45
48
 
49
+ export interface ResolvedTrustRule {
50
+ readonly rule: TrustRule;
51
+ readonly effectivePath: string;
52
+ readonly trusted: boolean;
53
+ readonly provenance: 'direct' | 'inherited';
54
+ }
55
+
46
56
  export interface TrustedFoldersError {
47
57
  message: string;
48
58
  path: string;
@@ -53,6 +63,37 @@ export interface TrustedFoldersFile {
53
63
  path: string;
54
64
  }
55
65
 
66
+ export interface TrustedFolderSnapshot {
67
+ readonly canonicalPath: string;
68
+ readonly entries: ReadonlyArray<readonly [string, TrustLevel]>;
69
+ }
70
+
71
+ function resolveCanonicalPath(location: string): string | undefined {
72
+ try {
73
+ return fs.realpathSync(path.resolve(location));
74
+ } catch {
75
+ return undefined;
76
+ }
77
+ }
78
+
79
+ function requireCanonicalPath(location: string): string {
80
+ const canonicalPath = resolveCanonicalPath(location);
81
+ if (canonicalPath === undefined) {
82
+ throw new Error(`Unable to resolve canonical path for "${location}".`);
83
+ }
84
+ return canonicalPath;
85
+ }
86
+
87
+ function restoreConfigInPlace(
88
+ target: Record<string, TrustLevel>,
89
+ snapshot: Readonly<Record<string, TrustLevel>>,
90
+ ): void {
91
+ for (const key of Object.keys(target)) {
92
+ delete target[key];
93
+ }
94
+ Object.assign(target, snapshot);
95
+ }
96
+
56
97
  export class LoadedTrustedFolders {
57
98
  constructor(
58
99
  readonly user: TrustedFoldersFile,
@@ -74,54 +115,142 @@ export class LoadedTrustedFolders {
74
115
  * @returns
75
116
  */
76
117
  isPathTrusted(location: string): boolean | undefined {
77
- const trustedPaths: string[] = [];
78
- const untrustedPaths: string[] = [];
79
-
80
- for (const rule of this.rules) {
81
- switch (rule.trustLevel) {
82
- case TrustLevel.TRUST_FOLDER:
83
- trustedPaths.push(rule.path);
84
- break;
85
- case TrustLevel.TRUST_PARENT:
86
- trustedPaths.push(path.dirname(rule.path));
87
- break;
88
- case TrustLevel.DO_NOT_TRUST:
89
- untrustedPaths.push(rule.path);
90
- break;
91
- default:
92
- // Do nothing for unknown trust levels.
93
- break;
94
- }
95
- }
118
+ return this.resolvePathTrust(location)?.trusted;
119
+ }
96
120
 
97
- for (const trustedPath of trustedPaths) {
98
- if (isWithinRoot(location, trustedPath)) {
99
- return true;
100
- }
121
+ resolvePathTrust(location: string): ResolvedTrustRule | undefined {
122
+ const resolvedLocation = resolveCanonicalPath(location);
123
+ if (resolvedLocation === undefined) {
124
+ return undefined;
101
125
  }
102
-
103
- for (const untrustedPath of untrustedPaths) {
104
- if (path.normalize(location) === path.normalize(untrustedPath)) {
105
- return false;
126
+ const matches = this.rules.flatMap((rule) => {
127
+ const canonicalRulePath = resolveCanonicalPath(rule.path);
128
+ if (canonicalRulePath === undefined) {
129
+ if (rule.trustLevel !== TrustLevel.DO_NOT_TRUST) {
130
+ return [];
131
+ }
132
+ const effectivePath = path.resolve(rule.path);
133
+ const lexicalLocation = path.resolve(location);
134
+ if (
135
+ !isWithinRoot(lexicalLocation, effectivePath) &&
136
+ !isWithinRoot(resolvedLocation, effectivePath)
137
+ ) {
138
+ return [];
139
+ }
140
+ return [
141
+ {
142
+ rule,
143
+ effectivePath,
144
+ trusted: false,
145
+ provenance:
146
+ lexicalLocation === effectivePath
147
+ ? ('direct' as const)
148
+ : ('inherited' as const),
149
+ },
150
+ ];
106
151
  }
152
+ const effectivePath =
153
+ rule.trustLevel === TrustLevel.TRUST_PARENT
154
+ ? path.dirname(canonicalRulePath)
155
+ : canonicalRulePath;
156
+ if (!isWithinRoot(resolvedLocation, effectivePath)) {
157
+ return [];
158
+ }
159
+ return [
160
+ {
161
+ rule,
162
+ effectivePath,
163
+ trusted: rule.trustLevel !== TrustLevel.DO_NOT_TRUST,
164
+ provenance:
165
+ resolvedLocation === effectivePath
166
+ ? ('direct' as const)
167
+ : ('inherited' as const),
168
+ },
169
+ ];
170
+ });
171
+
172
+ // The most specific rule wins; at equal specificity, denial wins so an
173
+ // ambiguous configuration cannot accidentally grant trust.
174
+ matches.sort((left, right) => {
175
+ const specificity =
176
+ right.effectivePath.length - left.effectivePath.length;
177
+ return specificity !== 0
178
+ ? specificity
179
+ : Number(left.trusted) - Number(right.trusted);
180
+ });
181
+ return matches[0];
182
+ }
183
+
184
+ getValue(location: string): TrustLevel | undefined {
185
+ const canonicalPath = resolveCanonicalPath(location);
186
+ return canonicalPath === undefined
187
+ ? undefined
188
+ : this.user.config[canonicalPath];
189
+ }
190
+
191
+ private aliasesFor(canonicalPath: string): string[] {
192
+ return Object.keys(this.user.config).filter(
193
+ (rulePath) => resolveCanonicalPath(rulePath) === canonicalPath,
194
+ );
195
+ }
196
+
197
+ snapshotValue(location: string): TrustedFolderSnapshot {
198
+ const canonicalPath = requireCanonicalPath(location);
199
+ const aliases = new Set(this.aliasesFor(canonicalPath));
200
+ return {
201
+ canonicalPath,
202
+ entries: Object.entries(this.user.config).filter(([rulePath]) =>
203
+ aliases.has(rulePath),
204
+ ),
205
+ };
206
+ }
207
+
208
+ restoreSnapshot(snapshot: TrustedFolderSnapshot): void {
209
+ const originalConfig = { ...this.user.config };
210
+ for (const rulePath of this.aliasesFor(snapshot.canonicalPath)) {
211
+ delete this.user.config[rulePath];
212
+ }
213
+ for (const [rulePath, trustLevel] of snapshot.entries) {
214
+ this.user.config[rulePath] = trustLevel;
107
215
  }
216
+ try {
217
+ saveTrustedFolders(this.user);
218
+ } catch (e) {
219
+ restoreConfigInPlace(this.user.config, originalConfig);
220
+ throw e;
221
+ }
222
+ }
108
223
 
109
- return undefined;
224
+ setValue(location: string, trustLevel: TrustLevel): void {
225
+ const canonicalPath = requireCanonicalPath(location);
226
+ const originalConfig = { ...this.user.config };
227
+ const aliases = this.aliasesFor(canonicalPath);
228
+ for (const alias of aliases) {
229
+ delete this.user.config[alias];
230
+ }
231
+ this.user.config[canonicalPath] = trustLevel;
232
+ try {
233
+ saveTrustedFolders(this.user);
234
+ } catch (e) {
235
+ restoreConfigInPlace(this.user.config, originalConfig);
236
+ throw e;
237
+ }
110
238
  }
111
239
 
112
- setValue(path: string, trustLevel: TrustLevel): void {
113
- const hadOriginalTrustLevel = Object.hasOwn(this.user.config, path);
114
- const originalTrustLevel = this.user.config[path];
115
- this.user.config[path] = trustLevel;
240
+ deleteValue(location: string): void {
241
+ const canonicalPath = requireCanonicalPath(location);
242
+ const originalConfig = { ...this.user.config };
243
+ const aliases = this.aliasesFor(canonicalPath);
244
+ if (aliases.length === 0) {
245
+ return;
246
+ }
247
+ for (const alias of aliases) {
248
+ delete this.user.config[alias];
249
+ }
116
250
  try {
117
251
  saveTrustedFolders(this.user);
118
252
  } catch (e) {
119
- // Revert the in-memory change if the save failed.
120
- if (!hadOriginalTrustLevel) {
121
- delete this.user.config[path];
122
- } else {
123
- this.user.config[path] = originalTrustLevel;
124
- }
253
+ restoreConfigInPlace(this.user.config, originalConfig);
125
254
  throw e;
126
255
  }
127
256
  }
@@ -185,6 +314,50 @@ export function loadTrustedFolders(): LoadedTrustedFolders {
185
314
  return loadedTrustedFolders;
186
315
  }
187
316
 
317
+ function removeTemporaryFile(temporaryPath: string): void {
318
+ try {
319
+ fs.unlinkSync(temporaryPath);
320
+ } catch (error) {
321
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
322
+ debugLogger.warn(
323
+ `Failed to remove trusted folders temporary file ${temporaryPath}:`,
324
+ error,
325
+ );
326
+ }
327
+ }
328
+ }
329
+
330
+ function isUnsupportedFileModeError(error: unknown): boolean {
331
+ if (!(error instanceof Error) || !('code' in error)) {
332
+ return false;
333
+ }
334
+ return (
335
+ error.code === 'ENOSYS' ||
336
+ error.code === 'ENOTSUP' ||
337
+ error.code === 'EOPNOTSUPP'
338
+ );
339
+ }
340
+
341
+ function secureTemporaryFileMode(temporaryPath: string): void {
342
+ try {
343
+ fs.chmodSync(temporaryPath, 0o600);
344
+ const temporaryMode = fs.statSync(temporaryPath).mode & 0o777;
345
+ if (temporaryMode !== 0o600) {
346
+ throw new Error(
347
+ `Trusted folders temporary file has mode ${temporaryMode.toString(8)} instead of 600.`,
348
+ );
349
+ }
350
+ } catch (error) {
351
+ if (!isUnsupportedFileModeError(error)) {
352
+ throw error;
353
+ }
354
+ debugLogger.warn(
355
+ `Filesystem for trusted folders does not support POSIX file modes; continuing with the mode requested at file creation for ${temporaryPath}:`,
356
+ error,
357
+ );
358
+ }
359
+ }
360
+
188
361
  export function saveTrustedFolders(
189
362
  trustedFoldersFile: TrustedFoldersFile,
190
363
  ): void {
@@ -194,11 +367,32 @@ export function saveTrustedFolders(
194
367
  fs.mkdirSync(dirPath, { recursive: true });
195
368
  }
196
369
 
197
- fs.writeFileSync(
198
- trustedFoldersFile.path,
199
- JSON.stringify(trustedFoldersFile.config, null, 2),
200
- { encoding: 'utf-8', mode: 0o600 },
370
+ const temporaryPath = path.join(
371
+ dirPath,
372
+ `.${path.basename(trustedFoldersFile.path)}.${process.pid}.${randomUUID()}.tmp`,
201
373
  );
374
+ try {
375
+ fs.writeFileSync(
376
+ temporaryPath,
377
+ JSON.stringify(trustedFoldersFile.config, null, 2),
378
+ { encoding: 'utf-8', mode: 0o600, flag: 'wx' },
379
+ );
380
+ if (process.platform !== 'win32') {
381
+ secureTemporaryFileMode(temporaryPath);
382
+ }
383
+ } catch (error) {
384
+ removeTemporaryFile(temporaryPath);
385
+ throw error;
386
+ }
387
+
388
+ // Atomic replacement is the commit point; nothing fallible may follow it on
389
+ // success. A failed commit still owns the temporary file and must remove it.
390
+ try {
391
+ fs.renameSync(temporaryPath, trustedFoldersFile.path);
392
+ } catch (error) {
393
+ removeTemporaryFile(temporaryPath);
394
+ throw error;
395
+ }
202
396
  }
203
397
 
204
398
  /** Is folder trust feature enabled per the current applied settings */
@@ -208,33 +402,56 @@ export function isFolderTrustEnabled(settings: Settings): boolean {
208
402
  return folderTrustSetting;
209
403
  }
210
404
 
211
- function getWorkspaceTrustFromLocalConfig(): boolean | undefined {
212
- const folders = loadTrustedFolders();
213
-
214
- if (folders.errors.length > 0) {
215
- const errorMessages = folders.errors.map(
216
- (error) => `Error in ${error.path}: ${error.message}`,
217
- );
218
- throw new FatalConfigError(
219
- `${errorMessages.join('\n')}\nPlease fix the configuration file and try again.`,
220
- );
405
+ export function resolveWorkspaceTrust(
406
+ settings: Settings,
407
+ trustedFolders: LoadedTrustedFolders,
408
+ workingDirectory: string,
409
+ ideTrust: boolean | undefined = getIdeTrust(),
410
+ ): boolean | undefined {
411
+ if (!isFolderTrustEnabled(settings)) {
412
+ return true;
221
413
  }
222
-
223
- return folders.isPathTrusted(process.cwd());
414
+ if (ideTrust !== undefined) {
415
+ return ideTrust;
416
+ }
417
+ return trustedFolders.isPathTrusted(workingDirectory);
224
418
  }
225
419
 
226
- export function isWorkspaceTrusted(settings: Settings): boolean | undefined {
420
+ export function resolveLocalWorkspaceTrust(
421
+ settings: Settings,
422
+ trustedFolders: LoadedTrustedFolders,
423
+ workingDirectory: string,
424
+ ): boolean | undefined {
227
425
  if (!isFolderTrustEnabled(settings)) {
228
426
  return true;
229
427
  }
428
+ return trustedFolders.isPathTrusted(workingDirectory);
429
+ }
230
430
 
231
- const ideTrust = getIdeTrust();
431
+ export function isWorkspaceTrusted(
432
+ settings: Settings,
433
+ workingDirectory: string = process.cwd(),
434
+ ideTrust: boolean | undefined = getIdeTrust(),
435
+ ): boolean | undefined {
436
+ if (!isFolderTrustEnabled(settings)) {
437
+ return true;
438
+ }
232
439
  if (ideTrust !== undefined) {
233
440
  return ideTrust;
234
441
  }
235
442
 
236
- // Fall back to the local user configuration
237
- return getWorkspaceTrustFromLocalConfig();
443
+ const trustedFolders = loadTrustedFolders();
444
+ if (trustedFolders.errors.length > 0) {
445
+ throw new FatalConfigError(
446
+ formatConfigFileErrors(trustedFolders.errors, 'configuration file'),
447
+ );
448
+ }
449
+ return resolveWorkspaceTrust(
450
+ settings,
451
+ trustedFolders,
452
+ workingDirectory,
453
+ ideTrust,
454
+ );
238
455
  }
239
456
 
240
457
  /**
@@ -207,6 +207,13 @@ export const innerCommandOptions: Record<string, Options> = {
207
207
  description:
208
208
  'Output format for non-interactive mode (text, json, or stream-json).',
209
209
  },
210
+ quiet: {
211
+ alias: 'q',
212
+ type: 'boolean',
213
+ description:
214
+ 'Suppress tool calls, tool results, and intermediate text. Only the final response is written to stdout (non-interactive mode).',
215
+ default: false,
216
+ },
210
217
  sandbox: {
211
218
  alias: 's',
212
219
  type: 'boolean',
@@ -1,3 +1,3 @@
1
1
  {
2
- "commit": "2d228fb17"
2
+ "commit": "ffaa8d5d7"
3
3
  }
@@ -368,6 +368,7 @@ async function processQuery(
368
368
  config: params.config,
369
369
  jsonOutput: options.jsonOutput,
370
370
  streamJsonOutput: options.streamJsonOutput,
371
+ quiet: params.config.getQuiet(),
371
372
  streamFormatter: options.streamFormatter,
372
373
  emojiFilter: options.emojiFilter,
373
374
  createProfileNameWriter: () =>