@ordewell/cli 0.4.9 → 0.4.10
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/main.js +48 -32
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2729,9 +2729,21 @@ var import_core13 = require("@ordewell/core");
|
|
|
2729
2729
|
|
|
2730
2730
|
// src/tui/ansi.ts
|
|
2731
2731
|
var import_string_width = __toESM(require("string-width"));
|
|
2732
|
-
var
|
|
2732
|
+
var ESCAPE = /\x1b(?:\][\s\S]*?(?:\x07|\x1b\\|$)|[P^_][\s\S]*?(?:\x1b\\|$)|\[[0-?]*[ -/]*[@-~]?|[ -/]*[0-~]?)/g;
|
|
2733
|
+
var ESCAPE_SPLIT = new RegExp(`(${ESCAPE.source})`);
|
|
2734
|
+
var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f]/g;
|
|
2735
|
+
var CONTROL_IN_ROW = /[\x00-\x1f\x7f-\x9f]/g;
|
|
2736
|
+
var HAS_CONTROL = /[\x00-\x1f\x7f-\x9f]/;
|
|
2737
|
+
var PAINT_ESCAPE = /^\x1b\[[0-9;]*[mGK]$/;
|
|
2733
2738
|
function stripAnsi(text) {
|
|
2734
|
-
return text.replace(
|
|
2739
|
+
return text.replace(ESCAPE, "");
|
|
2740
|
+
}
|
|
2741
|
+
function sanitize(text) {
|
|
2742
|
+
return text.replace(ESCAPE, "").replace(/\r\n?/g, "\n").replace(/\t/g, " ").replace(CONTROL, "");
|
|
2743
|
+
}
|
|
2744
|
+
function paintOnly(line) {
|
|
2745
|
+
if (!HAS_CONTROL.test(line)) return line;
|
|
2746
|
+
return line.split(ESCAPE_SPLIT).map((piece) => piece.startsWith("\x1B") ? PAINT_ESCAPE.test(piece) ? piece : "" : piece.replace(CONTROL_IN_ROW, "")).join("");
|
|
2735
2747
|
}
|
|
2736
2748
|
function width(text) {
|
|
2737
2749
|
return (0, import_string_width.default)(stripAnsi(text));
|
|
@@ -2749,9 +2761,6 @@ function truncate(text, max) {
|
|
|
2749
2761
|
}
|
|
2750
2762
|
return out + "\u2026";
|
|
2751
2763
|
}
|
|
2752
|
-
function stripTabs(text) {
|
|
2753
|
-
return text.replace(/\t/g, " ");
|
|
2754
|
-
}
|
|
2755
2764
|
function pad(text, target) {
|
|
2756
2765
|
const current = width(text);
|
|
2757
2766
|
if (current > target) return truncate(text, target);
|
|
@@ -3676,13 +3685,16 @@ function cells(line) {
|
|
|
3676
3685
|
}
|
|
3677
3686
|
var INVERSE_ON = "\x1B[7m";
|
|
3678
3687
|
var INVERSE_OFF = "\x1B[27m";
|
|
3679
|
-
var
|
|
3688
|
+
var ESCAPE_SPLIT2 = /(\x1b\[[0-9;]*[A-Za-z])/;
|
|
3689
|
+
var CURSOR_COLUMN = /^\x1b\[([0-9]*)G$/;
|
|
3680
3690
|
function invertCells(line, from, to) {
|
|
3681
3691
|
let out = "";
|
|
3682
3692
|
let col = 1;
|
|
3683
3693
|
let inside = false;
|
|
3684
|
-
for (const piece of line.split(
|
|
3685
|
-
if (
|
|
3694
|
+
for (const piece of line.split(ESCAPE_SPLIT2)) {
|
|
3695
|
+
if (ESCAPE_SPLIT2.test(piece)) {
|
|
3696
|
+
const jump = CURSOR_COLUMN.exec(piece);
|
|
3697
|
+
if (jump) col = Number(jump[1] || "1");
|
|
3686
3698
|
out += piece + (inside ? INVERSE_ON : "");
|
|
3687
3699
|
continue;
|
|
3688
3700
|
}
|
|
@@ -3782,15 +3794,18 @@ function suggest(state, room) {
|
|
|
3782
3794
|
function renderFooter(state, cols) {
|
|
3783
3795
|
return packHints(footerHints(state), cols).map((line) => truncate(style.grey(line), cols));
|
|
3784
3796
|
}
|
|
3797
|
+
var ERASE_TO_END = "\x1B[K";
|
|
3798
|
+
var atColumn = (col) => `\x1B[${col}G`;
|
|
3785
3799
|
function renderBody(state, rows, cols) {
|
|
3786
3800
|
const planCols = planPaneWidth(state);
|
|
3787
3801
|
if (planCols === 0) return renderChat(state, rows, cols);
|
|
3788
3802
|
const chatCols = chatPaneWidth(state);
|
|
3789
3803
|
const chat = renderChat(state, rows, chatCols);
|
|
3790
3804
|
const plan = renderPlan(state, rows, planCols);
|
|
3805
|
+
const divider = `${ERASE_TO_END}${atColumn(chatCols + 1)}${style.grey("\u2502")}`;
|
|
3791
3806
|
return Array.from(
|
|
3792
3807
|
{ length: rows },
|
|
3793
|
-
(_, i) => `${pad(chat[i] ?? "", chatCols)}${
|
|
3808
|
+
(_, i) => `${pad(chat[i] ?? "", chatCols)}${divider}${pad(plan[i] ?? "", planCols)}`
|
|
3794
3809
|
);
|
|
3795
3810
|
}
|
|
3796
3811
|
function renderChat(state, rows, cols) {
|
|
@@ -3901,13 +3916,13 @@ function step(state, effects = []) {
|
|
|
3901
3916
|
return { state, effects };
|
|
3902
3917
|
}
|
|
3903
3918
|
function say(state, role, content, research) {
|
|
3904
|
-
const message = { role, content:
|
|
3919
|
+
const message = { role, content: sanitize(content), timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...research ? { research } : {} };
|
|
3905
3920
|
return { ...state, messages: [...state.messages, message], scroll: 0 };
|
|
3906
3921
|
}
|
|
3907
3922
|
function restoredMessages(history) {
|
|
3908
3923
|
return history.map((entry) => ({
|
|
3909
3924
|
role: entry.kind === "plan_generated" ? "system" : entry.kind === "system" ? "system" : entry.role,
|
|
3910
|
-
content:
|
|
3925
|
+
content: sanitize(entry.kind === "plan_generated" ? "Plan generated." : entry.content),
|
|
3911
3926
|
timestamp: entry.timestamp
|
|
3912
3927
|
}));
|
|
3913
3928
|
}
|
|
@@ -3921,13 +3936,13 @@ function researchLabel(messages, summary) {
|
|
|
3921
3936
|
return others > 0 ? `${summary} (+${others} more)` : summary;
|
|
3922
3937
|
}
|
|
3923
3938
|
function settleResearchStep(messages, action) {
|
|
3924
|
-
const summary =
|
|
3939
|
+
const summary = sanitize(action.summary);
|
|
3925
3940
|
const index = findLastIndex(messages, (m) => isPendingResearch(m) && (action.toolCallId ? m.research?.toolCallId === action.toolCallId : m.content === summary));
|
|
3926
3941
|
if (index < 0) return messages;
|
|
3927
3942
|
const next = [...messages];
|
|
3928
3943
|
next[index] = {
|
|
3929
3944
|
...next[index],
|
|
3930
|
-
research: { ...next[index].research, outcome: action.outcome, result:
|
|
3945
|
+
research: { ...next[index].research, outcome: action.outcome, result: sanitize(action.result) }
|
|
3931
3946
|
};
|
|
3932
3947
|
return next;
|
|
3933
3948
|
}
|
|
@@ -3985,13 +4000,13 @@ function reduce(state, action) {
|
|
|
3985
4000
|
case "plannerMessage": {
|
|
3986
4001
|
if (stale(state, action.sessionId)) return step(state);
|
|
3987
4002
|
const settled = { ...state, status: "idle", busyLabel: "", thinkingLine: "" };
|
|
3988
|
-
const content =
|
|
4003
|
+
const content = sanitize(action.content);
|
|
3989
4004
|
if (alreadySpoken(state.messages, content)) return step(settled);
|
|
3990
4005
|
return step(say(settled, "assistant", content));
|
|
3991
4006
|
}
|
|
3992
4007
|
case "researchStep": {
|
|
3993
4008
|
if (stale(state, action.sessionId)) return step(state);
|
|
3994
|
-
const summary =
|
|
4009
|
+
const summary = sanitize(action.summary);
|
|
3995
4010
|
const spoken = say(state, "research", summary, { toolCallId: action.toolCallId });
|
|
3996
4011
|
const status = state.status === "planning" ? "researching" : state.status;
|
|
3997
4012
|
return step({ ...spoken, status, busyLabel: researchLabel(spoken.messages, summary) });
|
|
@@ -4010,7 +4025,7 @@ function reduce(state, action) {
|
|
|
4010
4025
|
}
|
|
4011
4026
|
case "plannerThinking": {
|
|
4012
4027
|
if (stale(state, action.sessionId)) return step(state);
|
|
4013
|
-
return step({ ...state, thinkingLine: (state.thinkingLine + action.text).slice(-THINKING_TAIL) });
|
|
4028
|
+
return step({ ...state, thinkingLine: (state.thinkingLine + sanitize(action.text)).slice(-THINKING_TAIL) });
|
|
4014
4029
|
}
|
|
4015
4030
|
case "taskStatus": {
|
|
4016
4031
|
if (stale(state, action.sessionId) || !state.tasks.some((t) => t.id === action.taskId)) return step(state);
|
|
@@ -4099,6 +4114,8 @@ function reduce(state, action) {
|
|
|
4099
4114
|
return step({ ...state, spinnerFrame: (state.spinnerFrame + 1) % 10 });
|
|
4100
4115
|
}
|
|
4101
4116
|
}
|
|
4117
|
+
var planText = (value, fallback = "") => sanitize(String(value ?? fallback));
|
|
4118
|
+
var planLabel = (value, fallback = "") => planText(value, fallback).replace(/\n+/g, " ");
|
|
4102
4119
|
function normalizeTasks(plan) {
|
|
4103
4120
|
const source = plan;
|
|
4104
4121
|
const byId = /* @__PURE__ */ new Map();
|
|
@@ -4111,19 +4128,19 @@ function normalizeTasks(plan) {
|
|
|
4111
4128
|
return raw.map((t, i) => ({
|
|
4112
4129
|
id: String(t.id ?? `task-${i + 1}`),
|
|
4113
4130
|
order: typeof t.order === "number" ? t.order : i + 1,
|
|
4114
|
-
title:
|
|
4115
|
-
description:
|
|
4116
|
-
prompt: typeof t.prompt === "string" ? t.prompt : void 0,
|
|
4131
|
+
title: planLabel(t.title, "Untitled task"),
|
|
4132
|
+
description: planText(t.description ?? t.title),
|
|
4133
|
+
prompt: typeof t.prompt === "string" ? sanitize(t.prompt) : void 0,
|
|
4117
4134
|
type: t.type === "user" ? "user" : "ai",
|
|
4118
|
-
status:
|
|
4119
|
-
dependencies: Array.isArray(t.dependencies) ? t.dependencies.map(
|
|
4120
|
-
assignedRunner: typeof t.assignedRunner === "string" ? t.assignedRunner : void 0,
|
|
4121
|
-
taskMode: typeof t.taskMode === "string" ? t.taskMode : void 0,
|
|
4135
|
+
status: planLabel(t.status, "pending"),
|
|
4136
|
+
dependencies: Array.isArray(t.dependencies) ? t.dependencies.map((id) => planLabel(id)) : [],
|
|
4137
|
+
assignedRunner: typeof t.assignedRunner === "string" ? planLabel(t.assignedRunner) : void 0,
|
|
4138
|
+
taskMode: typeof t.taskMode === "string" ? planLabel(t.taskMode) : void 0,
|
|
4122
4139
|
assignedModel: t.assignedModel && typeof t.assignedModel === "object" ? {
|
|
4123
|
-
modelId:
|
|
4124
|
-
modelLabel:
|
|
4125
|
-
thinkingEffort: typeof t.assignedModel.thinkingEffort === "string" ? t.assignedModel.thinkingEffort : typeof t.thinkingEffort === "string" ? t.thinkingEffort : void 0,
|
|
4126
|
-
availableVariants: Array.isArray(t.assignedModel.availableVariants) ? t.assignedModel.availableVariants.map(
|
|
4140
|
+
modelId: planLabel(t.assignedModel.modelId),
|
|
4141
|
+
modelLabel: planLabel(t.assignedModel.modelLabel ?? t.assignedModel.modelId),
|
|
4142
|
+
thinkingEffort: typeof t.assignedModel.thinkingEffort === "string" ? planLabel(t.assignedModel.thinkingEffort) : typeof t.thinkingEffort === "string" ? planLabel(t.thinkingEffort) : void 0,
|
|
4143
|
+
availableVariants: Array.isArray(t.assignedModel.availableVariants) ? t.assignedModel.availableVariants.map((variant) => planLabel(variant)) : void 0
|
|
4127
4144
|
} : void 0
|
|
4128
4145
|
}));
|
|
4129
4146
|
}
|
|
@@ -5745,7 +5762,7 @@ async function loadSettings(deps) {
|
|
|
5745
5762
|
}
|
|
5746
5763
|
|
|
5747
5764
|
// src/tui/keys.ts
|
|
5748
|
-
var
|
|
5765
|
+
var CONTROL2 = {
|
|
5749
5766
|
"\r": "enter",
|
|
5750
5767
|
"\n": "enter",
|
|
5751
5768
|
" ": "tab",
|
|
@@ -5850,7 +5867,7 @@ function decodeMouse(seq) {
|
|
|
5850
5867
|
function decodeKey(seq) {
|
|
5851
5868
|
const escaped = ESCAPES[seq];
|
|
5852
5869
|
if (escaped) return { name: escaped };
|
|
5853
|
-
const control =
|
|
5870
|
+
const control = CONTROL2[seq];
|
|
5854
5871
|
if (control) return { name: control };
|
|
5855
5872
|
if (seq.startsWith("\x1B[")) {
|
|
5856
5873
|
const mouse = decodeMouse(seq);
|
|
@@ -5862,8 +5879,7 @@ function decodeKey(seq) {
|
|
|
5862
5879
|
var PASTE_START = "\x1B[200~";
|
|
5863
5880
|
var PASTE_END = "\x1B[201~";
|
|
5864
5881
|
function pasteKey(raw) {
|
|
5865
|
-
|
|
5866
|
-
return { name: "paste", text };
|
|
5882
|
+
return { name: "paste", text: sanitize(raw) };
|
|
5867
5883
|
}
|
|
5868
5884
|
function createKeyDecoder() {
|
|
5869
5885
|
let paste = null;
|
|
@@ -5997,7 +6013,7 @@ function openTerminal(options) {
|
|
|
5997
6013
|
draw(frame2) {
|
|
5998
6014
|
if (closed) return;
|
|
5999
6015
|
const { cols } = size();
|
|
6000
|
-
const rows = frame2.map((line, i) => `\x1B[${i + 1};1H${clampToCols(line, cols)}\x1B[K`).join("");
|
|
6016
|
+
const rows = frame2.map((line, i) => `\x1B[${i + 1};1H${clampToCols(paintOnly(line), cols)}\x1B[K`).join("");
|
|
6001
6017
|
output.write(AUTOWRAP_OFF + rows + AUTOWRAP_ON);
|
|
6002
6018
|
},
|
|
6003
6019
|
setMouse(enabled) {
|
package/package.json
CHANGED