@ouro.bot/cli 0.1.0-alpha.94 → 0.1.0-alpha.95
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 -0
- package/dist/senses/cli.js +48 -12
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
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.95",
|
|
6
|
+
"changes": [
|
|
7
|
+
"CLI chats now surface coding-session feedback back into the live `ouro chat` thread, so hidden child work no longer finishes silently while the operator sees an idle prompt.",
|
|
8
|
+
"Those async coding updates are also persisted into the CLI session history, which keeps the visible return loop truthful across follow-up turns instead of losing the fact that work already came back."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
4
11
|
{
|
|
5
12
|
"version": "0.1.0-alpha.94",
|
|
6
13
|
"changes": [
|
package/dist/senses/cli.js
CHANGED
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.MarkdownStreamer = exports.InputController = exports.Spinner = exports.StreamingWordWrapper = exports.wrapCliText = exports.formatEchoedInputSummary = void 0;
|
|
37
37
|
exports.formatPendingPrefix = formatPendingPrefix;
|
|
38
38
|
exports.getCliContinuityIngressTexts = getCliContinuityIngressTexts;
|
|
39
|
+
exports.writeCliAsyncAssistantMessage = writeCliAsyncAssistantMessage;
|
|
39
40
|
exports.pauseActiveSpinner = pauseActiveSpinner;
|
|
40
41
|
exports.resumeActiveSpinner = resumeActiveSpinner;
|
|
41
42
|
exports.setActiveSpinner = setActiveSpinner;
|
|
@@ -94,6 +95,21 @@ function getCliContinuityIngressTexts(input) {
|
|
|
94
95
|
const trimmed = input.trim();
|
|
95
96
|
return trimmed ? [trimmed] : [];
|
|
96
97
|
}
|
|
98
|
+
const CLI_PROMPT = "\x1b[36m> \x1b[0m";
|
|
99
|
+
function writeCliAsyncAssistantMessage(rl, message, stdout = process.stdout) {
|
|
100
|
+
const rlInt = rl;
|
|
101
|
+
const currentLine = rlInt.line ?? "";
|
|
102
|
+
const currentCursor = rlInt.cursor ?? currentLine.length;
|
|
103
|
+
stdout.write("\r\x1b[K");
|
|
104
|
+
stdout.write(`${renderMarkdown(message)}\n`);
|
|
105
|
+
stdout.write(CLI_PROMPT);
|
|
106
|
+
if (!currentLine)
|
|
107
|
+
return;
|
|
108
|
+
stdout.write(currentLine);
|
|
109
|
+
if (currentCursor < currentLine.length) {
|
|
110
|
+
readline.cursorTo(process.stdout, 2 + currentCursor);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
97
113
|
// Module-level active spinner for log coordination.
|
|
98
114
|
// The terminal log sink calls these to avoid interleaving with spinner output.
|
|
99
115
|
let _activeSpinner = null;
|
|
@@ -515,6 +531,22 @@ async function runCliSession(options) {
|
|
|
515
531
|
console.log(`\n${bannerText}\n`);
|
|
516
532
|
}
|
|
517
533
|
const cliCallbacks = createCliCallbacks();
|
|
534
|
+
const effectiveToolContext = {
|
|
535
|
+
signin: options.toolContext?.signin ?? (async () => undefined),
|
|
536
|
+
...options.toolContext,
|
|
537
|
+
codingFeedback: {
|
|
538
|
+
send: async (message) => {
|
|
539
|
+
const assistantMessage = {
|
|
540
|
+
role: "assistant",
|
|
541
|
+
content: message,
|
|
542
|
+
};
|
|
543
|
+
messages.push(assistantMessage);
|
|
544
|
+
await options.onAsyncAssistantMessage?.(messages, assistantMessage);
|
|
545
|
+
writeCliAsyncAssistantMessage(rl, message);
|
|
546
|
+
await options.toolContext?.codingFeedback?.send(message);
|
|
547
|
+
},
|
|
548
|
+
},
|
|
549
|
+
};
|
|
518
550
|
// exitOnToolCall machinery: wrap execTool to detect target tool
|
|
519
551
|
let exitToolResult;
|
|
520
552
|
let exitToolFired = false;
|
|
@@ -542,14 +574,14 @@ async function runCliSession(options) {
|
|
|
542
574
|
if (result === "clear") {
|
|
543
575
|
rlInt.line = "";
|
|
544
576
|
rlInt.cursor = 0;
|
|
545
|
-
process.stdout.write(
|
|
577
|
+
process.stdout.write(`\r\x1b[K${CLI_PROMPT}`);
|
|
546
578
|
}
|
|
547
579
|
else if (result === "warn") {
|
|
548
580
|
rlInt.line = "";
|
|
549
581
|
rlInt.cursor = 0;
|
|
550
582
|
process.stdout.write("\r\x1b[K");
|
|
551
583
|
process.stderr.write("press Ctrl-C again to exit\n");
|
|
552
|
-
process.stdout.write(
|
|
584
|
+
process.stdout.write(CLI_PROMPT);
|
|
553
585
|
}
|
|
554
586
|
else {
|
|
555
587
|
rl.close();
|
|
@@ -576,7 +608,7 @@ async function runCliSession(options) {
|
|
|
576
608
|
traceId,
|
|
577
609
|
tools: options.tools,
|
|
578
610
|
execTool: wrappedExecTool,
|
|
579
|
-
toolContext:
|
|
611
|
+
toolContext: effectiveToolContext,
|
|
580
612
|
});
|
|
581
613
|
}
|
|
582
614
|
catch (err) {
|
|
@@ -605,14 +637,14 @@ async function runCliSession(options) {
|
|
|
605
637
|
}
|
|
606
638
|
}
|
|
607
639
|
if (!exitToolFired) {
|
|
608
|
-
process.stdout.write(
|
|
640
|
+
process.stdout.write(CLI_PROMPT);
|
|
609
641
|
}
|
|
610
642
|
try {
|
|
611
643
|
for await (const input of debouncedLines(rl)) {
|
|
612
644
|
if (closed)
|
|
613
645
|
break;
|
|
614
646
|
if (!input.trim()) {
|
|
615
|
-
process.stdout.write(
|
|
647
|
+
process.stdout.write(CLI_PROMPT);
|
|
616
648
|
continue;
|
|
617
649
|
}
|
|
618
650
|
// Optional input gate (e.g. trust gate in main)
|
|
@@ -624,7 +656,7 @@ async function runCliSession(options) {
|
|
|
624
656
|
}
|
|
625
657
|
if (closed)
|
|
626
658
|
break;
|
|
627
|
-
process.stdout.write(
|
|
659
|
+
process.stdout.write(CLI_PROMPT);
|
|
628
660
|
continue;
|
|
629
661
|
}
|
|
630
662
|
}
|
|
@@ -642,13 +674,13 @@ async function runCliSession(options) {
|
|
|
642
674
|
await options.onNewSession?.();
|
|
643
675
|
// eslint-disable-next-line no-console -- terminal UX: session cleared
|
|
644
676
|
console.log("session cleared");
|
|
645
|
-
process.stdout.write(
|
|
677
|
+
process.stdout.write(CLI_PROMPT);
|
|
646
678
|
continue;
|
|
647
679
|
}
|
|
648
680
|
else if (dispatchResult.result.action === "response") {
|
|
649
681
|
// eslint-disable-next-line no-console -- terminal UX: command dispatch result
|
|
650
682
|
console.log(dispatchResult.result.message || "");
|
|
651
|
-
process.stdout.write(
|
|
683
|
+
process.stdout.write(CLI_PROMPT);
|
|
652
684
|
continue;
|
|
653
685
|
}
|
|
654
686
|
}
|
|
@@ -664,7 +696,7 @@ async function runCliSession(options) {
|
|
|
664
696
|
if (options.runTurn) {
|
|
665
697
|
// Pipeline-based turn: the runTurn callback handles user message assembly,
|
|
666
698
|
// pending drain, trust gate, runAgent, postTurn, and token accumulation.
|
|
667
|
-
result = await options.runTurn(messages, input, cliCallbacks, currentAbort.signal);
|
|
699
|
+
result = await options.runTurn(messages, input, cliCallbacks, currentAbort.signal, effectiveToolContext);
|
|
668
700
|
}
|
|
669
701
|
else {
|
|
670
702
|
// Legacy path: inline runAgent (used by adoption specialist and tests)
|
|
@@ -676,7 +708,7 @@ async function runCliSession(options) {
|
|
|
676
708
|
traceId,
|
|
677
709
|
tools: options.tools,
|
|
678
710
|
execTool: wrappedExecTool,
|
|
679
|
-
toolContext:
|
|
711
|
+
toolContext: effectiveToolContext,
|
|
680
712
|
});
|
|
681
713
|
}
|
|
682
714
|
}
|
|
@@ -707,7 +739,7 @@ async function runCliSession(options) {
|
|
|
707
739
|
}
|
|
708
740
|
if (closed)
|
|
709
741
|
break;
|
|
710
|
-
process.stdout.write(
|
|
742
|
+
process.stdout.write(CLI_PROMPT);
|
|
711
743
|
}
|
|
712
744
|
}
|
|
713
745
|
finally {
|
|
@@ -781,7 +813,10 @@ async function main(agentName, options) {
|
|
|
781
813
|
agentName: currentAgentName,
|
|
782
814
|
pasteDebounceMs,
|
|
783
815
|
messages: sessionMessages,
|
|
784
|
-
|
|
816
|
+
onAsyncAssistantMessage: async (messages, _assistantMessage) => {
|
|
817
|
+
(0, context_1.postTurn)(messages, sessPath, undefined, undefined, sessionState);
|
|
818
|
+
},
|
|
819
|
+
runTurn: async (messages, userInput, callbacks, signal, toolContext) => {
|
|
785
820
|
// Run the full per-turn pipeline: resolve -> gate -> session -> drain -> runAgent -> postTurn -> tokens
|
|
786
821
|
// User message passed via input.messages so the pipeline can prepend pending messages to it.
|
|
787
822
|
const result = await (0, pipeline_1.handleInboundTurn)({
|
|
@@ -819,6 +854,7 @@ async function main(agentName, options) {
|
|
|
819
854
|
toolChoiceRequired: (0, commands_1.getToolChoiceRequired)(),
|
|
820
855
|
traceId: (0, nerves_1.createTraceId)(),
|
|
821
856
|
mcpManager,
|
|
857
|
+
toolContext,
|
|
822
858
|
},
|
|
823
859
|
});
|
|
824
860
|
// Handle gate rejection: display auto-reply if present
|