@lardexx/arenacode 2.5.5 → 2.5.6
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/package.json +1 -1
- package/src/cli.js +4 -3
- package/src/config.js +5 -2
- package/src/tui/app.js +14 -17
- package/src/tui/logo.js +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lardexx/arenacode",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.6",
|
|
4
4
|
"description": "Terminal client for ArenaCode: talks to an arena-bridge, streams the Agent Mode timeline, and runs local commands and file operations on your PC. Node port of the ArenaCode desktop client.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
package/src/cli.js
CHANGED
|
@@ -144,9 +144,10 @@ async function cmdInit(flags, { tail = true } = {}) {
|
|
|
144
144
|
write('');
|
|
145
145
|
const url = await ask(` Bridge URL ${cfg.url ? c.gray(`[${cfg.url}]`) : ''}: `, { default: cfg.url });
|
|
146
146
|
const key = await ask(` API key ${cfg.key ? c.gray('[configured]') : ''}: `, { default: cfg.key });
|
|
147
|
-
const folder = await ask(` Open folder ${c.gray(`[${cfg.folder || process.cwd()}]`)}: `, { default: cfg.folder || process.cwd() });
|
|
148
147
|
|
|
149
|
-
|
|
148
|
+
// no folder question: arenacode always works in the directory it was started from
|
|
149
|
+
const next = { ...cfg, url: String(url).replace(/\/+$/, ''), key: String(key) };
|
|
150
|
+
delete next.folder;
|
|
150
151
|
const file = writeConfig(next);
|
|
151
152
|
write(` ${c.green('✓')} saved ${c.gray(file)}`);
|
|
152
153
|
|
|
@@ -184,7 +185,7 @@ function cmdConfig(positional, flags) {
|
|
|
184
185
|
const name = key;
|
|
185
186
|
const val = rest.join(' ');
|
|
186
187
|
if (!name || val === '') {
|
|
187
|
-
write(`usage: ${SELF} config set <url|key|
|
|
188
|
+
write(`usage: ${SELF} config set <url|key|lang|mode|pc_access> <value>`);
|
|
188
189
|
return 2;
|
|
189
190
|
}
|
|
190
191
|
const patch = {};
|
package/src/config.js
CHANGED
|
@@ -121,9 +121,12 @@ function resolveKey(cfg, flagKey) {
|
|
|
121
121
|
return String(flagKey || process.env.ARENACODE_KEY || cfg.key || '').trim();
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* The folder arenacode works in: the one you launched it from. No stored default, so starting it in
|
|
126
|
+
* another project just works — `--folder` (or ARENACODE_FOLDER) still forces one.
|
|
127
|
+
*/
|
|
124
128
|
function openFolder(cfg, flagFolder) {
|
|
125
|
-
|
|
126
|
-
return folder;
|
|
129
|
+
return path.resolve(flagFolder || process.env.ARENACODE_FOLDER || process.cwd());
|
|
127
130
|
}
|
|
128
131
|
|
|
129
132
|
module.exports = {
|
package/src/tui/app.js
CHANGED
|
@@ -95,7 +95,10 @@ class App {
|
|
|
95
95
|
// ---------------------------------------------------------------- lifecycle
|
|
96
96
|
async start() {
|
|
97
97
|
this.term.enter();
|
|
98
|
-
this.term.on('key', (chunk) =>
|
|
98
|
+
this.term.on('key', (chunk) => {
|
|
99
|
+
this.parser.feed(chunk);
|
|
100
|
+
this.flush();
|
|
101
|
+
});
|
|
99
102
|
this.term.on('resize', () => this.invalidate());
|
|
100
103
|
this.running = true;
|
|
101
104
|
|
|
@@ -124,6 +127,14 @@ class App {
|
|
|
124
127
|
this.dirty = true;
|
|
125
128
|
}
|
|
126
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Keys used to wait for the render loop's next turn (up to 33 ms), which on Windows reads as
|
|
132
|
+
* lag when tapping through a list. Paint on the keystroke itself and keep the loop as fallback.
|
|
133
|
+
*/
|
|
134
|
+
flush() {
|
|
135
|
+
if (this.dirty && !this.rendering) this.render();
|
|
136
|
+
}
|
|
137
|
+
|
|
127
138
|
maybeRender() {
|
|
128
139
|
if (this.dirty && !this.rendering) this.render();
|
|
129
140
|
}
|
|
@@ -463,7 +474,6 @@ class App {
|
|
|
463
474
|
if (h) this.push({ kind: 'system', text: `bridge v${h.version} · ${h.executor_mode} · claimable ${h.tasks.claimable}` });
|
|
464
475
|
else this.toast('bridge unreachable', 'error');
|
|
465
476
|
} },
|
|
466
|
-
{ title: 'Bridge workspace files', run: () => this.openFiles() },
|
|
467
477
|
{ title: 'Help', hint: 'f1', run: () => this.openHelp() },
|
|
468
478
|
{ title: 'Quit', hint: 'ctrl+x q', run: () => this.quit() },
|
|
469
479
|
].map((cmd) => ({ ...cmd, slash: '/' + cmd.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/-+$/, ''), group: 'Commands' }));
|
|
@@ -474,7 +484,6 @@ class App {
|
|
|
474
484
|
return [
|
|
475
485
|
{ slash: '/new', title: 'Start a new session', hint: 'ctrl+x n', group: 'Session', run: () => this.commands()[1].run() },
|
|
476
486
|
{ slash: '/tasks', title: 'Show the task queue', hint: 'ctrl+x l', group: 'Session', run: () => this.openTasks() },
|
|
477
|
-
{ slash: '/files', title: 'Browse the workspace files', hint: '', group: 'Session', run: () => this.openFiles() },
|
|
478
487
|
{ slash: '/mode', title: 'Switch agent / plan', hint: 'tab', group: 'Session', run: () => this.commands()[5].run() },
|
|
479
488
|
{ slash: '/theme', title: 'Cycle the colour theme', hint: 'ctrl+x t', group: 'Session', run: () => this.commands()[6].run() },
|
|
480
489
|
{ slash: '/status', title: 'Ping the bridge', hint: '', group: 'Session', run: () => this.commands()[7].run() },
|
|
@@ -1071,12 +1080,11 @@ class App {
|
|
|
1071
1080
|
}
|
|
1072
1081
|
|
|
1073
1082
|
modelName() {
|
|
1074
|
-
return
|
|
1083
|
+
return 'auto';
|
|
1075
1084
|
}
|
|
1076
1085
|
|
|
1077
1086
|
providerLabel() {
|
|
1078
|
-
|
|
1079
|
-
return `bridge ${v}`;
|
|
1087
|
+
return 'arena';
|
|
1080
1088
|
}
|
|
1081
1089
|
|
|
1082
1090
|
statusText() {
|
|
@@ -1105,13 +1113,11 @@ class App {
|
|
|
1105
1113
|
|
|
1106
1114
|
if (this.isHome()) {
|
|
1107
1115
|
const logo = W2.centerLines(logoLines(t), W);
|
|
1108
|
-
const notify = this.notifyLine(W);
|
|
1109
1116
|
const blockH = logo.length + 1 + prompt.lines.length + 2 + 1;
|
|
1110
1117
|
const top = Math.max(1, Math.floor((H - 2 - blockH) / 2));
|
|
1111
1118
|
for (let i = 0; i < top; i++) frame.push('');
|
|
1112
1119
|
frame.push(...logo);
|
|
1113
1120
|
frame.push('');
|
|
1114
|
-
if (notify) frame.push(notify);
|
|
1115
1121
|
const promptStart = frame.length;
|
|
1116
1122
|
this._promptTop = promptStart;
|
|
1117
1123
|
frame.push(...prompt.lines);
|
|
@@ -1170,15 +1176,6 @@ class App {
|
|
|
1170
1176
|
if (this.dirty) setTimeout(() => this.maybeRender(), 16);
|
|
1171
1177
|
}
|
|
1172
1178
|
|
|
1173
|
-
notifyLine(W) {
|
|
1174
|
-
const t = this.theme;
|
|
1175
|
-
const st = this.state;
|
|
1176
|
-
if (!st.connected) {
|
|
1177
|
-
return W2.notifyLine(t, { width: W, command: '/connect', text: ` bridge offline at ${this.url}` });
|
|
1178
|
-
}
|
|
1179
|
-
return '';
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
1179
|
tipLine(W) {
|
|
1183
1180
|
const t = this.theme;
|
|
1184
1181
|
const tips = [
|
package/src/tui/logo.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const { fgSeq, bgSeq, RESET, tint } = require('./theme');
|
|
13
13
|
|
|
14
14
|
const LOGO = {
|
|
15
|
-
left: [' ', '
|
|
15
|
+
left: [' ', ';::█ █▀▀█ █▀▀█ █▀▀▄ ;::█', '█;;█ █▀▀▄ █^^^ █__█ █;;█', ' : ▀~~▀ ▀▀▀▀ ▀~~▀ :'],
|
|
16
16
|
right: [' ▄ ', '█▀▀▀ █▀▀█ █▀▀█ █▀▀█', '█___ █__█ █__█ █^^^', '▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀'],
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -33,6 +33,9 @@ function paintLine(line, color, shadow, bold) {
|
|
|
33
33
|
else if (ch === '^') out += bgFill(shadow, '▀', color, bold);
|
|
34
34
|
else if (ch === '~') out += fgPaint(shadow, '▀', bold);
|
|
35
35
|
else if (ch === ',') out += fgPaint(shadow, '▄', bold);
|
|
36
|
+
// plain half blocks in the letter colour: lets a glyph put a stroke on only one half of a cell
|
|
37
|
+
else if (ch === ':') out += fgPaint(color, '▀', bold);
|
|
38
|
+
else if (ch === ';') out += fgPaint(color, '▄', bold);
|
|
36
39
|
else out += fgPaint(color, ch, bold);
|
|
37
40
|
}
|
|
38
41
|
return out;
|