Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 545e956c3c | |||
| 256584d147 | |||
| 3b2d4f1000 | |||
| b569a98c02 | |||
| ea7dfe8914 | |||
| 527a08d76a | |||
| 352bbe1493 | |||
| ae9d4e16a3 | |||
| ac34520776 | |||
| 7cd6dde12a | |||
| 24810f97ef | |||
| c0f8f3cb7b |
@@ -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]]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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',
|
||||
|
||||
@@ -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' },
|
||||
|
||||
@@ -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"> <u>not underline</u> </text>
|
||||
<text x="180" y="70" fill="#d7afff" textLength="180" lengthAdjust="spacingAndGlyphs"><u>not underline</u></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& </text>
|
||||
<text x="342" y="104" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Ampersand&</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,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 {
|
||||
|
||||
@@ -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" ]');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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,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,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,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",
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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"]
|
||||
},
|
||||
|
||||