nexrall-code 0.5.89 → 0.5.90

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 (2) hide show
  1. package/dist/index.js +137 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9875,8 +9875,10 @@ var require_client = __commonJS({
9875
9875
  exports2.revokeRefreshToken = revokeRefreshToken2;
9876
9876
  exports2.describeAttachment = describeAttachment2;
9877
9877
  exports2.getBalance = getBalance3;
9878
+ exports2.getUsageDaily = getUsageDaily;
9878
9879
  exports2.exchangeVscodeCode = exchangeVscodeCode;
9879
9880
  exports2.login = login2;
9881
+ exports2.getUserProfile = getUserProfile;
9880
9882
  var eventsource_parser_1 = require_dist();
9881
9883
  var node_fetch_1 = __importDefault((init_src(), __toCommonJS(src_exports)));
9882
9884
  var crypto_1 = __require("crypto");
@@ -10646,6 +10648,27 @@ var require_client = __commonJS({
10646
10648
  const data = await response.json();
10647
10649
  return typeof data.balance === "number" ? data.balance : 0;
10648
10650
  }
10651
+ async function getUsageDaily(days = 30) {
10652
+ const fetchOnce = () => (0, node_fetch_1.default)(`${exports2.API_BASE}/api/user/usage-daily?days=${days}`, { method: "GET", headers: authHeaders() });
10653
+ let response = await fetchOnce();
10654
+ if (response.status === 401 || response.status === 403) {
10655
+ const body = await response.text().catch(() => "");
10656
+ if (isExpiredTokenResponse(response.status, body) && await refreshAccessToken()) {
10657
+ response = await fetchOnce();
10658
+ } else {
10659
+ throw new Error(`API error ${response.status}: ${body}`);
10660
+ }
10661
+ }
10662
+ if (!response.ok) {
10663
+ const errText = await response.text();
10664
+ throw new Error(`API error ${response.status}: ${errText}`);
10665
+ }
10666
+ const data = await response.json();
10667
+ return {
10668
+ days: Array.isArray(data.days) ? data.days : [],
10669
+ totalSpent: typeof data.totalSpent === "number" ? data.totalSpent : 0
10670
+ };
10671
+ }
10649
10672
  async function exchangeVscodeCode(code) {
10650
10673
  const response = await (0, node_fetch_1.default)(`${exports2.API_BASE}/api/auth/vscode-exchange`, {
10651
10674
  method: "POST",
@@ -10685,6 +10708,23 @@ var require_client = __commonJS({
10685
10708
  email: data.email ?? email
10686
10709
  };
10687
10710
  }
10711
+ async function getUserProfile() {
10712
+ const fetchOnce = () => (0, node_fetch_1.default)(`${exports2.API_BASE}/api/user/profile`, { method: "GET", headers: authHeaders() });
10713
+ let response = await fetchOnce();
10714
+ if (response.status === 401 || response.status === 403) {
10715
+ const body = await response.text().catch(() => "");
10716
+ if (isExpiredTokenResponse(response.status, body) && await refreshAccessToken()) {
10717
+ response = await fetchOnce();
10718
+ } else {
10719
+ throw new Error(`API error ${response.status}: ${body}`);
10720
+ }
10721
+ }
10722
+ if (!response.ok) {
10723
+ const errText = await response.text();
10724
+ throw new Error(`API error ${response.status}: ${errText}`);
10725
+ }
10726
+ return await response.json();
10727
+ }
10688
10728
  }
10689
10729
  });
10690
10730
 
@@ -147336,6 +147376,17 @@ var setTextNodeValue = (node, text) => {
147336
147376
  node.nodeValue = text;
147337
147377
  markNodeAsDirty(node);
147338
147378
  };
147379
+ var addLayoutListener = (rootNode, listener) => {
147380
+ if (rootNode.nodeName !== "ink-root") {
147381
+ return () => {
147382
+ };
147383
+ }
147384
+ rootNode.internal_layoutListeners ??= /* @__PURE__ */ new Set();
147385
+ rootNode.internal_layoutListeners.add(listener);
147386
+ return () => {
147387
+ rootNode.internal_layoutListeners?.delete(listener);
147388
+ };
147389
+ };
147339
147390
  var emitLayoutListeners = (rootNode) => {
147340
147391
  if (rootNode.nodeName !== "ink-root" || !rootNode.internal_layoutListeners) {
147341
147392
  return;
@@ -151674,6 +151725,21 @@ var import_react29 = __toESM(require_react(), 1);
151674
151725
 
151675
151726
  // ../../node_modules/.pnpm/ink@7.1.1_@types+react@19.2.18_react@19.2.8/node_modules/ink/build/hooks/use-cursor.js
151676
151727
  var import_react30 = __toESM(require_react(), 1);
151728
+ var useCursor = () => {
151729
+ const context = (0, import_react30.useContext)(CursorContext_default);
151730
+ const positionRef = (0, import_react30.useRef)(void 0);
151731
+ const setCursorPosition = (0, import_react30.useCallback)((position) => {
151732
+ positionRef.current = position;
151733
+ }, []);
151734
+ (0, import_react30.useInsertionEffect)(() => {
151735
+ context.setCursorPosition(positionRef.current);
151736
+ return () => {
151737
+ context.setCursorPosition(void 0);
151738
+ };
151739
+ });
151740
+ return { setCursorPosition };
151741
+ };
151742
+ var use_cursor_default = useCursor;
151677
151743
 
151678
151744
  // ../../node_modules/.pnpm/ink@7.1.1_@types+react@19.2.18_react@19.2.8/node_modules/ink/build/hooks/use-animation.js
151679
151745
  var import_react31 = __toESM(require_react(), 1);
@@ -151683,6 +151749,46 @@ var import_react32 = __toESM(require_react(), 1);
151683
151749
 
151684
151750
  // ../../node_modules/.pnpm/ink@7.1.1_@types+react@19.2.18_react@19.2.8/node_modules/ink/build/hooks/use-box-metrics.js
151685
151751
  var import_react33 = __toESM(require_react(), 1);
151752
+ var emptyMetrics = {
151753
+ width: 0,
151754
+ height: 0,
151755
+ left: 0,
151756
+ top: 0
151757
+ };
151758
+ var findRootNode = (node) => {
151759
+ if (!node) {
151760
+ return void 0;
151761
+ }
151762
+ if (!node.parentNode) {
151763
+ return node.nodeName === "ink-root" ? node : void 0;
151764
+ }
151765
+ return findRootNode(node.parentNode);
151766
+ };
151767
+ var useBoxMetrics = (ref) => {
151768
+ const [metrics, setMetrics] = (0, import_react33.useState)(emptyMetrics);
151769
+ const [hasMeasured, setHasMeasured] = (0, import_react33.useState)(false);
151770
+ const updateMetrics = (0, import_react33.useCallback)(() => {
151771
+ const layout = ref.current?.yogaNode?.getComputedLayout() ?? emptyMetrics;
151772
+ setMetrics((previousMetrics) => {
151773
+ const hasChanged = previousMetrics.width !== layout.width || previousMetrics.height !== layout.height || previousMetrics.left !== layout.left || previousMetrics.top !== layout.top;
151774
+ return hasChanged ? layout : previousMetrics;
151775
+ });
151776
+ setHasMeasured(Boolean(ref.current));
151777
+ }, [ref]);
151778
+ (0, import_react33.useEffect)(updateMetrics);
151779
+ (0, import_react33.useEffect)(() => {
151780
+ const rootNode = findRootNode(ref.current);
151781
+ if (!rootNode) {
151782
+ return;
151783
+ }
151784
+ return addLayoutListener(rootNode, updateMetrics);
151785
+ });
151786
+ return (0, import_react33.useMemo)(() => ({
151787
+ ...metrics,
151788
+ hasMeasured
151789
+ }), [metrics, hasMeasured]);
151790
+ };
151791
+ var use_box_metrics_default = useBoxMetrics;
151686
151792
 
151687
151793
  // src/ui/trustPrompt.tsx
151688
151794
  var CHOICES = ["Yes, I trust this folder", "No, exit"];
@@ -151847,6 +151953,24 @@ function renderInputSlices(line, cursorPos) {
151847
151953
  after: line.slice(end)
151848
151954
  };
151849
151955
  }
151956
+ function caretPosition(opts) {
151957
+ const columns = Math.max(1, opts.columns);
151958
+ const logicalLines = opts.line.split("\n");
151959
+ const beforeLines = opts.line.slice(0, opts.cursorPos).split("\n");
151960
+ const caretLineIndex = beforeLines.length - 1;
151961
+ const widthBeforeCaret = (caretLineIndex === 0 ? opts.promptWidth : 0) + visibleLen(beforeLines[caretLineIndex] ?? "");
151962
+ let rowsAboveCaretLine = 0;
151963
+ for (let i2 = 0; i2 < caretLineIndex; i2++) {
151964
+ const width = (i2 === 0 ? opts.promptWidth : 0) + visibleLen(logicalLines[i2] ?? "");
151965
+ rowsAboveCaretLine += Math.max(1, Math.ceil(width / columns));
151966
+ }
151967
+ return {
151968
+ x: widthBeforeCaret % columns,
151969
+ // Where the input box begins (measured), plus however far down its own
151970
+ // wrapped/multi-line content the caret has reached.
151971
+ y: opts.inputRowTop + rowsAboveCaretLine + Math.floor(widthBeforeCaret / columns)
151972
+ };
151973
+ }
151850
151974
  var CTRL_C_QUIT_WINDOW_MS = 3e3;
151851
151975
  var CTRL_C_HINT = "Press Ctrl+C again to exit";
151852
151976
  function decideCtrlC(state) {
@@ -151872,7 +151996,6 @@ function repaintAfterResizeSettle() {
151872
151996
  void instance.waitUntilRenderFlush().then(() => {
151873
151997
  if (inkInstance !== instance)
151874
151998
  return;
151875
- process.stdout.write("\x1B[0J");
151876
151999
  forceFullRedrawRef?.();
151877
152000
  });
151878
152001
  }
@@ -152124,6 +152247,18 @@ var App2 = ({ onReady }) => {
152124
152247
  });
152125
152248
  }, []);
152126
152249
  const slices = renderInputSlices(line, cursorPos);
152250
+ const inputRowRef = (0, import_react35.useRef)(null);
152251
+ const inputMetrics = use_box_metrics_default(inputRowRef);
152252
+ const { setCursorPosition } = use_cursor_default();
152253
+ setCursorPosition(
152254
+ inputMetrics.hasMeasured ? caretPosition({
152255
+ promptWidth: visibleLen(prompt2),
152256
+ line,
152257
+ cursorPos,
152258
+ columns: process.stdout.columns || 80,
152259
+ inputRowTop: inputMetrics.top
152260
+ }) : void 0
152261
+ );
152127
152262
  return /* @__PURE__ */ import_react35.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react35.default.createElement(Static, { items, key: staticKey }, (item) => /* @__PURE__ */ import_react35.default.createElement(Text, { key: item.id }, item.content)), live ? /* @__PURE__ */ import_react35.default.createElement(Text, null, live) : null, /* @__PURE__ */ import_react35.default.createElement(
152128
152263
  Box_default,
152129
152264
  {
@@ -152134,7 +152269,7 @@ var App2 = ({ onReady }) => {
152134
152269
  borderRight: false,
152135
152270
  borderDimColor: true
152136
152271
  }
152137
- ), /* @__PURE__ */ import_react35.default.createElement(Box_default, null, /* @__PURE__ */ import_react35.default.createElement(Text, { wrap: "hard" }, /* @__PURE__ */ import_react35.default.createElement(Text, null, prompt2), /* @__PURE__ */ import_react35.default.createElement(Text, null, slices.before), /* @__PURE__ */ import_react35.default.createElement(Text, { inverse: true }, slices.atCursor), /* @__PURE__ */ import_react35.default.createElement(Text, null, slices.after))), /* @__PURE__ */ import_react35.default.createElement(
152272
+ ), /* @__PURE__ */ import_react35.default.createElement(Box_default, { ref: inputRowRef }, /* @__PURE__ */ import_react35.default.createElement(Text, { wrap: "hard" }, /* @__PURE__ */ import_react35.default.createElement(Text, null, prompt2), /* @__PURE__ */ import_react35.default.createElement(Text, null, slices.before), /* @__PURE__ */ import_react35.default.createElement(Text, { inverse: true }, slices.atCursor), /* @__PURE__ */ import_react35.default.createElement(Text, null, slices.after))), /* @__PURE__ */ import_react35.default.createElement(
152138
152273
  Box_default,
152139
152274
  {
152140
152275
  borderStyle: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexrall-code",
3
- "version": "0.5.89",
3
+ "version": "0.5.90",
4
4
  "description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
5
5
  "keywords": [
6
6
  "ai",