@epoch-agent/tui 0.3.1 → 0.4.0

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.
Files changed (2) hide show
  1. package/dist/index.js +55 -11
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/app.tsx
2
2
  import { Box as Box27, Static, Text as Text28, useBoxMetrics, useInput as useInput7, useWindowSize } from "ink";
3
- import { useCallback as useCallback13, useEffect as useEffect8, useMemo as useMemo11, useRef as useRef13, useState as useState15 } from "react";
3
+ import { useCallback as useCallback13, useEffect as useEffect8, useMemo as useMemo12, useRef as useRef13, useState as useState15 } from "react";
4
4
  import {
5
5
  extractAllMentions
6
6
  } from "@epoch-agent/protocol";
@@ -4209,6 +4209,38 @@ var useStreamingContext = () => {
4209
4209
  }
4210
4210
  return context2;
4211
4211
  };
4212
+ // src/dialogs/use-dialog-stack.ts
4213
+ import { useMemo as useMemo10 } from "react";
4214
+ // src/dialogs/stack.ts
4215
+ var DIALOG_ORDER = [
4216
+ "confirmation",
4217
+ "question",
4218
+ "picker",
4219
+ "search",
4220
+ "rewind"
4221
+ ];
4222
+ function topOf(open) {
4223
+ for (const kind of DIALOG_ORDER) {
4224
+ if (open[kind]) return kind;
4225
+ }
4226
+ return null;
4227
+ }
4228
+ function anyDialogOpen(open) {
4229
+ return topOf(open) !== null;
4230
+ }
4231
+ // src/dialogs/use-dialog-stack.ts
4232
+ function useDialogStack(open) {
4233
+ const { confirmation, question, picker, search, rewind: rewind2 } = open;
4234
+ return useMemo10(() => {
4235
+ const map = { confirmation, question, picker, search, rewind: rewind2 };
4236
+ const top = topOf(map);
4237
+ return {
4238
+ top,
4239
+ anyOpen: anyDialogOpen(map),
4240
+ isTop: (kind) => top === kind
4241
+ };
4242
+ }, [confirmation, question, picker, search, rewind2]);
4243
+ }
4212
4244
  // src/hooks/use-agent-run.ts
4213
4245
  import { useCallback as useCallback9, useRef as useRef11, useState as useState12 } from "react";
