@ouro.bot/cli 0.1.0-alpha.57 → 0.1.0-alpha.58
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 +8 -0
- package/dist/heart/daemon/runtime-logging.js +38 -11
- package/dist/senses/cli-layout.js +87 -0
- package/dist/senses/cli.js +7 -8
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.58",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Normal `ouro` and `ouro-bot` CLI entrypoints now stay quiet by default in the terminal while still writing runtime NDJSON logs, and explicit logging overrides still work.",
|
|
8
|
+
"Interactive pasted input now clears every echoed row before re-rendering its bold summary, so multi-line instructions stay legible instead of colliding with prompt redraws and streaming output.",
|
|
9
|
+
"Wrapped CLI text now prefers whitespace breaks for ordinary words and only splits a word mid-line when that single word is wider than the terminal."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
4
12
|
{
|
|
5
13
|
"version": "0.1.0-alpha.57",
|
|
6
14
|
"changes": [
|
|
@@ -39,37 +39,64 @@ const os = __importStar(require("os"));
|
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
40
|
const nerves_1 = require("../../nerves");
|
|
41
41
|
const runtime_1 = require("../../nerves/runtime");
|
|
42
|
-
const
|
|
42
|
+
const LEGACY_SHARED_RUNTIME_LOGGING = {
|
|
43
43
|
level: "info",
|
|
44
44
|
sinks: ["terminal", "ndjson"],
|
|
45
45
|
};
|
|
46
|
-
function
|
|
47
|
-
|
|
46
|
+
function defaultLoggingForProcess(processName) {
|
|
47
|
+
if (processName === "ouro" || processName === "ouro-bot") {
|
|
48
|
+
return {
|
|
49
|
+
level: "info",
|
|
50
|
+
sinks: ["ndjson"],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (processName === "bluebubbles") {
|
|
54
|
+
return {
|
|
55
|
+
level: "warn",
|
|
56
|
+
sinks: ["terminal", "ndjson"],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return { ...LEGACY_SHARED_RUNTIME_LOGGING };
|
|
48
60
|
}
|
|
49
61
|
function isLogLevel(value) {
|
|
50
62
|
return value === "debug" || value === "info" || value === "warn" || value === "error";
|
|
51
63
|
}
|
|
64
|
+
function normalizeSinks(value, fallback) {
|
|
65
|
+
if (!Array.isArray(value)) {
|
|
66
|
+
return [...fallback];
|
|
67
|
+
}
|
|
68
|
+
const sinks = value.filter((entry) => entry === "terminal" || entry === "ndjson");
|
|
69
|
+
return sinks.length > 0 ? [...new Set(sinks)] : [...fallback];
|
|
70
|
+
}
|
|
71
|
+
function isLegacySharedDefaultConfig(candidate, normalizedLevel, normalizedSinks) {
|
|
72
|
+
return normalizedLevel === LEGACY_SHARED_RUNTIME_LOGGING.level
|
|
73
|
+
&& normalizedSinks.length === LEGACY_SHARED_RUNTIME_LOGGING.sinks.length
|
|
74
|
+
&& LEGACY_SHARED_RUNTIME_LOGGING.sinks.every((sink) => normalizedSinks.includes(sink))
|
|
75
|
+
&& Object.keys(candidate).every((key) => key === "level" || key === "sinks");
|
|
76
|
+
}
|
|
52
77
|
function resolveRuntimeLoggingConfig(configPath, processName) {
|
|
53
|
-
const
|
|
78
|
+
const processDefault = defaultLoggingForProcess(processName);
|
|
54
79
|
let parsed = null;
|
|
55
80
|
try {
|
|
56
81
|
const raw = fs.readFileSync(configPath, "utf-8");
|
|
57
82
|
parsed = JSON.parse(raw);
|
|
58
83
|
}
|
|
59
84
|
catch {
|
|
60
|
-
return { ...
|
|
85
|
+
return { ...processDefault };
|
|
61
86
|
}
|
|
62
87
|
if (!parsed || typeof parsed !== "object") {
|
|
63
|
-
return { ...
|
|
88
|
+
return { ...processDefault };
|
|
64
89
|
}
|
|
65
90
|
const candidate = parsed;
|
|
66
|
-
const level = isLogLevel(candidate.level) ? candidate.level :
|
|
67
|
-
const sinks =
|
|
68
|
-
|
|
69
|
-
|
|
91
|
+
const level = isLogLevel(candidate.level) ? candidate.level : processDefault.level;
|
|
92
|
+
const sinks = normalizeSinks(candidate.sinks, processDefault.sinks);
|
|
93
|
+
if ((processName === "ouro" || processName === "ouro-bot")
|
|
94
|
+
&& isLegacySharedDefaultConfig(candidate, level, sinks)) {
|
|
95
|
+
return { ...processDefault };
|
|
96
|
+
}
|
|
70
97
|
return {
|
|
71
98
|
level,
|
|
72
|
-
sinks
|
|
99
|
+
sinks,
|
|
73
100
|
};
|
|
74
101
|
}
|
|
75
102
|
function configureDaemonRuntimeLogger(processName, options = {}) {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapCliText = wrapCliText;
|
|
4
|
+
exports.formatEchoedInputSummary = formatEchoedInputSummary;
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
function splitLongWord(word, width) {
|
|
7
|
+
const chunks = [];
|
|
8
|
+
for (let index = 0; index < word.length; index += width) {
|
|
9
|
+
chunks.push(word.slice(index, index + width));
|
|
10
|
+
}
|
|
11
|
+
return chunks;
|
|
12
|
+
}
|
|
13
|
+
function wrapCliText(text, cols) {
|
|
14
|
+
const width = Math.max(cols, 1);
|
|
15
|
+
const wrapped = [];
|
|
16
|
+
for (const rawLine of text.split("\n")) {
|
|
17
|
+
if (rawLine.trim().length === 0) {
|
|
18
|
+
wrapped.push("");
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const words = rawLine.trim().split(/\s+/);
|
|
22
|
+
let current = "";
|
|
23
|
+
for (const word of words) {
|
|
24
|
+
if (!current) {
|
|
25
|
+
if (word.length <= width) {
|
|
26
|
+
current = word;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const chunks = splitLongWord(word, width);
|
|
30
|
+
wrapped.push(...chunks.slice(0, -1));
|
|
31
|
+
current = chunks[chunks.length - 1];
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const candidate = `${current} ${word}`;
|
|
35
|
+
if (candidate.length <= width) {
|
|
36
|
+
current = candidate;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
wrapped.push(current);
|
|
40
|
+
if (word.length <= width) {
|
|
41
|
+
current = word;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const chunks = splitLongWord(word, width);
|
|
45
|
+
wrapped.push(...chunks.slice(0, -1));
|
|
46
|
+
current = chunks[chunks.length - 1];
|
|
47
|
+
}
|
|
48
|
+
wrapped.push(current);
|
|
49
|
+
}
|
|
50
|
+
return wrapped;
|
|
51
|
+
}
|
|
52
|
+
function countEchoedInputRows(input, cols) {
|
|
53
|
+
const width = Math.max(cols, 1);
|
|
54
|
+
return input.split("\n").reduce((sum, line, index) => {
|
|
55
|
+
const promptWidth = index === 0 ? 2 : 0;
|
|
56
|
+
return sum + Math.max(1, Math.ceil((promptWidth + line.length) / width));
|
|
57
|
+
}, 0);
|
|
58
|
+
}
|
|
59
|
+
function formatEchoedInputSummary(input, cols) {
|
|
60
|
+
const inputLines = input.split("\n");
|
|
61
|
+
const summary = `> ${inputLines[0]}${inputLines.length > 1 ? ` (+${inputLines.length - 1} lines)` : ""}`;
|
|
62
|
+
const wrappedSummary = wrapCliText(summary, cols);
|
|
63
|
+
const echoRows = countEchoedInputRows(input, cols);
|
|
64
|
+
(0, runtime_1.emitNervesEvent)({
|
|
65
|
+
component: "senses",
|
|
66
|
+
event: "senses.cli_echo_summary_formatted",
|
|
67
|
+
message: "formatted echoed cli input summary",
|
|
68
|
+
meta: {
|
|
69
|
+
cols,
|
|
70
|
+
echo_rows: echoRows,
|
|
71
|
+
input_line_count: inputLines.length,
|
|
72
|
+
wrapped_line_count: wrappedSummary.length,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
let output = `\x1b[${echoRows}A`;
|
|
76
|
+
for (let i = 0; i < echoRows; i += 1) {
|
|
77
|
+
output += "\r\x1b[K";
|
|
78
|
+
if (i < echoRows - 1) {
|
|
79
|
+
output += "\x1b[1B";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (echoRows > 1) {
|
|
83
|
+
output += `\x1b[${echoRows - 1}A`;
|
|
84
|
+
}
|
|
85
|
+
output += `\x1b[1m${wrappedSummary.join("\n")}\x1b[0m\n\n`;
|
|
86
|
+
return output;
|
|
87
|
+
}
|
package/dist/senses/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.MarkdownStreamer = exports.InputController = exports.Spinner = void 0;
|
|
36
|
+
exports.MarkdownStreamer = exports.InputController = exports.Spinner = exports.wrapCliText = exports.formatEchoedInputSummary = void 0;
|
|
37
37
|
exports.formatPendingPrefix = formatPendingPrefix;
|
|
38
38
|
exports.getCliContinuityIngressTexts = getCliContinuityIngressTexts;
|
|
39
39
|
exports.handleSigint = handleSigint;
|
|
@@ -68,6 +68,10 @@ const session_lock_1 = require("./session-lock");
|
|
|
68
68
|
const update_hooks_1 = require("../heart/daemon/update-hooks");
|
|
69
69
|
const bundle_meta_1 = require("../heart/daemon/hooks/bundle-meta");
|
|
70
70
|
const bundle_manifest_1 = require("../mind/bundle-manifest");
|
|
71
|
+
const cli_layout_1 = require("./cli-layout");
|
|
72
|
+
var cli_layout_2 = require("./cli-layout");
|
|
73
|
+
Object.defineProperty(exports, "formatEchoedInputSummary", { enumerable: true, get: function () { return cli_layout_2.formatEchoedInputSummary; } });
|
|
74
|
+
Object.defineProperty(exports, "wrapCliText", { enumerable: true, get: function () { return cli_layout_2.wrapCliText; } });
|
|
71
75
|
/**
|
|
72
76
|
* Format pending messages as content-prefix strings for injection into
|
|
73
77
|
* the next user message. Self-messages (from === agentName) become
|
|
@@ -618,14 +622,9 @@ async function runCliSession(options) {
|
|
|
618
622
|
}
|
|
619
623
|
}
|
|
620
624
|
}
|
|
621
|
-
// Re-style the echoed input lines
|
|
625
|
+
// Re-style the echoed input lines without leaving wrapped paste remnants behind.
|
|
622
626
|
const cols = process.stdout.columns || 80;
|
|
623
|
-
|
|
624
|
-
let echoRows = 0;
|
|
625
|
-
for (const line of inputLines) {
|
|
626
|
-
echoRows += Math.ceil((2 + line.length) / cols);
|
|
627
|
-
}
|
|
628
|
-
process.stdout.write(`\x1b[${echoRows}A\x1b[K` + `\x1b[1m> ${inputLines[0]}${inputLines.length > 1 ? ` (+${inputLines.length - 1} lines)` : ""}\x1b[0m\n\n`);
|
|
627
|
+
process.stdout.write((0, cli_layout_1.formatEchoedInputSummary)(input, cols));
|
|
629
628
|
addHistory(history, input);
|
|
630
629
|
currentAbort = new AbortController();
|
|
631
630
|
ctrl.suppress(() => currentAbort.abort());
|