@ouro.bot/cli 0.1.0-alpha.175 → 0.1.0-alpha.177
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/changelog.json +7 -1
- package/dist/heart/active-work.js +2 -2
- package/dist/heart/core.js +1 -1
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/prompt.js +119 -60
- package/dist/mind/scrutiny.js +173 -0
- package/dist/nerves/coverage/audit.js +1 -1
- package/dist/repertoire/ado-semantic.js +5 -5
- package/dist/repertoire/coding/tools.js +35 -5
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/tools-base.js +145 -16
- package/dist/repertoire/tools.js +37 -0
- package/dist/senses/cli/adapter.js +307 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +68 -0
- package/dist/senses/cli/message-list.js +84 -0
- package/dist/senses/cli/ouro-tui.js +296 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +64 -0
- package/dist/senses/cli/streaming-markdown.js +486 -0
- package/dist/senses/cli/tool-display.js +77 -0
- package/dist/senses/cli/tool-render.js +89 -0
- package/dist/senses/cli/tui-store.js +198 -0
- package/dist/senses/cli/virtual-list.js +68 -0
- package/dist/senses/cli.js +231 -157
- package/dist/senses/pipeline.js +53 -10
- package/package.json +3 -1
- package/dist/outlook-ui/assets/index-DN6vVYPm.css +0 -1
- package/dist/outlook-ui/assets/index-M1l1tDTX.js +0 -61
- package/dist/outlook-ui/index.html +0 -15
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TuiStore = void 0;
|
|
4
|
+
exports.createTuiCallbacks = createTuiCallbacks;
|
|
5
|
+
/**
|
|
6
|
+
* TUI Store — mutable external state for the OuroTui component.
|
|
7
|
+
*
|
|
8
|
+
* Tracks two buckets:
|
|
9
|
+
* 1. completedMessages — fed to Ink's <Static>, rendered once
|
|
10
|
+
* 2. live — current turn state, re-renders on change
|
|
11
|
+
*
|
|
12
|
+
* ZERO business logic. Just state + notify.
|
|
13
|
+
*/
|
|
14
|
+
const phrases_1 = require("../../mind/phrases");
|
|
15
|
+
const format_1 = require("../../mind/format");
|
|
16
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
17
|
+
class TuiStore {
|
|
18
|
+
_completed = [];
|
|
19
|
+
_live = {
|
|
20
|
+
streamingText: "",
|
|
21
|
+
loading: false,
|
|
22
|
+
spinnerPhrase: "",
|
|
23
|
+
spinnerPhrasePool: [],
|
|
24
|
+
activeTool: null,
|
|
25
|
+
errorMessage: null,
|
|
26
|
+
kickMessage: null,
|
|
27
|
+
inputSuppressed: false,
|
|
28
|
+
};
|
|
29
|
+
_spinnerStart = 0;
|
|
30
|
+
_hadTool = false;
|
|
31
|
+
_turnId = 0;
|
|
32
|
+
_listeners = new Set();
|
|
33
|
+
_headerShown = false;
|
|
34
|
+
_inputHistory = [];
|
|
35
|
+
get completedMessages() { return this._completed; }
|
|
36
|
+
get live() { return this._live; }
|
|
37
|
+
get headerShown() { return this._headerShown; }
|
|
38
|
+
get inputHistory() { return this._inputHistory; }
|
|
39
|
+
/** Elapsed seconds since spinner started — computed on demand, not stored */
|
|
40
|
+
getElapsed() {
|
|
41
|
+
if (this._live.loading && this._spinnerStart > 0) {
|
|
42
|
+
return Math.floor((Date.now() - this._spinnerStart) / 1000);
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
subscribe(fn) {
|
|
47
|
+
this._listeners.add(fn);
|
|
48
|
+
return () => { this._listeners.delete(fn); };
|
|
49
|
+
}
|
|
50
|
+
notify() {
|
|
51
|
+
for (const fn of this._listeners)
|
|
52
|
+
fn();
|
|
53
|
+
}
|
|
54
|
+
// ─── Called by business logic (via callbacks) ───
|
|
55
|
+
modelStart() {
|
|
56
|
+
const phrases = (0, phrases_1.getPhrases)();
|
|
57
|
+
const pool = this._hadTool ? phrases.followup : phrases.thinking;
|
|
58
|
+
this._live = {
|
|
59
|
+
...this._live,
|
|
60
|
+
loading: true,
|
|
61
|
+
spinnerPhrase: (0, phrases_1.pickPhrase)(pool),
|
|
62
|
+
spinnerPhrasePool: pool,
|
|
63
|
+
streamingText: "",
|
|
64
|
+
activeTool: null,
|
|
65
|
+
errorMessage: null,
|
|
66
|
+
kickMessage: null,
|
|
67
|
+
};
|
|
68
|
+
this._spinnerStart = Date.now();
|
|
69
|
+
this._turnId++;
|
|
70
|
+
this.notify();
|
|
71
|
+
}
|
|
72
|
+
appendText(text) {
|
|
73
|
+
this._live = {
|
|
74
|
+
...this._live,
|
|
75
|
+
loading: false,
|
|
76
|
+
streamingText: this._live.streamingText + text,
|
|
77
|
+
};
|
|
78
|
+
this.notify();
|
|
79
|
+
}
|
|
80
|
+
clearText() {
|
|
81
|
+
this._live = { ...this._live, streamingText: "" };
|
|
82
|
+
this.notify();
|
|
83
|
+
}
|
|
84
|
+
toolStart(name, args) {
|
|
85
|
+
this._hadTool = true;
|
|
86
|
+
// Before showing tool in-progress, commit any buffered streaming text
|
|
87
|
+
// so it doesn't disappear when the live area switches to tool display
|
|
88
|
+
if (this._live.streamingText.trim()) {
|
|
89
|
+
this._completed = [...this._completed, {
|
|
90
|
+
id: `asst-${this._turnId}-${Date.now()}`,
|
|
91
|
+
role: "assistant",
|
|
92
|
+
content: this._live.streamingText.trim(),
|
|
93
|
+
}];
|
|
94
|
+
}
|
|
95
|
+
this._live = {
|
|
96
|
+
...this._live,
|
|
97
|
+
loading: true,
|
|
98
|
+
streamingText: "",
|
|
99
|
+
activeTool: { name, args },
|
|
100
|
+
spinnerPhrase: (0, phrases_1.pickPhrase)((0, phrases_1.getPhrases)().tool),
|
|
101
|
+
spinnerPhrasePool: (0, phrases_1.getPhrases)().tool,
|
|
102
|
+
};
|
|
103
|
+
this._spinnerStart = Date.now();
|
|
104
|
+
this.notify();
|
|
105
|
+
}
|
|
106
|
+
toolEnd(name, argSummary, success) {
|
|
107
|
+
// Move tool result to completed messages (so it renders via Static)
|
|
108
|
+
this._completed = [...this._completed, {
|
|
109
|
+
id: `tool-${this._turnId}-${Date.now()}`,
|
|
110
|
+
role: "tool",
|
|
111
|
+
content: "",
|
|
112
|
+
toolCalls: [{ name, argSummary, success }],
|
|
113
|
+
}];
|
|
114
|
+
this._live = {
|
|
115
|
+
...this._live,
|
|
116
|
+
loading: false,
|
|
117
|
+
activeTool: null,
|
|
118
|
+
};
|
|
119
|
+
this.notify();
|
|
120
|
+
}
|
|
121
|
+
setError(msg) {
|
|
122
|
+
this._live = { ...this._live, loading: false, errorMessage: msg };
|
|
123
|
+
this.notify();
|
|
124
|
+
}
|
|
125
|
+
setKick() {
|
|
126
|
+
this._live = { ...this._live, loading: false, kickMessage: (0, format_1.formatKick)() };
|
|
127
|
+
this.notify();
|
|
128
|
+
}
|
|
129
|
+
suppressInput() {
|
|
130
|
+
this._live = { ...this._live, inputSuppressed: true };
|
|
131
|
+
this.notify();
|
|
132
|
+
}
|
|
133
|
+
restoreInput() {
|
|
134
|
+
this._live = { ...this._live, inputSuppressed: false };
|
|
135
|
+
this.notify();
|
|
136
|
+
}
|
|
137
|
+
/** Commit current streaming text as a completed assistant message */
|
|
138
|
+
commitAssistantMessage() {
|
|
139
|
+
if (this._live.streamingText.trim()) {
|
|
140
|
+
this._completed = [...this._completed, {
|
|
141
|
+
id: `asst-${this._turnId}-${Date.now()}`,
|
|
142
|
+
role: "assistant",
|
|
143
|
+
content: this._live.streamingText.trim(),
|
|
144
|
+
}];
|
|
145
|
+
}
|
|
146
|
+
// Clear streaming text immediately — prevents double display
|
|
147
|
+
this._live = {
|
|
148
|
+
...this._live,
|
|
149
|
+
loading: false,
|
|
150
|
+
streamingText: "",
|
|
151
|
+
activeTool: null,
|
|
152
|
+
errorMessage: null,
|
|
153
|
+
kickMessage: null,
|
|
154
|
+
};
|
|
155
|
+
this.notify();
|
|
156
|
+
}
|
|
157
|
+
/** Add a user message to completed (for display) AND input history */
|
|
158
|
+
addUserMessage(text) {
|
|
159
|
+
if (this._completed.length === 0) {
|
|
160
|
+
this._headerShown = false;
|
|
161
|
+
}
|
|
162
|
+
this._completed = [...this._completed, {
|
|
163
|
+
id: `user-${Date.now()}`,
|
|
164
|
+
role: "user",
|
|
165
|
+
content: text,
|
|
166
|
+
}];
|
|
167
|
+
this._inputHistory.push(text);
|
|
168
|
+
this.notify();
|
|
169
|
+
}
|
|
170
|
+
/** Seed input history from previous session messages (display only, no rendering) */
|
|
171
|
+
seedHistory(texts) {
|
|
172
|
+
this._inputHistory.push(...texts);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.TuiStore = TuiStore;
|
|
176
|
+
// ─── Callbacks factory ──────────────────────────────────────────────
|
|
177
|
+
function createTuiCallbacks(store) {
|
|
178
|
+
(0, runtime_1.emitNervesEvent)({
|
|
179
|
+
component: "senses",
|
|
180
|
+
event: "senses.tui_callbacks_created",
|
|
181
|
+
message: "TUI callbacks created",
|
|
182
|
+
meta: {},
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
onModelStart: () => { store.modelStart(); },
|
|
186
|
+
onModelStreamStart: () => { },
|
|
187
|
+
onClearText: () => { store.clearText(); },
|
|
188
|
+
onTextChunk: (text) => { store.appendText(text); },
|
|
189
|
+
onReasoningChunk: () => { },
|
|
190
|
+
onToolStart: (name, args) => { store.toolStart(name, args); },
|
|
191
|
+
onToolEnd: (name, argSummary, success) => { store.toolEnd(name, argSummary, success); },
|
|
192
|
+
onError: (error, severity) => {
|
|
193
|
+
store.setError(severity === "terminal" ? (0, format_1.formatError)(error) : error.message);
|
|
194
|
+
},
|
|
195
|
+
onKick: () => { store.setKick(); },
|
|
196
|
+
flushMarkdown: () => { store.commitAssistantMessage(); },
|
|
197
|
+
};
|
|
198
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.VirtualList = VirtualList;
|
|
37
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
|
+
const react_1 = __importStar(require("react"));
|
|
39
|
+
const ink_1 = require("ink");
|
|
40
|
+
function VirtualList({ items, viewportHeight, scrollOffset, renderItem, }) {
|
|
41
|
+
const { startIndex, visibleItems } = (0, react_1.useMemo)(() => {
|
|
42
|
+
if (items.length === 0) {
|
|
43
|
+
return { startIndex: 0, visibleItems: [] };
|
|
44
|
+
}
|
|
45
|
+
// Determine the start index for the visible window
|
|
46
|
+
let start;
|
|
47
|
+
if (scrollOffset !== undefined) {
|
|
48
|
+
// Scroll-locked: show items starting at the given offset
|
|
49
|
+
start = Math.max(0, Math.min(scrollOffset, items.length - 1));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Auto-scroll: pin to bottom, show last viewportHeight items
|
|
53
|
+
start = Math.max(0, items.length - viewportHeight);
|
|
54
|
+
}
|
|
55
|
+
const end = Math.min(start + viewportHeight, items.length);
|
|
56
|
+
return {
|
|
57
|
+
startIndex: start,
|
|
58
|
+
visibleItems: items.slice(start, end),
|
|
59
|
+
};
|
|
60
|
+
}, [items, viewportHeight, scrollOffset]);
|
|
61
|
+
if (visibleItems.length === 0) {
|
|
62
|
+
return (0, jsx_runtime_1.jsx)(ink_1.Box, { children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: "" }) });
|
|
63
|
+
}
|
|
64
|
+
return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", children: visibleItems.map((item, i) => {
|
|
65
|
+
const globalIndex = startIndex + i;
|
|
66
|
+
return ((0, jsx_runtime_1.jsx)(ink_1.Box, { children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: renderItem(item, globalIndex) }) }, globalIndex));
|
|
67
|
+
}) }));
|
|
68
|
+
}
|