4214
4246
  import {
@@ -4591,7 +4623,7 @@ ${t("tui.rewind.screen_note")}`
4591
4623
  return { open, openPanel, closePanel: () => setOpen(false), finish };
4592
4624
  }
4593
4625
  // src/hooks/use-slash-commands.ts
4594
- import { useCallback as useCallback12, useMemo as useMemo10 } from "react";
4626
+ import { useCallback as useCallback12, useMemo as useMemo11 } from "react";
4595
4627
  // src/commands/builtin.ts
4596
4628
  import {
4597
4629
  isPermissionLevel,
@@ -5765,14 +5797,14 @@ function useSlashCommands(opts) {
5765
5797
  const { host, push, clear: clear2, exit: exit2, submitPrompt, approve, openRewind } = opts;
5766
5798
  const { showThoughts, setShowThoughts } = opts;
5767
5799
  const { commands: override, customCommands } = opts;
5768
- const commands = useMemo10(
5800
+ const commands = useMemo11(
5769
5801
  () => override ?? mergeCommands(availableCommands(host), (customCommands ?? []).map(toSlashCommand)),
5770
5802
  [override, customCommands, host]
5771
5803
  );
5772
5804
  const config = useConfig();
5773
5805
  const { stats } = useSessionStats();
5774
5806
  const { state: ui, setPicker, setPermissionLevel, setModel } = useUIState();
5775
- const hostWithSync = useMemo10(
5807
+ const hostWithSync = useMemo11(
5776
5808
  () => ({
5777
5809
  ...host,
5778
5810
  ...host.setPermissionLevel ? {
@@ -6197,7 +6229,14 @@ function App({
6197
6229
  addToast("error", err instanceof Error ? err.message : String(err));
6198
6230
  });
6199
6231
  }, [ui.history, ui.pendingHistoryItems, host, addToast]);
6200
- const modalOpen = ui.confirmationRequest !== null || ui.picker !== null || question.picker !== null || searchOpen || rewind2.open;
6232
+ const dialogs = useDialogStack({
6233
+ confirmation: ui.confirmationRequest !== null,
6234
+ question: question.picker !== null,
6235
+ picker: ui.picker !== null,
6236
+ search: searchOpen,
6237
+ rewind: rewind2.open
6238
+ });
6239
+ const modalOpen = dialogs.anyOpen;
6201
6240
  const escOnce = useCallback13(() => {
6202
6241
  if (run.isRunning) {
6203
6242
  run.abort();
@@ -6268,7 +6307,7 @@ function App({
6268
6307
  [setPicker]
6269
6308
  );
6270
6309
  const questionPicker = question.picker;
6271
- const staticItems = useMemo11(
6310
+ const staticItems = useMemo12(
6272
6311
  () => [
6273
6312
  /* @__PURE__ */ jsx30(Banner, { width: columns }, "banner"),
6274
6313
  ...ui.history.map((item) => /* @__PURE__ */ jsx30(HistoryItemDisplay, { item, terminalWidth: columns }, item.id))
@@ -6303,14 +6342,16 @@ function App({
6303
6342
  PlanConfirmation,
6304
6343
  {
6305
6344
  proposal: ui.confirmationRequest.request.plan,
6306
- onRespond: respondWithRuleHint
6345
+ onRespond: respondWithRuleHint,
6346
+ isActive: dialogs.isTop("confirmation")
6307
6347
  }
6308
6348
  ) : /* @__PURE__ */ jsx30(
6309
6349
  ToolConfirmation,
6310
6350
  {
6311
6351
  request: ui.confirmationRequest.request,
6312
6352
  onRespond: respondWithRuleHint,
6313
- remaining: Math.max(0, run.approvalCount - 1)
6353
+ remaining: Math.max(0, run.approvalCount - 1),
6354
+ isActive: dialogs.isTop("confirmation")
6314
6355
  }
6315
6356
  ) }),
6316
6357
  questionPicker && /* @__PURE__ */ jsx30(Box27, { paddingX: 1, paddingY: 1, children: /* @__PURE__ */ jsx30(
@@ -6318,7 +6359,8 @@ function App({
6318
6359
  {
6319
6360
  request: questionPicker,
6320
6361
  onPick: (value) => deliverPick(questionPicker, value),
6321
- onCancel: () => questionPicker.onCancel?.()
6362
+ onCancel: () => questionPicker.onCancel?.(),
6363
+ isActive: dialogs.isTop("question")
6322
6364
  },
6323
6365
  `q-${question.step}`
6324
6366
  ) }),
@@ -6328,12 +6370,13 @@ function App({
6328
6370
  request: ui.picker,
6329
6371
  onPick: pickWith(ui.picker),
6330
6372
  onCancel: () => setPicker(null),
6331
- isActive: questionPicker === null
6373
+ isActive: dialogs.isTop("picker")
6332
6374
  }
6333
6375
  ) }),
6334
6376
  searchOpen && host.searchSessions && /* @__PURE__ */ jsx30(Box27, { paddingX: 1, paddingY: 1, children: /* @__PURE__ */ jsx30(
6335
6377
  SearchPalette,
6336
6378
  {
6379
+ isActive: dialogs.isTop("search"),
6337
6380
  search: (q) => host.searchSessions(q),
6338
6381
  onPick: (chosen) => {
6339
6382
  setSearchOpen(false);
@@ -6359,7 +6402,8 @@ function App({
6359
6402
  checkpoints: host.checkpoints,
6360
6403
  ...host.gitDirty ? { gitDirty: host.gitDirty } : {},
6361
6404
  onDone: rewind2.finish,
6362
- onCancel: rewind2.closePanel
6405
+ onCancel: rewind2.closePanel,
6406
+ isActive: dialogs.isTop("rewind")
6363
6407
  }
6364
6408
  ) }),
6365
6409
  run.isRunning && run.startedAt !== null && !modalOpen && /* @__PURE__ */ jsx30(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epoch-agent/tui",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "description": "epoch-agent Ink TUI 界面",
6
6
  "repository": {
@@ -29,8 +29,8 @@
29
29
  "mnemonist": "0",
30
30
  "string-width": "8",
31
31
  "strip-ansi": "7",
32
- "@epoch-agent/protocol": "0.3.1",
33
- "@epoch-agent/view": "0.3.1"
32
+ "@epoch-agent/protocol": "0.4.0",
33
+ "@epoch-agent/view": "0.4.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.1.2",