@higherdev/cli 0.14.3 → 0.14.4
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/tui/App.js +21 -24
- package/dist/tui/chat-wait.js +18 -0
- package/package.json +1 -1
package/dist/tui/App.js
CHANGED
|
@@ -18,7 +18,8 @@ import { alertOnce } from "./alert.js";
|
|
|
18
18
|
import { bubbleRows } from "./height.js";
|
|
19
19
|
import { planLayout, splitPanels } from "./layout.js";
|
|
20
20
|
import { parseLine } from "./parse.js";
|
|
21
|
-
import { configuredSlugs, acknowledgeInbox, approveEpic, cancelTicket, createAgent, createEpicFromFile, decisionOptions, deleteAgent, loadLiveEvents, listWorkspaceEnv, loadTicketDetail, pollSnapshot, postAgentMessage, queueTicket, resolveDecision, setWorkspacePaused, switchWorkspace, updateAgent, updateProviderCap, updateWorkspace, } from "./data.js";
|
|
21
|
+
import { configuredSlugs, acknowledgeInbox, approveEpic, cancelTicket, createAgent, createEpicFromFile, decisionOptions, deleteAgent, loadLiveEvents, listWorkspaceEnv, loadTicketDetail, pollSnapshot, postAgentMessage, queueTicket, resolveDecision, setWorkspacePaused, switchWorkspace, updateAgent, updateProviderCap, updateWorkspace, waitForReply, } from "./data.js";
|
|
22
|
+
import { inputActive, promptPlaceholder, QUEUED_STEP, REPLY_WAIT_MS, settleChatReply } from "./chat-wait.js";
|
|
22
23
|
import { editFor, editableKeys, nextValue, seedFor, settingsRows } from "./settings-model.js";
|
|
23
24
|
import { appendLines, runLabels, toStreamLines } from "./stream.js";
|
|
24
25
|
import { UI } from "./theme.js";
|
|
@@ -215,30 +216,26 @@ export function App({ initial }) {
|
|
|
215
216
|
setBusy(false);
|
|
216
217
|
}
|
|
217
218
|
}, [config, say]);
|
|
218
|
-
const askAgent = useCallback(
|
|
219
|
-
setBusy(true);
|
|
219
|
+
const askAgent = useCallback((role, text) => {
|
|
220
220
|
const id = nextId();
|
|
221
221
|
setMessages((prior) => [...prior, { id, speaker: role, body: "", pending: true }]);
|
|
222
222
|
const since = new Date().toISOString();
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
setMessages((prior) => prior.map((message) => message.id === id ? { ...message, done: true } : message));
|
|
240
|
-
setBusy(false);
|
|
241
|
-
}
|
|
223
|
+
void (async () => {
|
|
224
|
+
try {
|
|
225
|
+
await postAgentMessage(role, text, config);
|
|
226
|
+
setMessages((prior) => prior.map((message) => message.id === id
|
|
227
|
+
? { ...message, steps: [QUEUED_STEP] }
|
|
228
|
+
: message));
|
|
229
|
+
const reply = await waitForReply(config, role, since, REPLY_WAIT_MS);
|
|
230
|
+
setMessages((prior) => prior.map((message) => message.id === id
|
|
231
|
+
? { ...message, ...settleChatReply(reply) }
|
|
232
|
+
: message));
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
const body = error instanceof Error ? error.message : String(error);
|
|
236
|
+
setMessages((prior) => prior.map((message) => message.id === id ? { ...message, body, pending: false, done: true } : message));
|
|
237
|
+
}
|
|
238
|
+
})();
|
|
242
239
|
}, [config]);
|
|
243
240
|
const run = useCallback(async (raw) => {
|
|
244
241
|
const text = raw.trim();
|
|
@@ -281,7 +278,7 @@ export function App({ initial }) {
|
|
|
281
278
|
if (action.kind === "say") {
|
|
282
279
|
say("you", text);
|
|
283
280
|
if (mode !== "browse")
|
|
284
|
-
|
|
281
|
+
askAgent(mode, text);
|
|
285
282
|
else
|
|
286
283
|
setNotice("Use /architect or /orchestrator before sending a message.");
|
|
287
284
|
return;
|
|
@@ -589,7 +586,7 @@ export function App({ initial }) {
|
|
|
589
586
|
setDraft(next);
|
|
590
587
|
if (editingRef.current)
|
|
591
588
|
setEditing({ key: editingRef.current.key, draft: next });
|
|
592
|
-
}, onSubmit: (value) => void run(value), isActive:
|
|
589
|
+
}, onSubmit: (value) => void run(value), isActive: inputActive({ busy, pendingChats: inFlight.length }), placeholder: promptPlaceholder({ busy, pendingChats: inFlight.length }), prompt: _jsx(Text, { color: mode === "browse" ? UI.dim : UI.cream, children: mode === "browse" ? "> " : `${mode}> ` }), color: UI.text, onCancel: () => {
|
|
593
590
|
if (editing) {
|
|
594
591
|
setEditing(null);
|
|
595
592
|
setDraft("");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** How long the TUI waits for an architect or orchestrator reply. */
|
|
2
|
+
export const REPLY_WAIT_MS = 180_000;
|
|
3
|
+
/** Shown in the pending bubble when the wait expires. The reply can still land in /inbox. */
|
|
4
|
+
export const NO_REPLY_NOTE = "No reply yet. It will land in /inbox.";
|
|
5
|
+
export const QUEUED_STEP = "· queued, it answers on the next tick";
|
|
6
|
+
/**
|
|
7
|
+
* The prompt stays live while a chat reply is pending so navigation, /decide,
|
|
8
|
+
* and a follow-up send still work. `busy` is the only lock.
|
|
9
|
+
*/
|
|
10
|
+
export function inputActive(state) {
|
|
11
|
+
return !state.busy;
|
|
12
|
+
}
|
|
13
|
+
export function promptPlaceholder(state) {
|
|
14
|
+
return state.busy ? "working…" : "message, or /help";
|
|
15
|
+
}
|
|
16
|
+
export function settleChatReply(reply) {
|
|
17
|
+
return { body: reply ?? NO_REPLY_NOTE, pending: false, steps: [], done: true };
|
|
18
|
+
}
|