@manix-cli/manix 0.1.2 → 0.1.3

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/dist/agent.js CHANGED
@@ -75,6 +75,7 @@ class Agent {
75
75
  }
76
76
  async send(text) {
77
77
  this.pushMessage({ role: "user", content: text });
78
+ this.h.onStats?.(this.stats());
78
79
  await this.run();
79
80
  }
80
81
  async run() {
package/dist/markdown.js CHANGED
@@ -1,21 +1,35 @@
1
- import { t } from "./theme.js";
1
+ import chalk from "chalk";
2
+ import { t, color } from "./theme.js";
3
+ const codeBg = chalk.bgHex("#1e2030");
4
+ const codeText = chalk.hex(color.code).bgHex("#1e2030");
5
+ const gutterCol = chalk.hex(color.border).bgHex("#1e2030");
6
+ const labelCol = chalk.hex(color.faint);
7
+ const termWidth = () => Math.min(process.stdout.columns || 80, 120);
2
8
  function renderMarkdown(md) {
3
9
  const out = [];
4
10
  let inCode = false;
11
+ let lang = "";
5
12
  for (const line of String(md).split("\n")) {
6
13
  const fence = line.match(/^\s*```(\S*)/);
7
14
  if (fence) {
8
15
  inCode = !inCode;
9
- out.push(inCode ? t.faint("\u250C\u2574" + (fence[1] || "code")) : t.faint("\u2514\u2574"));
16
+ lang = fence[1] || "";
17
+ if (inCode) {
18
+ const label = lang ? ` ${lang} ` : " code ";
19
+ out.push(labelCol(" \u256D\u2500") + labelCol(label) + labelCol("\u2500".repeat(Math.max(2, termWidth() - label.length - 6))));
20
+ } else {
21
+ out.push(labelCol(" \u2570" + "\u2500".repeat(termWidth() - 3)));
22
+ }
10
23
  continue;
11
24
  }
12
25
  if (inCode) {
13
- out.push(t.faint("\u2502 ") + t.code(line));
26
+ const padded = " " + line + " ".repeat(Math.max(0, termWidth() - line.length - 3));
27
+ out.push(gutterCol(" \u2502") + codeText(padded));
14
28
  continue;
15
29
  }
16
30
  out.push(renderLine(line));
17
31
  }
18
- if (inCode) out.push(t.faint("\u2514\u2574"));
32
+ if (inCode) out.push(labelCol(" \u2570" + "\u2500".repeat(termWidth() - 3)));
19
33
  return out.join("\n");
20
34
  }
21
35
  function renderLine(line) {
package/dist/ui/Footer.js CHANGED
@@ -8,14 +8,16 @@ function Footer({ model, stats, yolo, cwd, exitHint }) {
8
8
  if (exitHint) {
9
9
  return /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { color: color.warn, children: "press ctrl+c again to exit" }) });
10
10
  }
11
- const pct = stats.contextLength ? Math.min(99, Math.round(stats.tokens / stats.contextLength * 100)) : 0;
11
+ const raw = stats.contextLength ? stats.tokens / stats.contextLength * 100 : 0;
12
+ const pctDisplay = raw < 1 ? raw.toFixed(1) : Math.min(99, Math.round(raw));
13
+ const pct = Math.min(99, raw);
12
14
  const pctColor = pct < 50 ? color.dim : pct < 80 ? color.warn : color.err;
13
15
  return /* @__PURE__ */ jsxs(Box, { paddingX: 1, children: [
14
16
  /* @__PURE__ */ jsx(Text, { color: color.faint, children: model }),
15
17
  /* @__PURE__ */ jsx(Text, { color: color.faint, children: SEP }),
16
18
  /* @__PURE__ */ jsxs(Text, { color: pctColor, children: [
17
19
  "ctx ",
18
- pct,
20
+ pctDisplay,
19
21
  "%"
20
22
  ] }),
21
23
  /* @__PURE__ */ jsx(Text, { color: color.faint, children: SEP }),
@@ -1,4 +1,4 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import React, { useState } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
4
  import chalk from "chalk";
@@ -39,7 +39,7 @@ function InputBox({ onSubmit, commands, active, history }) {
39
39
  return;
40
40
  }
41
41
  if (key.upArrow) {
42
- if (menuOpen && matches.length) return setMenuIdx((i) => (i + matches.length - 1) % matches.length);
42
+ if (menuOpen && matches.length) return setMenuIdx((i) => (i - 1 + matches.length) % matches.length);
43
43
  if (history.length) {
44
44
  const next = histIdx === -1 ? history.length - 1 : Math.max(0, histIdx - 1);
45
45
  setHistIdx(next);
@@ -97,14 +97,34 @@ function InputBox({ onSubmit, commands, active, history }) {
97
97
  { isActive: active }
98
98
  );
99
99
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
100
- menuOpen && matches.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: matches.slice(0, 6).map((c, i) => /* @__PURE__ */ jsxs(Text, { children: [
101
- /* @__PURE__ */ jsxs(Text, { color: i === sel ? color.accent : color.dim, children: [
102
- i === sel ? "\u276F " : " ",
103
- "/",
104
- c.name.padEnd(14)
105
- ] }),
106
- /* @__PURE__ */ jsx(Text, { color: color.faint, children: c.desc })
107
- ] }, c.name)) }),
100
+ menuOpen && matches.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: (() => {
101
+ const PAGE = 6;
102
+ const start = Math.min(Math.max(0, sel - PAGE + 1), Math.max(0, matches.length - PAGE));
103
+ const visible = matches.slice(start, start + PAGE);
104
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
105
+ start > 0 && /* @__PURE__ */ jsxs(Text, { color: color.faint, children: [
106
+ " \u2191 ",
107
+ start,
108
+ " more"
109
+ ] }),
110
+ visible.map((c, j) => {
111
+ const abs = start + j;
112
+ return /* @__PURE__ */ jsxs(Text, { children: [
113
+ /* @__PURE__ */ jsxs(Text, { color: abs === sel ? color.accent : color.dim, children: [
114
+ abs === sel ? "\u276F " : " ",
115
+ "/",
116
+ c.name.padEnd(14)
117
+ ] }),
118
+ /* @__PURE__ */ jsx(Text, { color: color.faint, children: c.desc })
119
+ ] }, c.name);
120
+ }),
121
+ start + PAGE < matches.length && /* @__PURE__ */ jsxs(Text, { color: color.faint, children: [
122
+ " \u2193 ",
123
+ matches.length - start - PAGE,
124
+ " more"
125
+ ] })
126
+ ] });
127
+ })() }),
108
128
  /* @__PURE__ */ jsx(Text, { color: color.faint, children: hr(2) }),
109
129
  /* @__PURE__ */ jsxs(Box, { paddingX: 1, children: [
110
130
  /* @__PURE__ */ jsx(Text, { color: color.accent, children: "\u276F " }),
@@ -7,10 +7,11 @@ import Mascot from "./Mascot.js";
7
7
  function LogItem({ item }) {
8
8
  switch (item.kind) {
9
9
  case "banner":
10
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
10
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 2, children: [
11
11
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
12
12
  /* @__PURE__ */ jsx(Mascot, {}),
13
13
  /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
14
+ /* @__PURE__ */ jsx(Text, { children: " " }),
14
15
  /* @__PURE__ */ jsxs(Text, { children: [
15
16
  /* @__PURE__ */ jsx(Text, { bold: true, color: color.user, children: "Manix" }),
16
17
  /* @__PURE__ */ jsxs(Text, { color: color.faint, children: [
@@ -22,7 +23,7 @@ function LogItem({ item }) {
22
23
  /* @__PURE__ */ jsx(Text, { color: color.faint, children: item.cwd })
23
24
  ] })
24
25
  ] }),
25
- /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
26
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, marginLeft: 1, children: [
26
27
  !item.hasManixmd && /* @__PURE__ */ jsxs(Text, { color: color.faint, children: [
27
28
  GLYPH.info,
28
29
  " MANIX.md not found \u2014 /init to create"
@@ -35,7 +36,7 @@ function LogItem({ item }) {
35
36
  ] })
36
37
  ] });
37
38
  case "user":
38
- return /* @__PURE__ */ jsxs(Box, { marginTop: 1, children: [
39
+ return /* @__PURE__ */ jsxs(Box, { marginTop: 2, children: [
39
40
  /* @__PURE__ */ jsxs(Text, { color: color.accent, children: [
40
41
  GLYPH.user,
41
42
  " "
package/dist/ui/Mascot.js CHANGED
@@ -1,11 +1,20 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
3
  import { Box, Text } from "ink";
4
- import { MASCOT, color, lerpColor } from "../theme.js";
4
+ import { color, lerpColor } from "../theme.js";
5
+ const ROWS = 5;
6
+ const lines = Array.from({ length: ROWS }, (_, i) => {
7
+ const glyphs = 2 * i + 1;
8
+ const pad = ROWS - 1 - i;
9
+ return { glyphs, pad };
10
+ });
5
11
  function Mascot() {
6
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginRight: 2, children: MASCOT.map((row, i) => {
7
- const c = lerpColor(color.accent, color.amber, MASCOT.length > 1 ? i / (MASCOT.length - 1) : 0);
8
- return /* @__PURE__ */ jsx(Text, { children: [...row].map((ch, j) => ch === "#" ? c("\u2588\u2588") : " ").join("") }, i);
12
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginRight: 2, children: lines.map(({ glyphs, pad }, i) => {
13
+ const c = lerpColor(color.accent, color.amber, i / (ROWS - 1));
14
+ return /* @__PURE__ */ jsxs(Text, { children: [
15
+ " ".repeat(pad),
16
+ c("\u25B2".repeat(glyphs))
17
+ ] }, i);
9
18
  }) });
10
19
  }
11
20
  export {
package/dist/ui/Picker.js CHANGED
@@ -17,16 +17,18 @@ function Picker({ title, load, onSelect, onCancel }) {
17
17
  const filtered = (items || []).filter(
18
18
  (it) => (it.label + " " + (it.extra || "")).toLowerCase().includes(q.toLowerCase())
19
19
  );
20
- const visible = filtered.slice(0, 10);
21
- const sel = visible.length ? Math.min(idx, visible.length - 1) : 0;
20
+ const PAGE = 10;
21
+ const sel = filtered.length ? (idx % filtered.length + filtered.length) % filtered.length : 0;
22
+ const start = Math.min(Math.max(0, sel - PAGE + 1), Math.max(0, filtered.length - PAGE));
23
+ const visible = filtered.slice(start, start + PAGE);
22
24
  useInput((input, key) => {
23
25
  if (key.escape) return onCancel();
24
26
  if (key.return) {
25
- if (visible.length) onSelect(visible[sel]);
27
+ if (filtered.length) onSelect(filtered[sel]);
26
28
  return;
27
29
  }
28
- if (key.upArrow) return setIdx(() => Math.max(0, sel - 1));
29
- if (key.downArrow) return setIdx(() => Math.min(visible.length - 1, sel + 1));
30
+ if (key.upArrow) return setIdx((i) => (i - 1 + filtered.length) % filtered.length);
31
+ if (key.downArrow) return setIdx((i) => (i + 1) % filtered.length);
30
32
  if (key.backspace || key.delete) {
31
33
  setQ((s) => s.slice(0, -1));
32
34
  setIdx(0);
@@ -46,17 +48,30 @@ function Picker({ title, load, onSelect, onCancel }) {
46
48
  ] }),
47
49
  error && /* @__PURE__ */ jsx(Text, { color: color.err, children: error }),
48
50
  !items && !error && /* @__PURE__ */ jsx(Text, { color: color.dim, children: "loading\u2026" }),
49
- visible.map((it, i) => /* @__PURE__ */ jsxs(Text, { children: [
50
- /* @__PURE__ */ jsxs(Text, { color: i === sel ? color.accent : color.user, children: [
51
- i === sel ? "\u276F " : " ",
52
- it.label
53
- ] }),
54
- it.extra ? /* @__PURE__ */ jsxs(Text, { color: color.dim, children: [
55
- " ",
56
- it.extra
57
- ] }) : null
58
- ] }, it.id ?? it.label)),
59
- items && !visible.length && /* @__PURE__ */ jsx(Text, { color: color.dim, children: "no matches" }),
51
+ start > 0 && /* @__PURE__ */ jsxs(Text, { color: color.faint, children: [
52
+ " \u2191 ",
53
+ start,
54
+ " more"
55
+ ] }),
56
+ visible.map((it) => {
57
+ const abs = filtered.indexOf(it);
58
+ return /* @__PURE__ */ jsxs(Text, { children: [
59
+ /* @__PURE__ */ jsxs(Text, { color: abs === sel ? color.accent : color.user, children: [
60
+ abs === sel ? "\u276F " : " ",
61
+ it.label
62
+ ] }),
63
+ it.extra ? /* @__PURE__ */ jsxs(Text, { color: color.dim, children: [
64
+ " ",
65
+ it.extra
66
+ ] }) : null
67
+ ] }, it.id ?? it.label);
68
+ }),
69
+ start + PAGE < filtered.length && /* @__PURE__ */ jsxs(Text, { color: color.faint, children: [
70
+ " \u2193 ",
71
+ filtered.length - start - PAGE,
72
+ " more"
73
+ ] }),
74
+ items && !filtered.length && /* @__PURE__ */ jsx(Text, { color: color.dim, children: "no matches" }),
60
75
  /* @__PURE__ */ jsxs(Text, { color: color.faint, children: [
61
76
  "\u2191\u2193 select \xB7 enter confirm \xB7 esc cancel \xB7 ",
62
77
  filtered.length,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manix-cli/manix",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Manix — a fast, beautiful terminal coding agent powered by OpenRouter. Any model, one key.",
5
5
  "type": "module",
6
6
  "bin": {