@oxecli/oxe 1.0.100 → 1.0.101
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/README.md +38 -0
- package/dist/ui.js +31 -4
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
**Oxe**
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
AI-powered coding agent for your terminal.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Oxe is a terminal-based AI coding agent built for developers who want to work with AI directly inside their development environment. Give Oxe a task and let it inspect your codebase, edit files, run commands, and iterate with you.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
**Installation**
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
Install Oxe globally with npm:
|
|
18
|
+
|
|
19
|
+
* npm install -g @oxecli/oxe
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Features
|
|
24
|
+
|
|
25
|
+
* Terminal-native — Work directly from your CLI.
|
|
26
|
+
* Codebase-aware — Inspect and understand your project before making changes.
|
|
27
|
+
* File editing — Create, modify, and refactor files.
|
|
28
|
+
* Command execution — Run development commands and inspect their output.
|
|
29
|
+
* Interactive prompts — Continue typing and interacting while the agent works.
|
|
30
|
+
* Diff viewer — Review file changes directly in the terminal.
|
|
31
|
+
* Tool execution — See what Oxe is doing as it works.
|
|
32
|
+
* AI-powered — Use the AI model configured for your Oxe deployment.
|
|
33
|
+
* Minimal interface — Designed to stay out of the way while you code.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
Oxe can inspect your project, make the required changes, run commands, and show you what it is doing along the way.
|
|
38
|
+
|
package/dist/ui.js
CHANGED
|
@@ -539,10 +539,13 @@ export function renderTableString(rows, opts = {}) {
|
|
|
539
539
|
export function formatDuration(seconds) {
|
|
540
540
|
const s = Math.max(0, seconds);
|
|
541
541
|
if (s < 60) {
|
|
542
|
+
// Sub-minute: update at 0.1s resolution.
|
|
542
543
|
return `${s.toFixed(1)}s`;
|
|
543
544
|
}
|
|
545
|
+
// Past one minute: update at whole-second resolution so the timer reads
|
|
546
|
+
// "1m 0s", "1m 1s", ... (not fractional seconds under a minutes prefix).
|
|
544
547
|
const mins = Math.floor(s / 60);
|
|
545
|
-
const remSecs = (s % 60)
|
|
548
|
+
const remSecs = Math.floor(s % 60);
|
|
546
549
|
return `${mins}m ${remSecs}s`;
|
|
547
550
|
}
|
|
548
551
|
export function tickDuration(seconds) {
|
|
@@ -747,15 +750,39 @@ function dockRenderBox() {
|
|
|
747
750
|
/**
|
|
748
751
|
* Redraw the docked prompt box with the given buffer/caret, keeping whatever
|
|
749
752
|
* content already streams above it. Used to make the prompt field live-edit
|
|
750
|
-
* while a query runs. Erases the box
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
+
* while a query runs. Erases the box, writes the new frame, and parks the
|
|
754
|
+
* cursor at the caret. Preserves exactly one blank row between the last content
|
|
755
|
+
* and the box. When a transient (thinking/working spinner) is parked above the
|
|
756
|
+
* box, it is rebuilt above the new frame and the physical cursor stays on that
|
|
757
|
+
* transient row, so streaming content is never pulled into the prompt.
|
|
753
758
|
*/
|
|
754
759
|
export function dockRenderPrompt(buffer, pasteSpans, prefix, label, hints) {
|
|
755
760
|
if (!docked || dockBoxRows < 1)
|
|
756
761
|
return;
|
|
762
|
+
// If a thinking/working spinner is currently parked above the box, typing
|
|
763
|
+
// must NOT disturb it. dockEraseBox() wipes that transient row and resets
|
|
764
|
+
// its state; the still-running spinner then keeps drawing at the physical
|
|
765
|
+
// caret (now inside the box), pulling streaming content into the prompt.
|
|
766
|
+
// Capture the transient before erasing so we can rebuild it above the frame
|
|
767
|
+
// and park the cursor back on the transient row, keeping the box intact.
|
|
768
|
+
const wasTransient = dockTransient;
|
|
769
|
+
const wasRel = dockRel;
|
|
757
770
|
const { frame, cursorRow, cursorCol, totalRows } = renderBufferWithCursor(buffer, pasteSpans, prefix, label, buffer.length, hints);
|
|
758
771
|
dockEraseBox();
|
|
772
|
+
if (wasTransient) {
|
|
773
|
+
// Rebuild the transient row(s) and gap above the new frame, then park the
|
|
774
|
+
// physical cursor at the transient row so the running spinner keeps
|
|
775
|
+
// drawing THERE instead of inside the prompt box.
|
|
776
|
+
process.stdout.write("\n".repeat(wasRel) + frame);
|
|
777
|
+
process.stdout.write(`\x1b[${totalRows - 1 + wasRel}A\r`);
|
|
778
|
+
dockSetFrame(frame, totalRows);
|
|
779
|
+
docked = true;
|
|
780
|
+
dockGap = false;
|
|
781
|
+
dockTransient = true;
|
|
782
|
+
dockRel = wasRel;
|
|
783
|
+
dockCaretBelow = 0;
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
759
786
|
process.stdout.write(frame);
|
|
760
787
|
// Park the cursor at the caret inside the box (cursorRow is 1-indexed, so
|
|
761
788
|
// the caret sits cursorRow rows below boxTop).
|