Compare commits

...

12 Commits

Author SHA1 Message Date
gemini-cli-robot 545e956c3c chore(release): v0.37.2 2026-04-13 20:12:28 +00:00
gemini-cli-robot 256584d147 fix(patch): cherry-pick 9d741ab to release/v0.37.1-pr-24565 to patch version v0.37.1 and create version 0.37.2 (#25322)
Co-authored-by: Dev Randalpura <devrandalpura@google.com>
2026-04-13 18:59:54 +00:00
gemini-cli-robot 3b2d4f1000 chore(release): v0.37.1 2026-04-09 19:04:09 +00:00
Sri Pasumarthi b569a98c02 feat(acp): add /help command (#24839) 2026-04-09 11:32:27 -07:00
Sri Pasumarthi ea7dfe8914 feat(acp): add support for /about command (#24649) 2026-04-09 11:32:08 -07:00
Sri Pasumarthi 527a08d76a fix(acp): handle all InvalidStreamError types gracefully in prompt (#24540) 2026-04-09 11:31:48 -07:00
gemini-cli-robot 352bbe1493 chore(release): v0.37.0 2026-04-08 17:09:14 +00:00
gemini-cli-robot ae9d4e16a3 chore(release): v0.37.0-preview.2 2026-04-07 19:02:56 +00:00
gemini-cli-robot ac34520776 fix(patch): cherry-pick cb7f7d6 to release/v0.37.0-preview.1-pr-24342 to patch version v0.37.0-preview.1 and create version 0.37.0-preview.2 (#24842)
Co-authored-by: Keith Guerin <keithguerin@gmail.com>
2026-04-07 18:08:35 +00:00
gemini-cli-robot 7cd6dde12a chore(release): v0.37.0-preview.1 2026-04-02 21:02:45 +00:00
gemini-cli-robot 24810f97ef fix(patch): cherry-pick 64c928f to release/v0.37.0-preview.0-pr-23257 to patch version v0.37.0-preview.0 and create version 0.37.0-preview.1 (#24561)
Co-authored-by: Jerop Kipruto <jerop@google.com>
2026-04-02 20:33:06 +00:00
gemini-cli-robot c0f8f3cb7b chore(release): v0.37.0-preview.0 2026-04-01 20:10:18 +00:00
50 changed files with 823 additions and 326 deletions
+10 -3
View File
@@ -180,9 +180,16 @@ As described in the
rule that does not explicitly specify `modes` is considered "always active" and
will apply to Plan Mode as well.
If you want a rule to apply to other modes but _not_ to Plan Mode, you must
explicitly specify the target modes. For example, to allow `npm test` in default
and Auto-Edit modes but not in Plan Mode:
To maintain the integrity of Plan Mode as a safe research environment,
persistent tool approvals are context-aware. Approvals granted in modes like
Default or Auto-Edit do not apply to Plan Mode, ensuring that tools trusted for
implementation don't automatically execute while you're researching. However,
approvals granted while in Plan Mode are treated as intentional choices for
global trust and apply to all modes.
If you want to manually restrict a rule to other modes but _not_ to Plan Mode,
you must explicitly specify the target modes. For example, to allow `npm test`
in default and Auto-Edit modes but not in Plan Mode:
```toml
[[rule]]
+33 -33
View File
@@ -47,39 +47,39 @@ they appear in the UI.
### UI
| UI Label | Setting | Description | Default |
| ------------------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| Auto Theme Switching | `ui.autoThemeSwitching` | Automatically switch between default light and dark themes based on terminal background color. | `true` |
| Terminal Background Polling Interval | `ui.terminalBackgroundPollingInterval` | Interval in seconds to poll the terminal background color. | `60` |
| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` |
| Inline Thinking | `ui.inlineThinkingMode` | Display model thinking inline: off or full. | `"off"` |
| Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` |
| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` |
| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` |
| Show Compatibility Warnings | `ui.showCompatibilityWarnings` | Show warnings about terminal or OS compatibility issues. | `true` |
| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` |
| Escape Pasted @ Symbols | `ui.escapePastedAtSymbols` | When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. | `false` |
| Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `true` |
| Compact Tool Output | `ui.compactToolOutput` | Display tool outputs (like directory listings and file reads) in a compact, structured format. | `false` |
| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` |
| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` |
| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory in the footer. | `false` |
| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` |
| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` |
| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window usage percentage. | `true` |
| Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` |
| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` |
| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` |
| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` |
| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` |
| Show User Identity | `ui.showUserIdentity` | Show the signed-in user's identity (e.g. email) in the UI. | `true` |
| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` |
| Use Background Color | `ui.useBackgroundColor` | Whether to use background colors in the UI. | `true` |
| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` |
| Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` |
| Loading Phrases | `ui.loadingPhrases` | What to show while the model is working: tips, witty comments, both, or nothing. | `"tips"` |
| Error Verbosity | `ui.errorVerbosity` | Controls whether recoverable errors are hidden (low) or fully shown (full). | `"low"` |
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` |
| UI Label | Setting | Description | Default |
| ------------------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| Auto Theme Switching | `ui.autoThemeSwitching` | Automatically switch between default light and dark themes based on terminal background color. | `true` |
| Terminal Background Polling Interval | `ui.terminalBackgroundPollingInterval` | Interval in seconds to poll the terminal background color. | `60` |
| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` |
| Inline Thinking | `ui.inlineThinkingMode` | Display model thinking inline: off or full. | `"off"` |
| Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` |
| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` |
| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` |
| Show Compatibility Warnings | `ui.showCompatibilityWarnings` | Show warnings about terminal or OS compatibility issues. | `true` |
| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` |
| Escape Pasted @ Symbols | `ui.escapePastedAtSymbols` | When enabled, @ symbols in pasted text are escaped to prevent unintended @path expansion. | `false` |
| Show Shortcuts Hint | `ui.showShortcutsHint` | Show the "? for shortcuts" hint above the input. | `true` |
| Compact Tool Output | `ui.compactToolOutput` | Display tool outputs (like directory listings and file reads) in a compact, structured format. | `false` |
| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` |
| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` |
| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory in the footer. | `false` |
| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` |
| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` |
| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window usage percentage. | `true` |
| Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` |
| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` |
| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` |
| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` |
| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` |
| Show User Identity | `ui.showUserIdentity` | Show the signed-in user's identity (e.g. email) in the UI. | `true` |
| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` |
| Use Background Color | `ui.useBackgroundColor` | Whether to use background colors in the UI. | `true` |
| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` |
| Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` |
| Loading Phrases | `ui.loadingPhrases` | What to show while the model is working: tips, witty comments, all, or off. | `"off"` |
| Error Verbosity | `ui.errorVerbosity` | Controls whether recoverable errors are hidden (low) or fully shown (full). | `"low"` |
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` |
### IDE
+2 -2
View File
@@ -354,8 +354,8 @@ their corresponding top-level category object in your `settings.json` file.
- **`ui.loadingPhrases`** (enum):
- **Description:** What to show while the model is working: tips, witty
comments, both, or nothing.
- **Default:** `"tips"`
comments, all, or off.
- **Default:** `"off"`
- **Values:** `"tips"`, `"witty"`, `"all"`, `"off"`
- **`ui.errorVerbosity`** (enum):
+20 -1
View File
@@ -171,6 +171,24 @@ modes specified, it is always active.
[Customizing Plan Mode Policies](../cli/plan-mode.md#customizing-policies).
- `yolo`: A mode where all tools are auto-approved (use with extreme caution).
To maintain the integrity of Plan Mode as a safe research environment,
persistent tool approvals are context-aware. When you select **"Allow for all
future sessions"**, the policy engine explicitly includes the current mode and
all more permissive modes in the hierarchy (`plan` < `default` < `autoEdit` <
`yolo`).
- **Approvals in `plan` mode**: These represent an intentional choice to trust a
tool globally. The resulting rule explicitly includes all modes (`plan`,
`default`, `autoEdit`, and `yolo`).
- **Approvals in other modes**: These only apply to the current mode and those
more permissive. For example:
- An approval granted in **`default`** mode applies to `default`, `autoEdit`,
and `yolo`.
- An approval granted in **`autoEdit`** mode applies to `autoEdit` and `yolo`.
- An approval granted in **`yolo`** mode applies only to `yolo`. This ensures
that trust flows correctly to more permissive environments while maintaining
the safety of more restricted modes like `plan`.
## Rule matching
When a tool call is made, the engine checks it against all active rules,
@@ -304,7 +322,8 @@ priority = 10
denyMessage = "Deletion is permanent"
# (Optional) An array of approval modes where this rule is active.
modes = ["autoEdit"]
# If omitted or empty, the rule applies to all modes.
modes = ["default", "autoEdit", "yolo"]
# (Optional) A boolean to restrict the rule to interactive (true) or
# non-interactive (false) environments.
+9 -9
View File
@@ -1,12 +1,12 @@
{
"name": "@google/gemini-cli",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@google/gemini-cli",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"workspaces": [
"packages/*"
],
@@ -17389,7 +17389,7 @@
},
"packages/a2a-server": {
"name": "@google/gemini-cli-a2a-server",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"dependencies": {
"@a2a-js/sdk": "0.3.11",
"@google-cloud/storage": "^7.16.0",
@@ -17504,7 +17504,7 @@
},
"packages/cli": {
"name": "@google/gemini-cli",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"license": "Apache-2.0",
"dependencies": {
"@agentclientprotocol/sdk": "^0.16.1",
@@ -17676,7 +17676,7 @@
},
"packages/core": {
"name": "@google/gemini-cli-core",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"license": "Apache-2.0",
"dependencies": {
"@a2a-js/sdk": "0.3.11",
@@ -17942,7 +17942,7 @@
},
"packages/devtools": {
"name": "@google/gemini-cli-devtools",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"license": "Apache-2.0",
"dependencies": {
"ws": "^8.16.0"
@@ -17957,7 +17957,7 @@
},
"packages/sdk": {
"name": "@google/gemini-cli-sdk",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"license": "Apache-2.0",
"dependencies": {
"@google/gemini-cli-core": "file:../core",
@@ -17974,7 +17974,7 @@
},
"packages/test-utils": {
"name": "@google/gemini-cli-test-utils",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"license": "Apache-2.0",
"dependencies": {
"@google/gemini-cli-core": "file:../core",
@@ -17991,7 +17991,7 @@
},
"packages/vscode-ide-companion": {
"name": "gemini-cli-vscode-ide-companion",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"license": "LICENSE",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.23.0",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"engines": {
"node": ">=20.0.0"
},
@@ -14,7 +14,7 @@
"url": "git+https://github.com/google-gemini/gemini-cli.git"
},
"config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.36.0-nightly.20260317.2f90b4653"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.37.2"
},
"scripts": {
"start": "cross-env NODE_ENV=development node scripts/start.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-a2a-server",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"description": "Gemini CLI A2A Server",
"repository": {
"type": "git",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"description": "Gemini CLI",
"license": "Apache-2.0",
"repository": {
@@ -27,7 +27,7 @@
"dist"
],
"config": {
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.36.0-nightly.20260317.2f90b4653"
"sandboxImageUri": "us-docker.pkg.dev/gemini-code-dev/gemini-cli/sandbox:0.37.2"
},
"dependencies": {
"@agentclientprotocol/sdk": "^0.16.1",
+26
View File
@@ -875,6 +875,32 @@ describe('Session', () => {
expect(result).toMatchObject({ stopReason: 'end_turn' });
});
it('should handle prompt with no finish reason (InvalidStreamError)', async () => {
mockChat.sendMessageStream.mockRejectedValue(
new InvalidStreamError('No finish reason', 'NO_FINISH_REASON'),
);
const result = await session.prompt({
sessionId: 'session-1',
prompt: [{ type: 'text', text: 'Hi' }],
});
expect(mockChat.sendMessageStream).toHaveBeenCalled();
expect(result).toMatchObject({ stopReason: 'end_turn' });
});
it('should handle prompt with no finish reason (NO_FINISH_REASON anomaly)', async () => {
mockChat.sendMessageStream.mockRejectedValue({ type: 'NO_FINISH_REASON' });
const result = await session.prompt({
sessionId: 'session-1',
prompt: [{ type: 'text', text: 'Hi' }],
});
expect(mockChat.sendMessageStream).toHaveBeenCalled();
expect(result).toMatchObject({ stopReason: 'end_turn' });
});
it('should handle /memory command', async () => {
const handleCommandSpy = vi
.spyOn(
+4 -1
View File
@@ -863,7 +863,10 @@ export class Session {
(error &&
typeof error === 'object' &&
'type' in error &&
error.type === 'NO_RESPONSE_TEXT')
(error.type === 'NO_RESPONSE_TEXT' ||
error.type === 'NO_FINISH_REASON' ||
error.type === 'MALFORMED_FUNCTION_CALL' ||
error.type === 'UNEXPECTED_TOOL_CALL'))
) {
// The stream ended with an empty response or malformed tool call.
// Treat this as a graceful end to the model's turn rather than a crash.
@@ -26,5 +26,11 @@ describe('CommandHandler', () => {
const init = parse('/init');
expect(init.commandToExecute?.name).toBe('init');
const about = parse('/about');
expect(about.commandToExecute?.name).toBe('about');
const help = parse('/help');
expect(help.commandToExecute?.name).toBe('help');
});
});
+4
View File
@@ -10,6 +10,8 @@ import { MemoryCommand } from './commands/memory.js';
import { ExtensionsCommand } from './commands/extensions.js';
import { InitCommand } from './commands/init.js';
import { RestoreCommand } from './commands/restore.js';
import { AboutCommand } from './commands/about.js';
import { HelpCommand } from './commands/help.js';
export class CommandHandler {
private registry: CommandRegistry;
@@ -24,6 +26,8 @@ export class CommandHandler {
registry.register(new ExtensionsCommand());
registry.register(new InitCommand());
registry.register(new RestoreCommand());
registry.register(new AboutCommand());
registry.register(new HelpCommand(registry));
return registry;
}
+74
View File
@@ -0,0 +1,74 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {
IdeClient,
UserAccountManager,
getVersion,
} from '@google/gemini-cli-core';
import type {
Command,
CommandContext,
CommandExecutionResponse,
} from './types.js';
import process from 'node:process';
export class AboutCommand implements Command {
readonly name = 'about';
readonly description = 'Show version and environment info';
async execute(
context: CommandContext,
_args: string[] = [],
): Promise<CommandExecutionResponse> {
const osVersion = process.platform;
let sandboxEnv = 'no sandbox';
if (process.env['SANDBOX'] && process.env['SANDBOX'] !== 'sandbox-exec') {
sandboxEnv = process.env['SANDBOX'];
} else if (process.env['SANDBOX'] === 'sandbox-exec') {
sandboxEnv = `sandbox-exec (${
process.env['SEATBELT_PROFILE'] || 'unknown'
})`;
}
const modelVersion = context.agentContext.config.getModel() || 'Unknown';
const cliVersion = await getVersion();
const selectedAuthType =
context.settings.merged?.security?.auth?.selectedType ?? '';
const gcpProject = process.env['GOOGLE_CLOUD_PROJECT'] || '';
const ideClient = await getIdeClientName(context);
const userAccountManager = new UserAccountManager();
const cachedAccount = userAccountManager.getCachedGoogleAccount();
const userEmail = cachedAccount ?? 'Unknown';
const tier = context.agentContext.config.getUserTierName() || 'Unknown';
const info = [
`- Version: ${cliVersion}`,
`- OS: ${osVersion}`,
`- Sandbox: ${sandboxEnv}`,
`- Model: ${modelVersion}`,
`- Auth Type: ${selectedAuthType}`,
`- GCP Project: ${gcpProject}`,
`- IDE Client: ${ideClient}`,
`- User Email: ${userEmail}`,
`- Tier: ${tier}`,
].join('\n');
return {
name: this.name,
data: `Gemini CLI Info:\n${info}`,
};
}
}
async function getIdeClientName(context: CommandContext) {
if (!context.agentContext.config.getIdeMode()) {
return '';
}
const ideClient = await IdeClient.getInstance();
return ideClient?.getDetectedIdeDisplayName() ?? '';
}
@@ -0,0 +1,53 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect } from 'vitest';
import { HelpCommand } from './help.js';
import { CommandRegistry } from './commandRegistry.js';
import type { Command, CommandContext } from './types.js';
describe('HelpCommand', () => {
it('returns formatted help text with sorted commands', async () => {
const registry = new CommandRegistry();
const cmdB: Command = {
name: 'bravo',
description: 'Bravo command',
execute: async () => ({ name: 'bravo', data: '' }),
};
const cmdA: Command = {
name: 'alpha',
description: 'Alpha command',
execute: async () => ({ name: 'alpha', data: '' }),
};
registry.register(cmdB);
registry.register(cmdA);
const helpCommand = new HelpCommand(registry);
const context = {} as CommandContext;
const response = await helpCommand.execute(context, []);
expect(response.name).toBe('help');
const data = response.data as string;
expect(data).toContain('Gemini CLI Help:');
expect(data).toContain('### Basics');
expect(data).toContain('### Commands');
const lines = data.split('\n');
const alphaIndex = lines.findIndex((l) => l.includes('/alpha'));
const bravoIndex = lines.findIndex((l) => l.includes('/bravo'));
expect(alphaIndex).toBeLessThan(bravoIndex);
expect(alphaIndex).not.toBe(-1);
expect(bravoIndex).not.toBe(-1);
});
});
+50
View File
@@ -0,0 +1,50 @@
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type {
Command,
CommandContext,
CommandExecutionResponse,
} from './types.js';
import type { CommandRegistry } from './commandRegistry.js';
export class HelpCommand implements Command {
readonly name = 'help';
readonly description = 'Show available commands';
constructor(private registry: CommandRegistry) {}
async execute(
_context: CommandContext,
_args: string[] = [],
): Promise<CommandExecutionResponse> {
const commands = this.registry
.getAllCommands()
.sort((a, b) => a.name.localeCompare(b.name));
const lines: string[] = [];
lines.push('Gemini CLI Help:');
lines.push('');
lines.push('### Basics');
lines.push(
'- **Add context**: Use `@` to specify files for context (e.g., `@src/myFile.ts`) to target specific files or folders.',
);
lines.push('');
lines.push('### Commands');
for (const cmd of commands) {
if (cmd.description) {
lines.push(`- **/${cmd.name}** - ${cmd.description}`);
}
}
return {
name: this.name,
data: lines.join('\n'),
};
}
}
@@ -87,7 +87,7 @@ describe('SettingsSchema', () => {
const definition = getSettingsSchema().ui?.properties?.loadingPhrases;
expect(definition).toBeDefined();
expect(definition?.type).toBe('enum');
expect(definition?.default).toBe('tips');
expect(definition?.default).toBe('off');
expect(definition?.options?.map((o) => o.value)).toEqual([
'tips',
'witty',
+2 -2
View File
@@ -776,9 +776,9 @@ const SETTINGS_SCHEMA = {
label: 'Loading Phrases',
category: 'UI',
requiresRestart: false,
default: 'tips',
default: 'off',
description:
'What to show while the model is working: tips, witty comments, both, or nothing.',
'What to show while the model is working: tips, witty comments, all, or off.',
showInDialog: true,
options: [
{ value: 'tips', label: 'Tips' },
+2 -2
View File
@@ -14,7 +14,7 @@ import {
wrapStyledChars,
widestLineFromStyledChars,
styledCharsWidth,
styledCharsToString,
styledLineToString,
} from 'ink';
import { theme } from '../semantic-colors.js';
import { parseMarkdownToANSI } from './markdownParsingUtils.js';
@@ -196,7 +196,7 @@ export const TableRenderer: React.FC<TableRendererProps> = ({
);
const lines = wrappedStyledLines.map((line) => ({
text: styledCharsToString(line),
text: styledLineToString(line),
width: styledCharsWidth(line),
}));
rowResult.push(lines);
@@ -14,25 +14,25 @@
<text x="243" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="252" lengthAdjust="spacingAndGlyphs">├────────┼────────┼────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> 123456 </text>
<text x="18" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs" font-weight="bold">123456</text>
<text x="81" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="90" y="53" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Normal </text>
<text x="99" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Normal</text>
<text x="162" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="171" y="53" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="180" y="53" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="243" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="18" y="70" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="81" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="90" y="70" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> 123456 </text>
<text x="99" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs" font-weight="bold">123456</text>
<text x="162" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="171" y="70" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Normal </text>
<text x="180" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Normal</text>
<text x="243" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Normal </text>
<text x="18" y="87" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Normal</text>
<text x="81" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="90" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="99" y="87" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="162" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="171" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> 123456 </text>
<text x="180" y="87" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs" font-weight="bold">123456</text>
<text x="243" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="252" lengthAdjust="spacingAndGlyphs">└────────┴────────┴────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

@@ -14,25 +14,31 @@
<text x="918" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="927" lengthAdjust="spacingAndGlyphs">├───────────────────────────────────┼───────────────────────────────┼─────────────────────────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="315" lengthAdjust="spacingAndGlyphs"> Visit Google (https://google.com) </text>
<text x="18" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">Visit Google (</text>
<text x="144" y="53" fill="#87afff" textLength="162" lengthAdjust="spacingAndGlyphs">https://google.com</text>
<text x="306" y="53" fill="#ffffff" textLength="9" lengthAdjust="spacingAndGlyphs">)</text>
<text x="324" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="53" fill="#ffffff" textLength="279" lengthAdjust="spacingAndGlyphs"> Plain Text </text>
<text x="342" y="53" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Plain Text</text>
<text x="612" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="621" y="53" fill="#ffffff" textLength="297" lengthAdjust="spacingAndGlyphs"> More Info </text>
<text x="630" y="53" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs">More Info</text>
<text x="918" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="315" lengthAdjust="spacingAndGlyphs"> Info Here </text>
<text x="18" y="70" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs">Info Here</text>
<text x="324" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="70" fill="#ffffff" textLength="279" lengthAdjust="spacingAndGlyphs"> Visit Bing (https://bing.com) </text>
<text x="342" y="70" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Visit Bing (</text>
<text x="450" y="70" fill="#87afff" textLength="144" lengthAdjust="spacingAndGlyphs">https://bing.com</text>
<text x="594" y="70" fill="#ffffff" textLength="9" lengthAdjust="spacingAndGlyphs">)</text>
<text x="612" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="621" y="70" fill="#ffffff" textLength="297" lengthAdjust="spacingAndGlyphs"> Links </text>
<text x="630" y="70" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Links</text>
<text x="918" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="315" lengthAdjust="spacingAndGlyphs"> Check This </text>
<text x="18" y="87" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Check This</text>
<text x="324" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="87" fill="#ffffff" textLength="279" lengthAdjust="spacingAndGlyphs"> Search </text>
<text x="342" y="87" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Search</text>
<text x="612" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="621" y="87" fill="#ffffff" textLength="297" lengthAdjust="spacingAndGlyphs"> Visit Yahoo (https://yahoo.com) </text>
<text x="630" y="87" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs">Visit Yahoo (</text>
<text x="747" y="87" fill="#87afff" textLength="153" lengthAdjust="spacingAndGlyphs">https://yahoo.com</text>
<text x="900" y="87" fill="#ffffff" textLength="9" lengthAdjust="spacingAndGlyphs">)</text>
<text x="918" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="927" lengthAdjust="spacingAndGlyphs">└───────────────────────────────────┴───────────────────────────────┴─────────────────────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

@@ -14,25 +14,26 @@
<text x="540" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="549" lengthAdjust="spacingAndGlyphs">├─────────────────┼──────────────────────┼──────────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> **not bold** </text>
<text x="18" y="53" fill="#d7afff" textLength="108" lengthAdjust="spacingAndGlyphs">**not bold**</text>
<text x="162" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="171" y="53" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs"> _not italic_ </text>
<text x="180" y="53" fill="#d7afff" textLength="108" lengthAdjust="spacingAndGlyphs">_not italic_</text>
<text x="369" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="378" y="53" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> ~~not strike~~ </text>
<text x="387" y="53" fill="#d7afff" textLength="126" lengthAdjust="spacingAndGlyphs">~~not strike~~</text>
<text x="540" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> [not link](url) </text>
<text x="18" y="70" fill="#d7afff" textLength="135" lengthAdjust="spacingAndGlyphs">[not link](url)</text>
<text x="162" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="171" y="70" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs"> &lt;u&gt;not underline&lt;/u&gt; </text>
<text x="180" y="70" fill="#d7afff" textLength="180" lengthAdjust="spacingAndGlyphs">&lt;u&gt;not underline&lt;/u&gt;</text>
<text x="369" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="378" y="70" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> https://not.link </text>
<text x="387" y="70" fill="#d7afff" textLength="144" lengthAdjust="spacingAndGlyphs">https://not.link</text>
<text x="540" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> Normal Text </text>
<text x="18" y="87" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">Normal Text</text>
<text x="162" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="171" y="87" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs"> More Code: *test* </text>
<text x="180" y="87" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">More Code: </text>
<text x="279" y="87" fill="#d7afff" textLength="54" lengthAdjust="spacingAndGlyphs">*test*</text>
<text x="369" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="378" y="87" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> ***nested*** </text>
<text x="387" y="87" fill="#d7afff" textLength="108" lengthAdjust="spacingAndGlyphs">***nested***</text>
<text x="540" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="549" lengthAdjust="spacingAndGlyphs">└─────────────────┴──────────────────────┴──────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

@@ -14,25 +14,31 @@
<text x="810" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="819" lengthAdjust="spacingAndGlyphs">├─────────────────────────────┼─────────────────────────────┼─────────────────────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Bold with Italic and Strike </text>
<text x="18" y="53" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs" font-weight="bold">Bold with </text>
<text x="108" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Italic</text>
<text x="162" y="53" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs" font-weight="bold"> and Strike</text>
<text x="270" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="53" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Normal </text>
<text x="288" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Normal</text>
<text x="540" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="549" y="53" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="558" y="53" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="810" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="18" y="70" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="270" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="70" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Bold with Italic and Strike </text>
<text x="288" y="70" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs" font-weight="bold">Bold with </text>
<text x="378" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Italic</text>
<text x="432" y="70" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs" font-weight="bold"> and Strike</text>
<text x="540" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="549" y="70" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Normal </text>
<text x="558" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Normal</text>
<text x="810" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Normal </text>
<text x="18" y="87" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Normal</text>
<text x="270" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="87" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="288" y="87" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="540" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="549" y="87" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Bold with Italic and Strike </text>
<text x="558" y="87" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs" font-weight="bold">Bold with </text>
<text x="648" y="87" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Italic</text>
<text x="702" y="87" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs" font-weight="bold"> and Strike</text>
<text x="810" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="819" lengthAdjust="spacingAndGlyphs">└─────────────────────────────┴─────────────────────────────┴─────────────────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

@@ -14,18 +14,18 @@
<text x="378" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="405" lengthAdjust="spacingAndGlyphs">├──────────────┼────────────┼───────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs"> Start 🌟 End </text>
<text x="18" y="53" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">Start 🌟 End</text>
<text x="126" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="135" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs"> 你好世界 </text>
<text x="144" y="53" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">你好世界</text>
<text x="243" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="252" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Rocket 🚀 Man </text>
<text x="261" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Rocket 🚀 Man</text>
<text x="378" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs"> Thumbs 👍 Up </text>
<text x="18" y="70" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">Thumbs 👍 Up</text>
<text x="126" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="135" y="70" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs"> こんにちは </text>
<text x="144" y="70" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">こんにちは</text>
<text x="243" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="252" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Fire 🔥 </text>
<text x="261" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Fire 🔥</text>
<text x="378" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="405" lengthAdjust="spacingAndGlyphs">└──────────────┴────────────┴───────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

@@ -31,15 +31,15 @@
<text x="288" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="297" lengthAdjust="spacingAndGlyphs">├─────────────┼───────┼─────────┤</text>
<text x="0" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="104" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs"> Data 1 </text>
<text x="18" y="104" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 1</text>
<text x="126" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="135" y="104" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs"> Data </text>
<text x="144" y="104" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">Data</text>
<text x="198" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="207" y="104" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs"> Data 3 </text>
<text x="216" y="104" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 3</text>
<text x="288" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="126" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="135" y="121" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs"> 2 </text>
<text x="144" y="121" fill="#ffffff" textLength="9" lengthAdjust="spacingAndGlyphs">2</text>
<text x="198" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="288" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="138" fill="#333333" textLength="297" lengthAdjust="spacingAndGlyphs">└─────────────┴───────┴─────────┘</text>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

@@ -14,25 +14,25 @@
<text x="405" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="414" lengthAdjust="spacingAndGlyphs">├──────────────┼──────────────┼──────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 1, Col 1 </text>
<text x="18" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 1, Col 1</text>
<text x="135" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="144" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 1, Col 2 </text>
<text x="153" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 1, Col 2</text>
<text x="270" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 1, Col 3 </text>
<text x="288" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 1, Col 3</text>
<text x="405" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 2, Col 1 </text>
<text x="18" y="70" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 2, Col 1</text>
<text x="135" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="144" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 2, Col 2 </text>
<text x="153" y="70" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 2, Col 2</text>
<text x="270" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 2, Col 3 </text>
<text x="288" y="70" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 2, Col 3</text>
<text x="405" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 3, Col 1 </text>
<text x="18" y="87" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 3, Col 1</text>
<text x="135" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="144" y="87" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 3, Col 2 </text>
<text x="153" y="87" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 3, Col 2</text>
<text x="270" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="87" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Row 3, Col 3 </text>
<text x="288" y="87" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Row 3, Col 3</text>
<text x="405" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="414" lengthAdjust="spacingAndGlyphs">└──────────────┴──────────────┴──────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

@@ -93,105 +93,105 @@
<text x="1395" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="138" fill="#333333" textLength="1404" lengthAdjust="spacingAndGlyphs">├─────────────────────────────┼──────────────────────────────┼─────────────────────────────┼──────────────────────────────┼─────┼────────┼─────────┼───────┤</text>
<text x="0" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="155" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> The primary architecture </text>
<text x="18" y="155" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">The primary architecture</text>
<text x="270" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="155" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> Each message is processed </text>
<text x="288" y="155" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">Each message is processed</text>
<text x="549" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="155" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Historical data indicates a </text>
<text x="567" y="155" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">Historical data indicates a</text>
<text x="819" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="155" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> A multi-layered defense </text>
<text x="837" y="155" fill="#ffffff" textLength="207" lengthAdjust="spacingAndGlyphs">A multi-layered defense</text>
<text x="1098" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1107" y="155" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs"> INF </text>
<text x="1116" y="155" fill="#ffffff" textLength="27" lengthAdjust="spacingAndGlyphs">INF</text>
<text x="1152" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1161" y="155" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Active </text>
<text x="1170" y="155" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Active</text>
<text x="1233" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1242" y="155" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs"> v2.4 </text>
<text x="1251" y="155" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">v2.4</text>
<text x="1323" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1332" y="155" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs"> J. </text>
<text x="1341" y="155" fill="#ffffff" textLength="18" lengthAdjust="spacingAndGlyphs">J.</text>
<text x="1395" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="172" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> utilizes a decoupled </text>
<text x="18" y="172" fill="#ffffff" textLength="180" lengthAdjust="spacingAndGlyphs">utilizes a decoupled</text>
<text x="270" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="172" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> through a series of </text>
<text x="288" y="172" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs">through a series of</text>
<text x="549" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="172" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> significant reduction in </text>
<text x="567" y="172" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">significant reduction in</text>
<text x="819" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="172" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> strategy incorporates </text>
<text x="837" y="172" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">strategy incorporates</text>
<text x="1098" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1332" y="172" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs"> Doe </text>
<text x="1341" y="172" fill="#ffffff" textLength="27" lengthAdjust="spacingAndGlyphs">Doe</text>
<text x="1395" y="172" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="189" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> microservices approach, </text>
<text x="18" y="189" fill="#ffffff" textLength="207" lengthAdjust="spacingAndGlyphs">microservices approach,</text>
<text x="270" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="189" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> specialized workers that </text>
<text x="288" y="189" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">specialized workers that</text>
<text x="549" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="189" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> tail latency when utilizing </text>
<text x="567" y="189" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">tail latency when utilizing</text>
<text x="819" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="189" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> content security policies, </text>
<text x="837" y="189" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">content security policies,</text>
<text x="1098" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="189" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="206" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> leveraging container </text>
<text x="18" y="206" fill="#ffffff" textLength="180" lengthAdjust="spacingAndGlyphs">leveraging container</text>
<text x="270" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="206" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> handle data transformation, </text>
<text x="288" y="206" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">handle data transformation,</text>
<text x="549" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="206" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> edge computing nodes closer </text>
<text x="567" y="206" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">edge computing nodes closer</text>
<text x="819" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="206" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> input sanitization </text>
<text x="837" y="206" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs">input sanitization</text>
<text x="1098" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="206" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="223" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> orchestration for </text>
<text x="18" y="223" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs">orchestration for</text>
<text x="270" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="223" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> validation, and persistent </text>
<text x="288" y="223" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">validation, and persistent</text>
<text x="549" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="223" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> to the geographic location </text>
<text x="567" y="223" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">to the geographic location</text>
<text x="819" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="223" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> libraries, and regular </text>
<text x="837" y="223" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">libraries, and regular</text>
<text x="1098" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="223" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="240" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> scalability and fault </text>
<text x="18" y="240" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">scalability and fault</text>
<text x="270" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="240" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> storage using a persistent </text>
<text x="288" y="240" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">storage using a persistent</text>
<text x="549" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="240" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> of the end-user base. </text>
<text x="567" y="240" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">of the end-user base.</text>
<text x="819" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="240" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> automated penetration </text>
<text x="837" y="240" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">automated penetration</text>
<text x="1098" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="240" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="257" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> tolerance in high-load </text>
<text x="18" y="257" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">tolerance in high-load</text>
<text x="270" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="257" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> queue. </text>
<text x="288" y="257" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">queue.</text>
<text x="549" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="819" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="257" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> testing routines. </text>
<text x="837" y="257" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs">testing routines.</text>
<text x="1098" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="257" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="274" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> scenarios. </text>
<text x="18" y="274" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">scenarios.</text>
<text x="270" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="549" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="274" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Monitoring tools have </text>
<text x="567" y="274" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">Monitoring tools have</text>
<text x="819" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1098" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
@@ -200,85 +200,85 @@
<text x="1395" y="274" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="270" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="291" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> The pipeline features </text>
<text x="288" y="291" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">The pipeline features</text>
<text x="549" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="291" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> captured a steady increase </text>
<text x="567" y="291" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">captured a steady increase</text>
<text x="819" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="291" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> Developers are required to </text>
<text x="837" y="291" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">Developers are required to</text>
<text x="1098" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="291" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="308" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> This layer provides the </text>
<text x="18" y="308" fill="#ffffff" textLength="207" lengthAdjust="spacingAndGlyphs">This layer provides the</text>
<text x="270" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="308" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> built-in retry mechanisms </text>
<text x="288" y="308" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">built-in retry mechanisms</text>
<text x="549" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="308" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> in throughput efficiency </text>
<text x="567" y="308" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">in throughput efficiency</text>
<text x="819" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="308" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> undergo mandatory security </text>
<text x="837" y="308" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">undergo mandatory security</text>
<text x="1098" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="308" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="325" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> fundamental building blocks </text>
<text x="18" y="325" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">fundamental building blocks</text>
<text x="270" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="325" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> with exponential backoff to </text>
<text x="288" y="325" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">with exponential backoff to</text>
<text x="549" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="325" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> since the introduction of </text>
<text x="567" y="325" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">since the introduction of</text>
<text x="819" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="325" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> training focusing on the </text>
<text x="837" y="325" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">training focusing on the</text>
<text x="1098" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="325" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="342" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> for service discovery, load </text>
<text x="18" y="342" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">for service discovery, load</text>
<text x="270" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="342" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> ensure message delivery </text>
<text x="288" y="342" fill="#ffffff" textLength="207" lengthAdjust="spacingAndGlyphs">ensure message delivery</text>
<text x="549" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="342" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> the vectorized query engine </text>
<text x="567" y="342" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">the vectorized query engine</text>
<text x="819" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="342" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> OWASP Top Ten to ensure that </text>
<text x="837" y="342" fill="#ffffff" textLength="252" lengthAdjust="spacingAndGlyphs">OWASP Top Ten to ensure that</text>
<text x="1098" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="342" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="359" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> balancing, and </text>
<text x="18" y="359" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">balancing, and</text>
<text x="270" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="359" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> integrity even during </text>
<text x="288" y="359" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">integrity even during</text>
<text x="549" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="359" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> in the primary data </text>
<text x="567" y="359" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs">in the primary data</text>
<text x="819" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="359" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> security is integrated into </text>
<text x="837" y="359" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">security is integrated into</text>
<text x="1098" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="359" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="376" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> inter-service communication </text>
<text x="18" y="376" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">inter-service communication</text>
<text x="270" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="376" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> transient network or service </text>
<text x="288" y="376" fill="#ffffff" textLength="252" lengthAdjust="spacingAndGlyphs">transient network or service</text>
<text x="549" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="376" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> warehouse. </text>
<text x="567" y="376" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">warehouse.</text>
<text x="819" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="376" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> the initial design phase. </text>
<text x="837" y="376" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">the initial design phase.</text>
<text x="1098" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="376" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="393" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="393" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> via highly efficient </text>
<text x="18" y="393" fill="#ffffff" textLength="180" lengthAdjust="spacingAndGlyphs">via highly efficient</text>
<text x="270" y="393" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="393" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> failures. </text>
<text x="288" y="393" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs">failures.</text>
<text x="549" y="393" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="819" y="393" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1098" y="393" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
@@ -287,12 +287,12 @@
<text x="1323" y="393" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="393" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="410" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> protocol buffers. </text>
<text x="18" y="410" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs">protocol buffers.</text>
<text x="270" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="549" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="410" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Resource utilization </text>
<text x="567" y="410" fill="#ffffff" textLength="180" lengthAdjust="spacingAndGlyphs">Resource utilization</text>
<text x="819" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="410" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> The implementation of a </text>
<text x="837" y="410" fill="#ffffff" textLength="207" lengthAdjust="spacingAndGlyphs">The implementation of a</text>
<text x="1098" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
@@ -300,85 +300,85 @@
<text x="1395" y="410" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="270" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="427" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> Horizontal autoscaling is </text>
<text x="288" y="427" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">Horizontal autoscaling is</text>
<text x="549" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="427" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> metrics demonstrate that </text>
<text x="567" y="427" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">metrics demonstrate that</text>
<text x="819" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="427" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> robust Identity and Access </text>
<text x="837" y="427" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">robust Identity and Access</text>
<text x="1098" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="427" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="444" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Advanced telemetry and </text>
<text x="18" y="444" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">Advanced telemetry and</text>
<text x="270" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="444" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> triggered automatically </text>
<text x="288" y="444" fill="#ffffff" textLength="207" lengthAdjust="spacingAndGlyphs">triggered automatically</text>
<text x="549" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="444" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> the transition to </text>
<text x="567" y="444" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs">the transition to</text>
<text x="819" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="444" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> Management system ensures </text>
<text x="837" y="444" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">Management system ensures</text>
<text x="1098" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="444" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="461" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> logging integrations allow </text>
<text x="18" y="461" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">logging integrations allow</text>
<text x="270" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="461" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> based on the depth of the </text>
<text x="288" y="461" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">based on the depth of the</text>
<text x="549" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="461" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> serverless compute for </text>
<text x="567" y="461" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">serverless compute for</text>
<text x="819" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="461" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> that the principle of least </text>
<text x="837" y="461" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">that the principle of least</text>
<text x="1098" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="461" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="478" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> for real-time monitoring of </text>
<text x="18" y="478" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">for real-time monitoring of</text>
<text x="270" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="478" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> processing queue, ensuring </text>
<text x="288" y="478" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">processing queue, ensuring</text>
<text x="549" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="478" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> intermittent tasks has </text>
<text x="567" y="478" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">intermittent tasks has</text>
<text x="819" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="478" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> privilege is strictly </text>
<text x="837" y="478" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">privilege is strictly</text>
<text x="1098" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="478" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="495" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> system health and rapid </text>
<text x="18" y="495" fill="#ffffff" textLength="207" lengthAdjust="spacingAndGlyphs">system health and rapid</text>
<text x="270" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="495" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> consistent performance </text>
<text x="288" y="495" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">consistent performance</text>
<text x="549" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="495" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> resulted in a thirty </text>
<text x="567" y="495" fill="#ffffff" textLength="180" lengthAdjust="spacingAndGlyphs">resulted in a thirty</text>
<text x="819" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="495" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> enforced across all </text>
<text x="837" y="495" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs">enforced across all</text>
<text x="1098" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="495" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="512" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> identification of </text>
<text x="18" y="512" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs">identification of</text>
<text x="270" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="512" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> during unexpected traffic </text>
<text x="288" y="512" fill="#ffffff" textLength="225" lengthAdjust="spacingAndGlyphs">during unexpected traffic</text>
<text x="549" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="558" y="512" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> percent cost optimization. </text>
<text x="567" y="512" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs">percent cost optimization.</text>
<text x="819" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="828" y="512" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> environments. </text>
<text x="837" y="512" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs">environments.</text>
<text x="1098" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1152" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1233" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1323" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="512" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="529" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="529" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> bottlenecks within the </text>
<text x="18" y="529" fill="#ffffff" textLength="198" lengthAdjust="spacingAndGlyphs">bottlenecks within the</text>
<text x="270" y="529" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="529" fill="#ffffff" textLength="270" lengthAdjust="spacingAndGlyphs"> spikes. </text>
<text x="288" y="529" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs">spikes.</text>
<text x="549" y="529" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="819" y="529" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1098" y="529" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
@@ -387,7 +387,7 @@
<text x="1323" y="529" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="1395" y="529" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="546" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="546" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> service mesh. </text>
<text x="18" y="546" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs">service mesh.</text>
<text x="270" y="546" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="549" y="546" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="819" y="546" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 42 KiB

@@ -32,31 +32,31 @@
<text x="630" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="639" lengthAdjust="spacingAndGlyphs">├───────────────┼───────────────┼──────────────────┼──────────────────┤</text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Data 1.1 </text>
<text x="18" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 1.1</text>
<text x="144" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="87" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Data 1.2 </text>
<text x="162" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 1.2</text>
<text x="288" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="297" y="87" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> Data 1.3 </text>
<text x="306" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 1.3</text>
<text x="459" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="468" y="87" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> Data 1.4 </text>
<text x="477" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 1.4</text>
<text x="630" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="104" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Data 2.1 </text>
<text x="18" y="104" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 2.1</text>
<text x="144" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="104" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Data 2.2 </text>
<text x="162" y="104" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 2.2</text>
<text x="288" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="297" y="104" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> Data 2.3 </text>
<text x="306" y="104" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 2.3</text>
<text x="459" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="468" y="104" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> Data 2.4 </text>
<text x="477" y="104" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 2.4</text>
<text x="630" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="121" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Data 3.1 </text>
<text x="18" y="121" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 3.1</text>
<text x="144" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="121" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Data 3.2 </text>
<text x="162" y="121" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 3.2</text>
<text x="288" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="297" y="121" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> Data 3.3 </text>
<text x="306" y="121" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 3.3</text>
<text x="459" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="468" y="121" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> Data 3.4 </text>
<text x="477" y="121" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Data 3.4</text>
<text x="630" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="138" fill="#333333" textLength="639" lengthAdjust="spacingAndGlyphs">└───────────────┴───────────────┴──────────────────┴──────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

@@ -14,18 +14,18 @@
<text x="450" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="486" lengthAdjust="spacingAndGlyphs">├───────────────┼───────────────────┼────────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> 你好 😃 </text>
<text x="18" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">你好 😃</text>
<text x="135" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="144" y="53" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> こんにちは 🚀 </text>
<text x="153" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">こんにちは 🚀</text>
<text x="306" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="315" y="53" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> 안녕하세요 📝 </text>
<text x="324" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">안녕하세요 📝</text>
<text x="450" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> World 🌍 </text>
<text x="18" y="70" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs">World 🌍</text>
<text x="135" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="144" y="70" fill="#ffffff" textLength="162" lengthAdjust="spacingAndGlyphs"> Code 💻 </text>
<text x="153" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Code 💻</text>
<text x="306" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="315" y="70" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Pizza 🍕 </text>
<text x="324" y="70" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs">Pizza 🍕</text>
<text x="450" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="486" lengthAdjust="spacingAndGlyphs">└───────────────┴───────────────────┴────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -14,18 +14,18 @@
<text x="441" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="450" lengthAdjust="spacingAndGlyphs">├──────────────┼─────────────────┼───────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> 你好 </text>
<text x="18" y="53" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">你好</text>
<text x="135" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="144" y="53" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> こんにちは </text>
<text x="153" y="53" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">こんにちは</text>
<text x="297" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="306" y="53" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> 안녕하세요 </text>
<text x="315" y="53" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">안녕하세요</text>
<text x="441" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> 世界 </text>
<text x="18" y="70" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">世界</text>
<text x="135" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="144" y="70" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> 世界 </text>
<text x="153" y="70" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">世界</text>
<text x="297" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="306" y="70" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> 세계 </text>
<text x="315" y="70" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">세계</text>
<text x="441" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="450" lengthAdjust="spacingAndGlyphs">└──────────────┴─────────────────┴───────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

@@ -14,18 +14,18 @@
<text x="279" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="315" lengthAdjust="spacingAndGlyphs">├──────────┼───────────┼──────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs"> Smile 😃 </text>
<text x="18" y="53" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs">Smile 😃</text>
<text x="90" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="99" y="53" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs"> Fire 🔥 </text>
<text x="108" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Fire 🔥</text>
<text x="189" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="198" y="53" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs"> Love 💖 </text>
<text x="207" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Love 💖</text>
<text x="279" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs"> Cool 😎 </text>
<text x="18" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Cool 😎</text>
<text x="90" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="99" y="70" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs"> Star ⭐ </text>
<text x="108" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Star ⭐</text>
<text x="189" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="198" y="70" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs"> Blue 💙 </text>
<text x="207" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Blue 💙</text>
<text x="279" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="315" lengthAdjust="spacingAndGlyphs">└──────────┴───────────┴──────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

@@ -12,39 +12,41 @@
<text x="414" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="423" lengthAdjust="spacingAndGlyphs">├───────────────┼─────────────────────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Bold </text>
<text x="18" y="53" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">Bold</text>
<text x="144" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="53" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Bold Text </text>
<text x="162" y="53" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs" font-weight="bold">Bold Text</text>
<text x="414" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Italic </text>
<text x="18" y="70" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Italic</text>
<text x="144" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="70" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Italic Text </text>
<text x="162" y="70" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs" font-style="italic">Italic Text</text>
<text x="414" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Combined </text>
<text x="18" y="87" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Combined</text>
<text x="144" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="87" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Bold and Italic </text>
<text x="162" y="87" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs" font-weight="bold" font-style="italic">Bold and Italic</text>
<text x="414" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="104" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Link </text>
<text x="18" y="104" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">Link</text>
<text x="144" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="104" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Google (https://google.com) </text>
<text x="162" y="104" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">Google (</text>
<text x="234" y="104" fill="#87afff" textLength="162" lengthAdjust="spacingAndGlyphs">https://google.com</text>
<text x="396" y="104" fill="#ffffff" textLength="9" lengthAdjust="spacingAndGlyphs">)</text>
<text x="414" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="121" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Code </text>
<text x="18" y="121" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">Code</text>
<text x="144" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="121" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> const x = 1 </text>
<text x="162" y="121" fill="#d7afff" textLength="99" lengthAdjust="spacingAndGlyphs">const x = 1</text>
<text x="414" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="138" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="138" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Strikethrough </text>
<text x="18" y="138" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs">Strikethrough</text>
<text x="144" y="138" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="138" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Strike </text>
<text x="162" y="138" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Strike</text>
<text x="414" y="138" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="155" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Underline </text>
<text x="18" y="155" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs">Underline</text>
<text x="144" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="155" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> Underline </text>
<text x="162" y="155" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs" text-decoration="underline">Underline</text>
<text x="414" y="155" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="172" fill="#333333" textLength="423" lengthAdjust="spacingAndGlyphs">└───────────────┴─────────────────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

@@ -10,9 +10,9 @@
<text x="162" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="171" lengthAdjust="spacingAndGlyphs">├────────┼────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Data 1 </text>
<text x="18" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 1</text>
<text x="81" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="90" y="53" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Data 2 </text>
<text x="99" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 2</text>
<text x="162" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="171" lengthAdjust="spacingAndGlyphs">└────────┴────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -14,9 +14,9 @@
<text x="297" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="306" lengthAdjust="spacingAndGlyphs">├──────────┼──────────┼──────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs"> Data 1 </text>
<text x="18" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 1</text>
<text x="99" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="108" y="53" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs"> Data 2 </text>
<text x="117" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 2</text>
<text x="198" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="297" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="306" lengthAdjust="spacingAndGlyphs">└──────────┴──────────┴──────────┘</text>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -14,11 +14,11 @@
<text x="405" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="414" lengthAdjust="spacingAndGlyphs">├─────────────┼───────────────┼──────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="117" lengthAdjust="spacingAndGlyphs"> Data 1 </text>
<text x="18" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 1</text>
<text x="126" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="135" y="53" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Data 2 </text>
<text x="144" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 2</text>
<text x="270" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="279" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs"> Data 3 </text>
<text x="288" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Data 3</text>
<text x="405" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="414" lengthAdjust="spacingAndGlyphs">└─────────────┴───────────────┴──────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -14,38 +14,38 @@
<text x="468" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="477" lengthAdjust="spacingAndGlyphs">├────────────────┼────────────────┼─────────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> This is a very </text>
<text x="18" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">This is a very</text>
<text x="153" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="162" y="53" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> This is also a </text>
<text x="171" y="53" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">This is also a</text>
<text x="306" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="315" y="53" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> And this is the </text>
<text x="324" y="53" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs">And this is the</text>
<text x="468" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> long text that </text>
<text x="18" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">long text that</text>
<text x="153" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="162" y="70" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> very long text </text>
<text x="171" y="70" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">very long text</text>
<text x="306" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="315" y="70" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> third long text </text>
<text x="324" y="70" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs">third long text</text>
<text x="468" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> needs wrapping </text>
<text x="18" y="87" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">needs wrapping</text>
<text x="153" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="162" y="87" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> that needs </text>
<text x="171" y="87" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">that needs</text>
<text x="306" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="315" y="87" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> that needs </text>
<text x="324" y="87" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">that needs</text>
<text x="468" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="104" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> in column 1 </text>
<text x="18" y="104" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">in column 1</text>
<text x="153" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="162" y="104" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> wrapping in </text>
<text x="171" y="104" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">wrapping in</text>
<text x="306" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="315" y="104" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> wrapping in </text>
<text x="324" y="104" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">wrapping in</text>
<text x="468" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="153" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="162" y="121" fill="#ffffff" textLength="144" lengthAdjust="spacingAndGlyphs"> column 2 </text>
<text x="171" y="121" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">column 2</text>
<text x="306" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="315" y="121" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> column 3 </text>
<text x="324" y="121" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs">column 3</text>
<text x="468" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="138" fill="#333333" textLength="477" lengthAdjust="spacingAndGlyphs">└────────────────┴────────────────┴─────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

@@ -14,37 +14,37 @@
<text x="486" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="495" lengthAdjust="spacingAndGlyphs">├───────────────────┼───────────────┼─────────────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs"> Start. Stop. </text>
<text x="18" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Start. Stop.</text>
<text x="180" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="189" y="53" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Semi; colon: </text>
<text x="198" y="53" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Semi; colon:</text>
<text x="324" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="53" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> At@ Hash# </text>
<text x="342" y="53" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs">At@ Hash#</text>
<text x="486" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="70" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs"> Comma, separated. </text>
<text x="18" y="70" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs">Comma, separated.</text>
<text x="180" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="189" y="70" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Pipe| Slash/ </text>
<text x="198" y="70" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Pipe| Slash/</text>
<text x="324" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="70" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> Dollar$ </text>
<text x="342" y="70" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs">Dollar$</text>
<text x="486" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="87" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs"> Exclamation! </text>
<text x="18" y="87" fill="#ffffff" textLength="108" lengthAdjust="spacingAndGlyphs">Exclamation!</text>
<text x="180" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="189" y="87" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs"> Backslash\ </text>
<text x="198" y="87" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Backslash\</text>
<text x="324" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="87" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> Percent% Caret^ </text>
<text x="342" y="87" fill="#ffffff" textLength="135" lengthAdjust="spacingAndGlyphs">Percent% Caret^</text>
<text x="486" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="104" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs"> Question? </text>
<text x="18" y="104" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs">Question?</text>
<text x="180" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="324" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="104" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> Ampersand&amp; </text>
<text x="342" y="104" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Ampersand&amp;</text>
<text x="486" y="104" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="121" fill="#ffffff" textLength="171" lengthAdjust="spacingAndGlyphs"> hyphen-ated </text>
<text x="18" y="121" fill="#ffffff" textLength="99" lengthAdjust="spacingAndGlyphs">hyphen-ated</text>
<text x="180" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="324" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="333" y="121" fill="#ffffff" textLength="153" lengthAdjust="spacingAndGlyphs"> Asterisk* </text>
<text x="342" y="121" fill="#ffffff" textLength="81" lengthAdjust="spacingAndGlyphs">Asterisk*</text>
<text x="486" y="121" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="138" fill="#333333" textLength="495" lengthAdjust="spacingAndGlyphs">└───────────────────┴───────────────┴─────────────────┘</text>
</g>

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

@@ -14,20 +14,20 @@
<text x="414" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="423" lengthAdjust="spacingAndGlyphs">├───────┼─────────────────────────────┼───────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="18" y="53" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="72" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="81" y="53" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> This is a very long cell </text>
<text x="90" y="53" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">This is a very long cell</text>
<text x="342" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="351" y="53" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs"> Short </text>
<text x="360" y="53" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">Short</text>
<text x="414" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="72" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="81" y="70" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> content that should wrap to </text>
<text x="90" y="70" fill="#ffffff" textLength="243" lengthAdjust="spacingAndGlyphs">content that should wrap to</text>
<text x="342" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="414" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="72" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="81" y="87" fill="#ffffff" textLength="261" lengthAdjust="spacingAndGlyphs"> multiple lines </text>
<text x="90" y="87" fill="#ffffff" textLength="126" lengthAdjust="spacingAndGlyphs">multiple lines</text>
<text x="342" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="414" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="423" lengthAdjust="spacingAndGlyphs">└───────┴─────────────────────────────┴───────┘</text>

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

@@ -14,21 +14,21 @@
<text x="396" y="19" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="36" fill="#333333" textLength="405" lengthAdjust="spacingAndGlyphs">├───────┼──────────────────────────┼────────┤</text>
<text x="0" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="9" y="53" fill="#ffffff" textLength="63" lengthAdjust="spacingAndGlyphs"> Tiny </text>
<text x="18" y="53" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">Tiny</text>
<text x="72" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="81" y="53" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs"> This is a very long text </text>
<text x="90" y="53" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">This is a very long text</text>
<text x="315" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="324" y="53" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> Not so </text>
<text x="333" y="53" fill="#ffffff" textLength="54" lengthAdjust="spacingAndGlyphs">Not so</text>
<text x="396" y="53" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="72" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="81" y="70" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs"> that definitely needs to </text>
<text x="90" y="70" fill="#ffffff" textLength="216" lengthAdjust="spacingAndGlyphs">that definitely needs to</text>
<text x="315" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="324" y="70" fill="#ffffff" textLength="72" lengthAdjust="spacingAndGlyphs"> long </text>
<text x="333" y="70" fill="#ffffff" textLength="36" lengthAdjust="spacingAndGlyphs">long</text>
<text x="396" y="70" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="72" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="81" y="87" fill="#ffffff" textLength="234" lengthAdjust="spacingAndGlyphs"> wrap to the next line </text>
<text x="90" y="87" fill="#ffffff" textLength="189" lengthAdjust="spacingAndGlyphs">wrap to the next line</text>
<text x="315" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="396" y="87" fill="#333333" textLength="9" lengthAdjust="spacingAndGlyphs"></text>
<text x="0" y="104" fill="#333333" textLength="405" lengthAdjust="spacingAndGlyphs">└───────┴──────────────────────────┴────────┘</text>

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-core",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"description": "Gemini CLI Core",
"license": "Apache-2.0",
"repository": {
@@ -5,6 +5,7 @@
*/
import { type FunctionCall } from '@google/genai';
import { type ApprovalMode } from '../policy/types.js';
import type {
ToolConfirmationOutcome,
ToolConfirmationPayload,
@@ -150,6 +151,7 @@ export interface UpdatePolicy {
commandPrefix?: string | string[];
mcpName?: string;
allowRedirection?: boolean;
modes?: ApprovalMode[];
}
export interface ToolPolicyRejection {
+79 -27
View File
@@ -533,7 +533,6 @@ export async function createPolicyEngineConfig(
disableAlwaysAllow: settings.disableAlwaysAllow,
};
}
interface TomlRule {
toolName?: string;
mcpName?: string;
@@ -542,10 +541,64 @@ interface TomlRule {
commandPrefix?: string | string[];
argsPattern?: string;
allowRedirection?: boolean;
modes?: ApprovalMode[];
// Index signature to satisfy Record type if needed for toml.stringify
[key: string]: unknown;
}
/**
* Finds a rule in the rule array that matches the given criteria.
*/
function findMatchingRule(
rules: TomlRule[],
criteria: {
toolName: string;
mcpName?: string;
commandPrefix?: string | string[];
argsPattern?: string;
},
): TomlRule | undefined {
return rules.find(
(r) =>
r.toolName === criteria.toolName &&
r.mcpName === criteria.mcpName &&
JSON.stringify(r.commandPrefix) ===
JSON.stringify(criteria.commandPrefix) &&
r.argsPattern === criteria.argsPattern,
);
}
/**
* Creates a new TOML rule object from the given tool name and message.
*/
function createTomlRule(toolName: string, message: UpdatePolicy): TomlRule {
const rule: TomlRule = {
decision: 'allow',
priority: getAlwaysAllowPriorityFraction(),
toolName,
};
if (message.mcpName) {
rule.mcpName = message.mcpName;
}
if (message.commandPrefix) {
rule.commandPrefix = message.commandPrefix;
} else if (message.argsPattern) {
rule.argsPattern = message.argsPattern;
}
if (message.allowRedirection !== undefined) {
rule.allowRedirection = message.allowRedirection;
}
if (message.modes) {
rule.modes = message.modes;
}
return rule;
}
export function createPolicyUpdater(
policyEngine: PolicyEngine,
messageBus: MessageBus,
@@ -585,6 +638,7 @@ export function createPolicyUpdater(
priority,
argsPattern: new RegExp(pattern),
mcpName: message.mcpName,
modes: message.modes,
source: 'Dynamic (Confirmed)',
allowRedirection: message.allowRedirection,
});
@@ -622,6 +676,7 @@ export function createPolicyUpdater(
priority,
argsPattern,
mcpName: message.mcpName,
modes: message.modes,
source: 'Dynamic (Confirmed)',
allowRedirection: message.allowRedirection,
});
@@ -662,39 +717,36 @@ export function createPolicyUpdater(
existingData.rule = [];
}
// Create new rule object
const newRule: TomlRule = {
decision: 'allow',
priority: getAlwaysAllowPriorityFraction(),
};
// Normalize tool name for MCP
let normalizedToolName = toolName;
if (message.mcpName) {
newRule.mcpName = message.mcpName;
const expectedPrefix = `${MCP_TOOL_PREFIX}${message.mcpName}_`;
if (toolName.startsWith(expectedPrefix)) {
newRule.toolName = toolName.slice(expectedPrefix.length);
} else {
newRule.toolName = toolName;
normalizedToolName = toolName.slice(expectedPrefix.length);
}
}
// Look for an existing rule to update
const existingRule = findMatchingRule(existingData.rule, {
toolName: normalizedToolName,
mcpName: message.mcpName,
commandPrefix: message.commandPrefix,
argsPattern: message.argsPattern,
});
if (existingRule) {
if (message.allowRedirection !== undefined) {
existingRule.allowRedirection = message.allowRedirection;
}
if (message.modes) {
existingRule.modes = message.modes;
}
} else {
newRule.toolName = toolName;
existingData.rule.push(
createTomlRule(normalizedToolName, message),
);
}
if (message.commandPrefix) {
newRule.commandPrefix = message.commandPrefix;
} else if (message.argsPattern) {
// message.argsPattern was already validated above
newRule.argsPattern = message.argsPattern;
}
if (message.allowRedirection !== undefined) {
newRule.allowRedirection = message.allowRedirection;
}
// Add to rules
existingData.rule.push(newRule);
// Serialize back to TOML
// @iarna/toml stringify might not produce beautiful output but it handles escaping correctly
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
@@ -242,4 +242,57 @@ decision = "deny"
const content = memfs.readFileSync(policyFile, 'utf-8') as string;
expect(content).toContain('toolName = "test_tool"');
});
it('should include modes if provided', async () => {
createPolicyUpdater(policyEngine, messageBus, mockStorage);
const policyFile = '/mock/user/.gemini/policies/auto-saved.toml';
vi.spyOn(mockStorage, 'getAutoSavedPolicyPath').mockReturnValue(policyFile);
await messageBus.publish({
type: MessageBusType.UPDATE_POLICY,
toolName: 'test_tool',
persist: true,
modes: [ApprovalMode.DEFAULT, ApprovalMode.YOLO],
});
await vi.advanceTimersByTimeAsync(100);
const content = memfs.readFileSync(policyFile, 'utf-8') as string;
expect(content).toContain('modes = [ "default", "yolo" ]');
});
it('should update existing rule modes instead of appending redundant rule', async () => {
createPolicyUpdater(policyEngine, messageBus, mockStorage);
const policyFile = '/mock/user/.gemini/policies/auto-saved.toml';
vi.spyOn(mockStorage, 'getAutoSavedPolicyPath').mockReturnValue(policyFile);
const existingContent = `
[[rule]]
decision = "allow"
priority = 950
toolName = "test_tool"
modes = [ "autoEdit", "yolo" ]
`;
const dir = path.dirname(policyFile);
memfs.mkdirSync(dir, { recursive: true });
memfs.writeFileSync(policyFile, existingContent);
// Now grant in DEFAULT mode, which should include [default, autoEdit, yolo]
await messageBus.publish({
type: MessageBusType.UPDATE_POLICY,
toolName: 'test_tool',
persist: true,
modes: [ApprovalMode.DEFAULT, ApprovalMode.AUTO_EDIT, ApprovalMode.YOLO],
});
await vi.advanceTimersByTimeAsync(100);
const content = memfs.readFileSync(policyFile, 'utf-8') as string;
// Should NOT have two [[rule]] entries for test_tool
const ruleCount = (content.match(/\[\[rule\]\]/g) || []).length;
expect(ruleCount).toBe(1);
expect(content).toContain('modes = [ "default", "autoEdit", "yolo" ]');
});
});
+12
View File
@@ -52,6 +52,18 @@ export enum ApprovalMode {
PLAN = 'plan',
}
/**
* The order of permissiveness for approval modes.
* Tools allowed in a less permissive mode should also be allowed
* in more permissive modes.
*/
export const MODES_BY_PERMISSIVENESS = [
ApprovalMode.PLAN,
ApprovalMode.DEFAULT,
ApprovalMode.AUTO_EDIT,
ApprovalMode.YOLO,
];
/**
* Configuration for the built-in allowed-path checker.
*/
@@ -49,6 +49,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
} as unknown as Mocked<Config>;
@@ -76,6 +77,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
} as unknown as Mocked<Config>;
@@ -106,6 +108,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
getDisableAlwaysAllow: vi.fn().mockReturnValue(true),
} as unknown as Mocked<Config>;
@@ -132,6 +135,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
isInteractive: vi.fn().mockReturnValue(false),
} as unknown as Mocked<Config>;
@@ -155,6 +159,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
} as unknown as Mocked<Config>;
@@ -176,6 +181,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
isInteractive: vi.fn().mockReturnValue(true),
} as unknown as Mocked<Config>;
@@ -198,6 +204,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
isInteractive: vi.fn().mockReturnValue(true),
} as unknown as Mocked<Config>;
@@ -217,6 +224,7 @@ describe('policy.ts', () => {
} as unknown as Mocked<PolicyEngine>;
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
} as unknown as Mocked<Config>;
@@ -233,6 +241,7 @@ describe('policy.ts', () => {
describe('updatePolicy', () => {
it('should set AUTO_EDIT mode for auto-edit transition tools', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -262,6 +271,7 @@ describe('policy.ts', () => {
it('should handle standard policy updates (persist=false)', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -293,6 +303,7 @@ describe('policy.ts', () => {
it('should handle standard policy updates with persistence', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
isTrustedFolder: vi.fn().mockReturnValue(false),
getWorkspacePoliciesDir: vi.fn().mockReturnValue(undefined),
setApprovalMode: vi.fn(),
@@ -326,6 +337,7 @@ describe('policy.ts', () => {
it('should handle shell command prefixes', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -365,6 +377,7 @@ describe('policy.ts', () => {
it('should handle MCP policy updates (server scope)', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -405,6 +418,7 @@ describe('policy.ts', () => {
it('should NOT publish update for ProceedOnce', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -431,6 +445,7 @@ describe('policy.ts', () => {
it('should NOT publish update for Cancel', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -456,6 +471,7 @@ describe('policy.ts', () => {
it('should NOT publish update for ModifyWithEditor', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -481,6 +497,7 @@ describe('policy.ts', () => {
it('should handle MCP ProceedAlwaysTool (specific tool name)', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -521,6 +538,7 @@ describe('policy.ts', () => {
it('should handle MCP ProceedAlways (persist: false)', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
@@ -561,6 +579,7 @@ describe('policy.ts', () => {
it('should handle MCP ProceedAlwaysAndSave (persist: true)', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
isTrustedFolder: vi.fn().mockReturnValue(false),
getWorkspacePoliciesDir: vi.fn().mockReturnValue(undefined),
setApprovalMode: vi.fn(),
@@ -603,6 +622,7 @@ describe('policy.ts', () => {
it('should determine persistScope: workspace in trusted folders', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
isTrustedFolder: vi.fn().mockReturnValue(true),
getWorkspacePoliciesDir: vi
.fn()
@@ -633,6 +653,7 @@ describe('policy.ts', () => {
it('should determine persistScope: user in untrusted folders', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
isTrustedFolder: vi.fn().mockReturnValue(false),
getWorkspacePoliciesDir: vi
.fn()
@@ -663,6 +684,7 @@ describe('policy.ts', () => {
it('should narrow edit tools with argsPattern', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
isTrustedFolder: vi.fn().mockReturnValue(false),
getWorkspacePoliciesDir: vi.fn().mockReturnValue(undefined),
getTargetDir: vi.fn().mockReturnValue('/mock/dir'),
@@ -703,6 +725,7 @@ describe('policy.ts', () => {
it('should work when context is created via Object.create (prototype chain)', async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
setApprovalMode: vi.fn(),
} as unknown as Mocked<Config>;
const mockMessageBus = {
@@ -868,4 +891,78 @@ describe('Plan Mode Denial Consistency', () => {
expect(resultMessage).toBe('Tool execution denied by policy.');
expect(resultErrorType).toBe(ToolErrorType.POLICY_VIOLATION);
});
describe('updatePolicy - context-aware modes', () => {
const testCases = [
{
currentMode: ApprovalMode.DEFAULT,
expectedModes: [
ApprovalMode.DEFAULT,
ApprovalMode.AUTO_EDIT,
ApprovalMode.YOLO,
],
description:
'include current and more permissive modes in DEFAULT mode',
},
{
currentMode: ApprovalMode.AUTO_EDIT,
expectedModes: [ApprovalMode.AUTO_EDIT, ApprovalMode.YOLO],
description:
'include current and more permissive modes in AUTO_EDIT mode',
},
{
currentMode: ApprovalMode.YOLO,
expectedModes: [ApprovalMode.YOLO],
description: 'include current and more permissive modes in YOLO mode',
},
{
currentMode: ApprovalMode.PLAN,
expectedModes: [
ApprovalMode.PLAN,
ApprovalMode.DEFAULT,
ApprovalMode.AUTO_EDIT,
ApprovalMode.YOLO,
],
description: 'include all modes explicitly when granted in PLAN mode',
},
];
testCases.forEach(({ currentMode, expectedModes, description }) => {
it(`should ${description}`, async () => {
const mockConfig = {
getApprovalMode: vi.fn().mockReturnValue(currentMode),
isTrustedFolder: vi.fn().mockReturnValue(false),
getWorkspacePoliciesDir: vi.fn().mockReturnValue(undefined),
} as unknown as Mocked<Config>;
const mockMessageBus = {
publish: vi.fn(),
} as unknown as Mocked<MessageBus>;
const context = {
config: mockConfig,
messageBus: mockMessageBus,
} as unknown as AgentLoopContext;
const tool = { name: 'test-tool' } as AnyDeclarativeTool;
await updatePolicy(
tool,
ToolConfirmationOutcome.ProceedAlwaysAndSave,
undefined,
context,
mockMessageBus,
);
expect(mockMessageBus.publish).toHaveBeenCalledWith(
expect.objectContaining({
type: MessageBusType.UPDATE_POLICY,
toolName: 'test-tool',
persist: true,
modes: expectedModes,
}),
);
});
});
});
});
+24
View File
@@ -7,6 +7,7 @@
import { ToolErrorType } from '../tools/tool-error.js';
import {
ApprovalMode,
MODES_BY_PERMISSIVENESS,
PolicyDecision,
type CheckResult,
type PolicyRule,
@@ -126,6 +127,23 @@ export async function updatePolicy(
// Determine persist scope if we are persisting.
let persistScope: 'workspace' | 'user' | undefined;
let modes: ApprovalMode[] | undefined;
const currentMode = context.config.getApprovalMode();
// If this is an 'Always Allow' selection, we restrict it to the current mode
// and more permissive modes.
if (
outcome === ToolConfirmationOutcome.ProceedAlways ||
outcome === ToolConfirmationOutcome.ProceedAlwaysTool ||
outcome === ToolConfirmationOutcome.ProceedAlwaysServer ||
outcome === ToolConfirmationOutcome.ProceedAlwaysAndSave
) {
const modeIndex = MODES_BY_PERMISSIVENESS.indexOf(currentMode);
if (modeIndex !== -1) {
modes = MODES_BY_PERMISSIVENESS.slice(modeIndex);
}
}
if (outcome === ToolConfirmationOutcome.ProceedAlwaysAndSave) {
// If folder is trusted and workspace policies are enabled, we prefer workspace scope.
if (
@@ -147,6 +165,7 @@ export async function updatePolicy(
confirmationDetails,
messageBus,
persistScope,
modes,
);
return;
}
@@ -160,6 +179,7 @@ export async function updatePolicy(
persistScope,
toolInvocation,
context.config,
modes,
);
}
@@ -192,6 +212,7 @@ async function handleStandardPolicyUpdate(
persistScope?: 'workspace' | 'user',
toolInvocation?: AnyToolInvocation,
config?: Config,
modes?: ApprovalMode[],
): Promise<void> {
if (
outcome === ToolConfirmationOutcome.ProceedAlways ||
@@ -214,6 +235,7 @@ async function handleStandardPolicyUpdate(
toolName: tool.name,
persist: outcome === ToolConfirmationOutcome.ProceedAlwaysAndSave,
persistScope,
modes,
...options,
});
}
@@ -232,6 +254,7 @@ async function handleMcpPolicyUpdate(
>,
messageBus: MessageBus,
persistScope?: 'workspace' | 'user',
modes?: ApprovalMode[],
): Promise<void> {
const isMcpAlways =
outcome === ToolConfirmationOutcome.ProceedAlways ||
@@ -257,5 +280,6 @@ async function handleMcpPolicyUpdate(
mcpName: confirmationDetails.serverName,
persist,
persistScope,
modes,
});
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-devtools",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"license": "Apache-2.0",
"type": "module",
"main": "dist/src/index.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-sdk",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"description": "Gemini CLI SDK",
"license": "Apache-2.0",
"repository": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@google/gemini-cli-test-utils",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"private": true,
"main": "src/index.ts",
"license": "Apache-2.0",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "gemini-cli-vscode-ide-companion",
"displayName": "Gemini CLI Companion",
"description": "Enable Gemini CLI with direct access to your IDE workspace.",
"version": "0.36.0-nightly.20260317.2f90b4653",
"version": "0.37.2",
"publisher": "google",
"icon": "assets/icon.png",
"repository": {
+3 -3
View File
@@ -478,9 +478,9 @@
},
"loadingPhrases": {
"title": "Loading Phrases",
"description": "What to show while the model is working: tips, witty comments, both, or nothing.",
"markdownDescription": "What to show while the model is working: tips, witty comments, both, or nothing.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `tips`",
"default": "tips",
"description": "What to show while the model is working: tips, witty comments, all, or off.",
"markdownDescription": "What to show while the model is working: tips, witty comments, all, or off.\n\n- Category: `UI`\n- Requires restart: `no`\n- Default: `off`",
"default": "off",
"type": "string",
"enum": ["tips", "witty", "all", "off"]
},