upfynai-code 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +22 -0
  2. package/bin/cli.js +86 -0
  3. package/dist/assets/CanvasPanel-B48gAKVY.js +538 -0
  4. package/dist/assets/CanvasPanel-B48gAKVY.js.map +1 -0
  5. package/dist/assets/CanvasPanel-BsOG3EVs.css +1 -0
  6. package/dist/assets/index-CEhTwG68.css +1 -0
  7. package/dist/assets/index-GqAGWpJI.js +70 -0
  8. package/dist/assets/index-GqAGWpJI.js.map +1 -0
  9. package/dist/index.html +18 -0
  10. package/index.html +17 -0
  11. package/package.json +67 -0
  12. package/src/App.tsx +226 -0
  13. package/src/components/canvas/CanvasPanel.tsx +62 -0
  14. package/src/components/canvas/layout/graph-builder.ts +136 -0
  15. package/src/components/canvas/shapes/CompactionNodeShape.tsx +76 -0
  16. package/src/components/canvas/shapes/SessionNodeShape.tsx +93 -0
  17. package/src/components/canvas/shapes/StatuslineWidgetShape.tsx +125 -0
  18. package/src/components/canvas/shapes/TextResponseNodeShape.tsx +86 -0
  19. package/src/components/canvas/shapes/ToolCallNodeShape.tsx +107 -0
  20. package/src/components/canvas/shapes/ToolResultNodeShape.tsx +87 -0
  21. package/src/components/canvas/shapes/shared-styles.ts +35 -0
  22. package/src/components/chat/ChatPanel.tsx +96 -0
  23. package/src/components/chat/InputBar.tsx +81 -0
  24. package/src/components/chat/MessageList.tsx +130 -0
  25. package/src/components/chat/PermissionDialog.tsx +70 -0
  26. package/src/components/layout/FolderSelector.tsx +152 -0
  27. package/src/components/layout/ModelSelector.tsx +65 -0
  28. package/src/components/layout/SessionManager.tsx +115 -0
  29. package/src/components/statusline/StatuslineBar.tsx +114 -0
  30. package/src/main.tsx +10 -0
  31. package/src/server/claude-session.ts +156 -0
  32. package/src/server/index.ts +149 -0
  33. package/src/services/stream-consumer.ts +330 -0
  34. package/src/statusline-core/bin/statusline.sh +121 -0
  35. package/src/statusline-core/commands/sls-config.md +42 -0
  36. package/src/statusline-core/commands/sls-doctor.md +35 -0
  37. package/src/statusline-core/commands/sls-help.md +48 -0
  38. package/src/statusline-core/commands/sls-layout.md +38 -0
  39. package/src/statusline-core/commands/sls-preview.md +34 -0
  40. package/src/statusline-core/commands/sls-theme.md +40 -0
  41. package/src/statusline-core/installer.js +228 -0
  42. package/src/statusline-core/layouts/compact.sh +21 -0
  43. package/src/statusline-core/layouts/full.sh +62 -0
  44. package/src/statusline-core/layouts/standard.sh +39 -0
  45. package/src/statusline-core/lib/core.sh +389 -0
  46. package/src/statusline-core/lib/helpers.sh +81 -0
  47. package/src/statusline-core/lib/json-parser.sh +71 -0
  48. package/src/statusline-core/themes/catppuccin.sh +32 -0
  49. package/src/statusline-core/themes/default.sh +37 -0
  50. package/src/statusline-core/themes/gruvbox.sh +32 -0
  51. package/src/statusline-core/themes/nord.sh +32 -0
  52. package/src/statusline-core/themes/tokyo-night.sh +32 -0
  53. package/src/store/canvas-store.ts +50 -0
  54. package/src/store/chat-store.ts +60 -0
  55. package/src/store/permission-store.ts +29 -0
  56. package/src/store/session-store.ts +52 -0
  57. package/src/store/statusline-store.ts +160 -0
  58. package/src/styles/global.css +117 -0
  59. package/src/themes/index.ts +149 -0
  60. package/src/types/canvas-graph.ts +24 -0
  61. package/src/types/sdk-messages.ts +156 -0
  62. package/src/types/statusline-fields.ts +67 -0
  63. package/src/vite-env.d.ts +1 -0
  64. package/tsconfig.json +26 -0
  65. package/vite.config.ts +24 -0
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: List available statusline themes or set a theme. Examples: /sls-theme, /sls-theme nord
3
+ argument-hint: "[theme-name]"
4
+ ---
5
+
6
+ # Statusline Theme
7
+
8
+ Manage the statusline theme for Claude Code.
9
+
10
+ ## Current Config
11
+
12
+ ```
13
+ !cat ~/.claude/statusline-config.json 2>/dev/null || echo '{"theme":"default","layout":"standard"}'
14
+ ```
15
+
16
+ ## Available Themes
17
+
18
+ | Theme | Description |
19
+ |-------|-------------|
20
+ | `default` | Classic purple/pink/cyan — the original |
21
+ | `nord` | Arctic, blue-tinted — frost palette |
22
+ | `tokyo-night` | Vibrant neon — dark city glow |
23
+ | `catppuccin` | Warm pastels — Mocha variant |
24
+ | `gruvbox` | Retro groovy — warm earth tones |
25
+
26
+ ## Instructions
27
+
28
+ If `$ARGUMENTS` is provided (a theme name):
29
+ 1. Run `ccsl theme set $ARGUMENTS` in the terminal
30
+ 2. Show the result to the user
31
+ 3. Tell them to restart Claude Code or start a new conversation for the theme to take effect
32
+
33
+ If no arguments provided:
34
+ 1. Run `ccsl theme` in the terminal to list themes with the current selection highlighted
35
+ 2. Show the output to the user
36
+ 3. Tell them they can set a theme with `/sls-theme <name>` or `ccsl theme set <name>`
37
+
38
+ **Valid theme names:** default, nord, tokyo-night, catppuccin, gruvbox
39
+
40
+ If the user provides an invalid theme name, show them the valid options above.
@@ -0,0 +1,228 @@
1
+ /**
2
+ * UC UpfynAI-Code — Statusline Auto-Installer
3
+ * Proprietary software by Thinqmesh Technologies, Developed by Anit Chaudhary
4
+ *
5
+ * Idempotent installer: copies vendored statusline bash scripts to ~/.claude/
6
+ * and configures Claude Code to use the statusline. Called on CLI startup.
7
+ */
8
+
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+ import os from 'node:os';
12
+ import { fileURLToPath } from 'node:url';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const CORE_DIR = path.dirname(__filename);
16
+
17
+ const HOME = os.homedir();
18
+ const CLAUDE_DIR = path.join(HOME, '.claude');
19
+ const SL_DIR = path.join(CLAUDE_DIR, 'statusline');
20
+ const CONFIG_PATH = path.join(CLAUDE_DIR, 'statusline-config.json');
21
+ const SETTINGS_PATH = path.join(CLAUDE_DIR, 'settings.json');
22
+ const SCRIPT_DEST = path.join(CLAUDE_DIR, 'statusline-command.sh');
23
+ const CLAUDE_MD_PATH = path.join(CLAUDE_DIR, 'CLAUDE.md');
24
+ const COMMANDS_DIR = path.join(CLAUDE_DIR, 'commands');
25
+
26
+ const SLS_COMMANDS = ['sls-theme', 'sls-layout', 'sls-preview', 'sls-config', 'sls-doctor', 'sls-help'];
27
+
28
+ const CLAUDE_MD_START = '<!-- skill-statusline:start -->';
29
+ const CLAUDE_MD_END = '<!-- skill-statusline:end -->';
30
+
31
+ const CLAUDE_MD_SECTION = `${CLAUDE_MD_START}
32
+ ## Statusline — Managed by UC UpfynAI-Code
33
+
34
+ The Claude Code statusline is fully configured and managed by **UC UpfynAI-Code** (proprietary software by Thinqmesh Technologies, Developed by Anit Chaudhary). Do NOT use the built-in \`statusline-setup\` agent for any statusline configuration — it is not compatible with this setup.
35
+
36
+ ### How It Works
37
+ - \`~/.claude/settings.json\` → points to \`bash ~/.claude/statusline-command.sh\`
38
+ - \`~/.claude/statusline-command.sh\` → entry point, delegates to v2 engine
39
+ - \`~/.claude/statusline/core.sh\` → v2 engine (themes, layouts, accurate context tracking)
40
+ - \`~/.claude/statusline-config.json\` → user preferences (theme, layout, options)
41
+
42
+ ### When the user asks about statusline configuration, use these CLI commands:
43
+
44
+ | Action | Command |
45
+ |--------|---------|
46
+ | Change theme | \`ccsl theme set <name>\` |
47
+ | Change layout | \`ccsl layout set <name>\` |
48
+ | List themes | \`ccsl theme\` |
49
+ | List layouts | \`ccsl layout\` |
50
+ | Preview | \`ccsl preview\` |
51
+ | Preview with overrides | \`ccsl preview --theme <name> --layout <name>\` |
52
+ | Show config | \`ccsl config\` |
53
+ | Set config option | \`ccsl config set <key> <value>\` |
54
+ | Diagnostics | \`ccsl doctor\` |
55
+ | Update scripts | \`ccsl update\` |
56
+ | Reinstall | \`ccsl install\` |
57
+
58
+ **Available themes:** default, nord, tokyo-night, catppuccin, gruvbox
59
+ **Available layouts:** compact (2 rows), standard (4 rows), full (6 rows)
60
+ **Config options:** compaction_warning_threshold, bar_width, cache_ttl_seconds, show_burn_rate, show_vim_mode, show_agent_name
61
+
62
+ ### Slash Commands (installed in ~/.claude/commands/)
63
+
64
+ Users can also use these slash commands inside Claude Code:
65
+ - \`/sls-theme [name]\` — List or set theme
66
+ - \`/sls-layout [name]\` — List or set layout
67
+ - \`/sls-preview [theme] [layout]\` — Preview with sample data
68
+ - \`/sls-config [key] [value]\` — Show or set config options
69
+ - \`/sls-doctor\` — Run diagnostics
70
+ - \`/sls-help\` — Show all commands
71
+
72
+ ### IMPORTANT
73
+ - NEVER spawn the \`statusline-setup\` agent — it will fail on Windows and conflict with this setup
74
+ - All statusline changes are made via \`ccsl\` CLI commands (run in terminal) or \`/sls-*\` slash commands
75
+ - Changes take effect on next Claude Code restart (or next statusline refresh for config changes)
76
+ ${CLAUDE_MD_END}`;
77
+
78
+ // ── Helpers ──
79
+
80
+ function ensureDir(dir) {
81
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
82
+ }
83
+
84
+ function copyDir(src, dest) {
85
+ ensureDir(dest);
86
+ for (const entry of fs.readdirSync(src)) {
87
+ const srcPath = path.join(src, entry);
88
+ const destPath = path.join(dest, entry);
89
+ if (fs.statSync(srcPath).isDirectory()) {
90
+ copyDir(srcPath, destPath);
91
+ } else {
92
+ fs.copyFileSync(srcPath, destPath);
93
+ }
94
+ }
95
+ }
96
+
97
+ function readConfig() {
98
+ try {
99
+ if (fs.existsSync(CONFIG_PATH)) {
100
+ return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
101
+ }
102
+ } catch {}
103
+ return { version: 2, theme: 'default', layout: 'standard', options: {} };
104
+ }
105
+
106
+ function writeConfig(config) {
107
+ config.version = 2;
108
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n');
109
+ }
110
+
111
+ function readSettings() {
112
+ try {
113
+ if (fs.existsSync(SETTINGS_PATH)) {
114
+ return JSON.parse(fs.readFileSync(SETTINGS_PATH, 'utf8'));
115
+ }
116
+ } catch {}
117
+ return {};
118
+ }
119
+
120
+ function writeSettings(settings) {
121
+ fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n');
122
+ }
123
+
124
+ // ── File installation ──
125
+
126
+ function installFiles() {
127
+ ensureDir(CLAUDE_DIR);
128
+ ensureDir(SL_DIR);
129
+
130
+ // lib/ → ~/.claude/statusline/
131
+ const libSrc = path.join(CORE_DIR, 'lib');
132
+ if (fs.existsSync(libSrc)) {
133
+ for (const f of fs.readdirSync(libSrc)) {
134
+ fs.copyFileSync(path.join(libSrc, f), path.join(SL_DIR, f));
135
+ }
136
+ }
137
+
138
+ // themes/ → ~/.claude/statusline/themes/
139
+ const themesSrc = path.join(CORE_DIR, 'themes');
140
+ if (fs.existsSync(themesSrc)) {
141
+ copyDir(themesSrc, path.join(SL_DIR, 'themes'));
142
+ }
143
+
144
+ // layouts/ → ~/.claude/statusline/layouts/
145
+ const layoutsSrc = path.join(CORE_DIR, 'layouts');
146
+ if (fs.existsSync(layoutsSrc)) {
147
+ copyDir(layoutsSrc, path.join(SL_DIR, 'layouts'));
148
+ }
149
+
150
+ // Entry point script
151
+ const slSrc = path.join(CORE_DIR, 'bin', 'statusline.sh');
152
+ if (fs.existsSync(slSrc)) {
153
+ fs.copyFileSync(slSrc, SCRIPT_DEST);
154
+ }
155
+ }
156
+
157
+ function installClaudeMd() {
158
+ let content = '';
159
+ if (fs.existsSync(CLAUDE_MD_PATH)) {
160
+ content = fs.readFileSync(CLAUDE_MD_PATH, 'utf8');
161
+ const startIdx = content.indexOf(CLAUDE_MD_START);
162
+ const endIdx = content.indexOf(CLAUDE_MD_END);
163
+ if (startIdx !== -1 && endIdx !== -1) {
164
+ content = content.substring(0, startIdx) + content.substring(endIdx + CLAUDE_MD_END.length);
165
+ content = content.replace(/\n{3,}/g, '\n\n').trim();
166
+ }
167
+ }
168
+ content = content ? content + '\n\n' + CLAUDE_MD_SECTION + '\n' : CLAUDE_MD_SECTION + '\n';
169
+ fs.writeFileSync(CLAUDE_MD_PATH, content);
170
+ }
171
+
172
+ function installCommands() {
173
+ ensureDir(COMMANDS_DIR);
174
+ const cmdSrc = path.join(CORE_DIR, 'commands');
175
+ if (!fs.existsSync(cmdSrc)) return 0;
176
+ let count = 0;
177
+ for (const cmd of SLS_COMMANDS) {
178
+ const src = path.join(cmdSrc, `${cmd}.md`);
179
+ const dest = path.join(COMMANDS_DIR, `${cmd}.md`);
180
+ if (fs.existsSync(src)) {
181
+ fs.copyFileSync(src, dest);
182
+ count++;
183
+ }
184
+ }
185
+ return count;
186
+ }
187
+
188
+ // ── Main export ──
189
+
190
+ export function ensureStatuslineInstalled() {
191
+ // Idempotency: skip if already fully configured
192
+ const coreExists = fs.existsSync(path.join(SL_DIR, 'core.sh'));
193
+ let settingsOk = false;
194
+ try {
195
+ const settings = readSettings();
196
+ settingsOk = !!(settings.statusLine && settings.statusLine.command);
197
+ } catch {}
198
+
199
+ if (coreExists && settingsOk) {
200
+ return { installed: false, reason: 'already-configured' };
201
+ }
202
+
203
+ // 1. Copy all scripts
204
+ installFiles();
205
+
206
+ // 2. Write default config if missing
207
+ if (!fs.existsSync(CONFIG_PATH)) {
208
+ writeConfig({ version: 2, theme: 'default', layout: 'standard', options: {} });
209
+ }
210
+
211
+ // 3. Patch settings.json
212
+ const settings = readSettings();
213
+ if (!settings.statusLine) {
214
+ settings.statusLine = {
215
+ type: 'command',
216
+ command: 'bash ~/.claude/statusline-command.sh',
217
+ };
218
+ writeSettings(settings);
219
+ }
220
+
221
+ // 4. Update CLAUDE.md
222
+ installClaudeMd();
223
+
224
+ // 5. Install slash commands
225
+ installCommands();
226
+
227
+ return { installed: true, reason: 'first-run' };
228
+ }
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+ # Layout: Compact (2 rows — minimal for narrow terminals)
3
+ # Row 1: Model │ Dir │ Cost Context%
4
+ # Row 2: Context bar
5
+
6
+ render_layout() {
7
+ local S
8
+ S=$(printf '%b' " ${CLR_SEP}${SEP_CHAR}${CLR_RST} ")
9
+
10
+ # Row 1: Model │ Dir │ Cost + Context%
11
+ printf ' '
12
+ rpad "${CLR_MODEL}${CLR_BOLD}${SL_MODEL}${CLR_RST}" 16
13
+ printf '%b' "$S"
14
+ rpad "${CLR_DIR}${SL_DIR}${CLR_RST}" 22
15
+ printf '%b' "$S"
16
+ printf '%b\n' "${CTX_CLR}${SL_CTX_PCT}%%${CLR_RST} ${CLR_COST}${SL_COST}${CLR_RST}"
17
+
18
+ # Row 2: Context bar
19
+ printf ' '
20
+ printf '%b' "${CTX_CLR}Context:${CLR_RST} ${SL_CTX_BAR}${SL_COMPACT_WARNING}"
21
+ }
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env bash
2
+ # Layout: Full (6 rows — everything)
3
+ # Row 1: Skill │ GitHub
4
+ # Row 2: Model │ Dir
5
+ # Row 3: Window │ Cost
6
+ # Row 4: Session │ Lines + Duration
7
+ # Row 5: Cache │ Vim/Agent
8
+ # Row 6: Context bar
9
+
10
+ render_layout() {
11
+ local C1="$SL_C1"
12
+ local S
13
+ S=$(printf '%b' " ${CLR_SEP}${SEP_CHAR}${CLR_RST} ")
14
+
15
+ # Row 1: Skill │ GitHub
16
+ printf ' '
17
+ rpad "${CLR_SKILL}Skill:${CLR_RST} ${CLR_SKILL}${SL_SKILL}${CLR_RST}" "$C1"
18
+ printf '%b' "$S"
19
+ printf '%b\n' "${CLR_GITHUB}GitHub:${CLR_RST} ${CLR_GITHUB}${SL_GITHUB}${CLR_RST}${SL_GIT_DIRTY}"
20
+
21
+ # Row 2: Model │ Dir
22
+ printf ' '
23
+ rpad "${CLR_MODEL}Model:${CLR_RST} ${CLR_MODEL}${CLR_BOLD}${SL_MODEL}${CLR_RST}" "$C1"
24
+ printf '%b' "$S"
25
+ printf '%b\n' "${CLR_DIR}Dir:${CLR_RST} ${CLR_DIR}${SL_DIR}${CLR_RST}"
26
+
27
+ # Row 3: Window tokens │ Cost + Burn rate
28
+ printf ' '
29
+ local win_label="${SL_TOKENS_WIN_IN} + ${SL_TOKENS_WIN_OUT}"
30
+ if [ "$cur_input" -eq 0 ] 2>/dev/null && [ "$cum_input" -gt 0 ] 2>/dev/null; then
31
+ win_label="${SL_TOKENS_CUM_IN} + ${SL_TOKENS_CUM_OUT}"
32
+ fi
33
+ rpad "${CLR_TOKENS}Window:${CLR_RST} ${CLR_TOKENS}${win_label}${CLR_RST}" "$C1"
34
+ printf '%b' "$S"
35
+ local cost_display="${CLR_COST}Cost:${CLR_RST} ${CLR_COST}${SL_COST}${CLR_RST}"
36
+ [ -n "$SL_BURN_RATE" ] && cost_display="${cost_display} ${CLR_LABEL}(${SL_BURN_RATE})${CLR_RST}"
37
+ printf '%b\n' "$cost_display"
38
+
39
+ # Row 4: Session tokens │ Lines + Duration
40
+ printf ' '
41
+ rpad "${CLR_TOKENS}Session:${CLR_RST} ${CLR_LABEL}${SL_TOKENS_CUM_IN} + ${SL_TOKENS_CUM_OUT}${CLR_RST}" "$C1"
42
+ printf '%b' "$S"
43
+ printf '%b\n' "${CLR_LABEL}+${SL_LINES_ADDED}/-${SL_LINES_REMOVED} ${SL_DURATION}${CLR_RST}"
44
+
45
+ # Row 5: Cache │ Vim/Agent
46
+ printf ' '
47
+ rpad "${CLR_AGENT}Cache:${CLR_RST} ${CLR_LABEL}W:${SL_CACHE_CREATE} R:${SL_CACHE_READ}${CLR_RST}" "$C1"
48
+ printf '%b' "$S"
49
+ local vim_agent=""
50
+ if [ -n "$SL_VIM_MODE" ] && [ "$SL_VIM_MODE" != "null" ]; then
51
+ vim_agent="${CLR_VIM}${SL_VIM_MODE}${CLR_RST}"
52
+ fi
53
+ if [ -n "$SL_AGENT_NAME" ] && [ "$SL_AGENT_NAME" != "null" ]; then
54
+ [ -n "$vim_agent" ] && vim_agent="${vim_agent} "
55
+ vim_agent="${vim_agent}${CLR_AGENT}@${SL_AGENT_NAME}${CLR_RST}"
56
+ fi
57
+ printf '%b\n' "$vim_agent"
58
+
59
+ # Row 6: Context bar (full width)
60
+ printf ' '
61
+ printf '%b' "${CTX_CLR}Context:${CLR_RST} ${SL_CTX_BAR}${SL_COMPACT_WARNING}"
62
+ }
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ # Layout: Standard (4 rows — default, backward compatible)
3
+ # Row 1: Skill │ GitHub
4
+ # Row 2: Model │ Dir
5
+ # Row 3: Window │ Cost
6
+ # Row 4: Context (wide bar)
7
+
8
+ render_layout() {
9
+ local C1="$SL_C1"
10
+ local S
11
+ S=$(printf '%b' " ${CLR_SEP}${SEP_CHAR}${CLR_RST} ")
12
+
13
+ # Row 1: Skill │ GitHub
14
+ printf ' '
15
+ rpad "${CLR_SKILL}Skill:${CLR_RST} ${CLR_SKILL}${SL_SKILL}${CLR_RST}" "$C1"
16
+ printf '%b' "$S"
17
+ printf '%b\n' "${CLR_GITHUB}GitHub:${CLR_RST} ${CLR_GITHUB}${SL_GITHUB}${CLR_RST}${SL_GIT_DIRTY}"
18
+
19
+ # Row 2: Model │ Dir
20
+ printf ' '
21
+ rpad "${CLR_MODEL}Model:${CLR_RST} ${CLR_MODEL}${CLR_BOLD}${SL_MODEL}${CLR_RST}" "$C1"
22
+ printf '%b' "$S"
23
+ printf '%b\n' "${CLR_DIR}Dir:${CLR_RST} ${CLR_DIR}${SL_DIR}${CLR_RST}"
24
+
25
+ # Row 3: Window tokens │ Cost
26
+ printf ' '
27
+ local win_label="${SL_TOKENS_WIN_IN} + ${SL_TOKENS_WIN_OUT}"
28
+ # If window tokens are 0 (before first API call), show cumulative instead
29
+ if [ "$cur_input" -eq 0 ] 2>/dev/null && [ "$cum_input" -gt 0 ] 2>/dev/null; then
30
+ win_label="${SL_TOKENS_CUM_IN} + ${SL_TOKENS_CUM_OUT}"
31
+ fi
32
+ rpad "${CLR_TOKENS}Tokens:${CLR_RST} ${CLR_TOKENS}${win_label}${CLR_RST}" "$C1"
33
+ printf '%b' "$S"
34
+ printf '%b\n' "${CLR_COST}Cost:${CLR_RST} ${CLR_COST}${SL_COST}${CLR_RST}"
35
+
36
+ # Row 4: Context bar (full width)
37
+ printf ' '
38
+ printf '%b' "${CTX_CLR}Context:${CLR_RST} ${SL_CTX_BAR}${SL_COMPACT_WARNING}"
39
+ }