codemaxxing 1.0.12 → 1.0.13

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/index.js CHANGED
@@ -4,6 +4,7 @@ import React, { useState, useEffect, useCallback } from "react";
4
4
  import { render, Box, Text, useInput, useApp, useStdout } from "ink";
5
5
  import { EventEmitter } from "events";
6
6
  import TextInput from "ink-text-input";
7
+ import { consumePendingPasteEndMarkerChunk } from "./utils/paste.js";
7
8
  import { CodingAgent } from "./agent.js";
8
9
  import { loadConfig, saveConfig, detectLocalProvider, detectLocalProviderDetailed, parseCLIArgs, applyOverrides, listModels } from "./config.js";
9
10
  import { listSessions, getSession, loadMessages, deleteSession } from "./utils/sessions.js";
@@ -1757,6 +1758,7 @@ let bracketedBuffer = "";
1757
1758
  let inBracketedPaste = false;
1758
1759
  let burstBuffer = "";
1759
1760
  let burstTimer = null;
1761
+ let pendingPasteEndMarker = { active: false, buffer: "" };
1760
1762
  const BURST_WINDOW_MS = 50; // Long enough for slow terminals to finish delivering paste
1761
1763
  // Debug paste: set CODEMAXXING_DEBUG_PASTE=1 to log all stdin chunks to /tmp/codemaxxing-paste-debug.log
1762
1764
  const PASTE_DEBUG = process.env.CODEMAXXING_DEBUG_PASTE === "1";
@@ -1778,6 +1780,10 @@ function handlePasteContent(content) {
1778
1780
  const lineCount = normalized.split("\n").length;
1779
1781
  if (lineCount > 2) {
1780
1782
  // Real multiline paste → badge it
1783
+ // Some terminals dribble the closing bracketed-paste marker (`[201~`)
1784
+ // one character at a time *after* the paste payload. Arm a tiny
1785
+ // swallow-state so those trailing fragments never leak into the input.
1786
+ pendingPasteEndMarker = { active: true, buffer: "" };
1781
1787
  pasteEvents.emit("paste", { content: normalized, lines: lineCount });
1782
1788
  return;
1783
1789
  }
@@ -1826,6 +1832,13 @@ process.stdin.emit = function (event, ...args) {
1826
1832
  const chunk = args[0];
1827
1833
  let data = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString("utf-8") : String(chunk);
1828
1834
  pasteLog(`CHUNK len=${data.length} raw=${data.substring(0, 200)}`);
1835
+ const pendingResult = consumePendingPasteEndMarkerChunk(data, pendingPasteEndMarker);
1836
+ pendingPasteEndMarker = pendingResult.nextState;
1837
+ data = pendingResult.remaining;
1838
+ if (!data) {
1839
+ pasteLog("PENDING END MARKER swallowed chunk");
1840
+ return true;
1841
+ }
1829
1842
  // Aggressively strip ALL bracketed paste escape sequences from every chunk,
1830
1843
  // regardless of context. Some terminals split markers across chunks or send
1831
1844
  // them in unexpected positions. We never want \x1b[200~ or \x1b[201~ (or
@@ -0,0 +1,9 @@
1
+ export interface PendingPasteEndState {
2
+ active: boolean;
3
+ buffer: string;
4
+ }
5
+ export declare function consumePendingPasteEndMarkerChunk(chunk: string, state: PendingPasteEndState): {
6
+ remaining: string;
7
+ nextState: PendingPasteEndState;
8
+ swallowed: boolean;
9
+ };
@@ -0,0 +1,48 @@
1
+ const END_MARKERS = ["\x1b[201~", "[201~", "201~"];
2
+ function isPrefixOfAnyMarker(value) {
3
+ return END_MARKERS.some((marker) => marker.startsWith(value));
4
+ }
5
+ function stripLeadingFullMarkers(value) {
6
+ let remaining = value;
7
+ let stripped = false;
8
+ outer: while (remaining.length > 0) {
9
+ for (const marker of END_MARKERS) {
10
+ if (remaining.startsWith(marker)) {
11
+ remaining = remaining.slice(marker.length);
12
+ stripped = true;
13
+ continue outer;
14
+ }
15
+ }
16
+ break;
17
+ }
18
+ return { remaining, stripped };
19
+ }
20
+ export function consumePendingPasteEndMarkerChunk(chunk, state) {
21
+ if (!state.active) {
22
+ return { remaining: chunk, nextState: state, swallowed: false };
23
+ }
24
+ let combined = state.buffer + chunk;
25
+ let swallowed = false;
26
+ const stripped = stripLeadingFullMarkers(combined);
27
+ combined = stripped.remaining;
28
+ swallowed = stripped.stripped;
29
+ if (!combined) {
30
+ return {
31
+ remaining: "",
32
+ nextState: { active: false, buffer: "" },
33
+ swallowed,
34
+ };
35
+ }
36
+ if (isPrefixOfAnyMarker(combined)) {
37
+ return {
38
+ remaining: "",
39
+ nextState: { active: true, buffer: combined },
40
+ swallowed: true,
41
+ };
42
+ }
43
+ return {
44
+ remaining: combined,
45
+ nextState: { active: false, buffer: "" },
46
+ swallowed,
47
+ };
48
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codemaxxing",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "Open-source terminal coding agent. Connect any LLM. Max your code.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {