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.
- package/LICENSE +22 -0
- package/bin/cli.js +86 -0
- package/dist/assets/CanvasPanel-B48gAKVY.js +538 -0
- package/dist/assets/CanvasPanel-B48gAKVY.js.map +1 -0
- package/dist/assets/CanvasPanel-BsOG3EVs.css +1 -0
- package/dist/assets/index-CEhTwG68.css +1 -0
- package/dist/assets/index-GqAGWpJI.js +70 -0
- package/dist/assets/index-GqAGWpJI.js.map +1 -0
- package/dist/index.html +18 -0
- package/index.html +17 -0
- package/package.json +67 -0
- package/src/App.tsx +226 -0
- package/src/components/canvas/CanvasPanel.tsx +62 -0
- package/src/components/canvas/layout/graph-builder.ts +136 -0
- package/src/components/canvas/shapes/CompactionNodeShape.tsx +76 -0
- package/src/components/canvas/shapes/SessionNodeShape.tsx +93 -0
- package/src/components/canvas/shapes/StatuslineWidgetShape.tsx +125 -0
- package/src/components/canvas/shapes/TextResponseNodeShape.tsx +86 -0
- package/src/components/canvas/shapes/ToolCallNodeShape.tsx +107 -0
- package/src/components/canvas/shapes/ToolResultNodeShape.tsx +87 -0
- package/src/components/canvas/shapes/shared-styles.ts +35 -0
- package/src/components/chat/ChatPanel.tsx +96 -0
- package/src/components/chat/InputBar.tsx +81 -0
- package/src/components/chat/MessageList.tsx +130 -0
- package/src/components/chat/PermissionDialog.tsx +70 -0
- package/src/components/layout/FolderSelector.tsx +152 -0
- package/src/components/layout/ModelSelector.tsx +65 -0
- package/src/components/layout/SessionManager.tsx +115 -0
- package/src/components/statusline/StatuslineBar.tsx +114 -0
- package/src/main.tsx +10 -0
- package/src/server/claude-session.ts +156 -0
- package/src/server/index.ts +149 -0
- package/src/services/stream-consumer.ts +330 -0
- package/src/statusline-core/bin/statusline.sh +121 -0
- package/src/statusline-core/commands/sls-config.md +42 -0
- package/src/statusline-core/commands/sls-doctor.md +35 -0
- package/src/statusline-core/commands/sls-help.md +48 -0
- package/src/statusline-core/commands/sls-layout.md +38 -0
- package/src/statusline-core/commands/sls-preview.md +34 -0
- package/src/statusline-core/commands/sls-theme.md +40 -0
- package/src/statusline-core/installer.js +228 -0
- package/src/statusline-core/layouts/compact.sh +21 -0
- package/src/statusline-core/layouts/full.sh +62 -0
- package/src/statusline-core/layouts/standard.sh +39 -0
- package/src/statusline-core/lib/core.sh +389 -0
- package/src/statusline-core/lib/helpers.sh +81 -0
- package/src/statusline-core/lib/json-parser.sh +71 -0
- package/src/statusline-core/themes/catppuccin.sh +32 -0
- package/src/statusline-core/themes/default.sh +37 -0
- package/src/statusline-core/themes/gruvbox.sh +32 -0
- package/src/statusline-core/themes/nord.sh +32 -0
- package/src/statusline-core/themes/tokyo-night.sh +32 -0
- package/src/store/canvas-store.ts +50 -0
- package/src/store/chat-store.ts +60 -0
- package/src/store/permission-store.ts +29 -0
- package/src/store/session-store.ts +52 -0
- package/src/store/statusline-store.ts +160 -0
- package/src/styles/global.css +117 -0
- package/src/themes/index.ts +149 -0
- package/src/types/canvas-graph.ts +24 -0
- package/src/types/sdk-messages.ts +156 -0
- package/src/types/statusline-fields.ts +67 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +26 -0
- 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
|
+
}
|