agentix-cli 0.102.2 → 0.103.1

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 (114) hide show
  1. package/apps/mac-voice/Sources/AgentXVoice/Character.swift +33 -8
  2. package/apps/mac-voice/Sources/AgentXVoice/CharacterMath.swift +13 -0
  3. package/apps/mac-voice/Sources/AgentXVoice/CharacterSim.swift +14 -16
  4. package/apps/mac-voice/Sources/AgentXVoice/CharacterSimFrame.swift +15 -0
  5. package/apps/mac-voice/Sources/AgentXVoice/Guide.swift +14 -6
  6. package/apps/mac-voice/Sources/AgentXVoice/GuideMath.swift +14 -2
  7. package/apps/mac-voice/Sources/AgentXVoice/IdlePlay.swift +113 -0
  8. package/apps/mac-voice/Sources/AgentXVoice/PlayActs.swift +67 -14
  9. package/apps/mac-voice/Sources/AgentXVoice/PlayMath.swift +13 -17
  10. package/apps/mac-voice/Sources/AgentXVoice/PlayRead.swift +10 -3
  11. package/apps/mac-voice/Sources/AgentXVoice/PlayStage.swift +6 -3
  12. package/apps/mac-voice/Sources/AgentXVoice/SettingsLook.swift +11 -0
  13. package/apps/mac-voice/Sources/AgentXVoice/SettingsWindow.swift +4 -1
  14. package/apps/mac-voice/Sources/AgentXVoice/VoiceSettings.swift +8 -2
  15. package/apps/mac-voice/Sources/AgentXVoice/main.swift +23 -11
  16. package/dist/{App-EYUDDF6K.js → App-A7WZMOGA.js} +2 -2
  17. package/dist/{ChatApp-F5LZLBI3.js → ChatApp-EWNT36ZE.js} +2 -2
  18. package/dist/{agent-XF3BWMOB.js → agent-MUGC4RZP.js} +2 -2
  19. package/dist/{board-dashboard-TVSOWW32.js → board-dashboard-IRMCGCU5.js} +4 -4
  20. package/dist/{chunk-ZJXDBVBT.js → chunk-25RQQ55U.js} +2 -2
  21. package/dist/{chunk-YOCQ2MWL.js → chunk-32BPHJ4I.js} +2 -2
  22. package/dist/{chunk-AYNZAOJN.js → chunk-76KJXOEV.js} +2 -2
  23. package/dist/{chunk-V6W3FFW7.js → chunk-BEFKOHRC.js} +2 -2
  24. package/dist/{chunk-QRD3ZG27.js → chunk-BUAVQUHR.js} +2 -2
  25. package/dist/{chunk-PYCTWI2I.js → chunk-CUS7WGZT.js} +2 -2
  26. package/dist/{chunk-CDM4G3CW.js → chunk-CW667M47.js} +185 -185
  27. package/dist/{chunk-CDM4G3CW.js.map → chunk-CW667M47.js.map} +1 -1
  28. package/dist/{chunk-EXPIKLUN.js → chunk-FZ7VHFL5.js} +2 -2
  29. package/dist/{chunk-RWSCQMLD.js → chunk-HE4PDESB.js} +2 -2
  30. package/dist/{chunk-HMDM5MCR.js → chunk-HVPRCHRG.js} +2 -2
  31. package/dist/{chunk-ECM2QEXF.js → chunk-IA3BC7M3.js} +10 -10
  32. package/dist/chunk-IA3BC7M3.js.map +1 -0
  33. package/dist/{chunk-S337S2M7.js → chunk-IOPAWHKW.js} +2 -2
  34. package/dist/{chunk-Y6POV2X5.js → chunk-MVLNVMWI.js} +2 -2
  35. package/dist/{chunk-HQJW3BC5.js → chunk-N4IWNCH3.js} +2 -2
  36. package/dist/{chunk-MWLX3QCD.js → chunk-NWNVHL57.js} +2 -2
  37. package/dist/{chunk-5UO6BBDG.js → chunk-OLUAEBHJ.js} +2 -2
  38. package/dist/{chunk-XO55WKCX.js → chunk-Q57GZPDA.js} +2 -2
  39. package/dist/{chunk-TXFIMVVF.js → chunk-UXTAK5WD.js} +5 -5
  40. package/dist/{chunk-GSFB46YC.js → chunk-WTFNEPJ7.js} +2 -2
  41. package/dist/{chunk-EEZI2K7S.js → chunk-XHUOWYNY.js} +2 -2
  42. package/dist/{chunk-N57ES35J.js → chunk-ZBKKOUNJ.js} +2 -2
  43. package/dist/cli.js +1 -1
  44. package/dist/{client-526OCGWD.js → client-ZX7AY7H3.js} +2 -2
  45. package/dist/config-BXOS2PLC.js +2 -0
  46. package/dist/config-mutator-KRAUD3CA.js +2 -0
  47. package/dist/{doctor-AC5ONEO2.js → doctor-P3QQP33C.js} +2 -2
  48. package/dist/index.d.ts +11 -0
  49. package/dist/index.js +1 -1
  50. package/dist/{program-M5LDV6UQ.js → program-DELG6KQQ.js} +169 -169
  51. package/dist/program-DELG6KQQ.js.map +1 -0
  52. package/dist/{promote-CNKIINYK.js → promote-FHX4Q62Z.js} +2 -2
  53. package/dist/{query-A2N2LIR7.js → query-WBK3YEPV.js} +2 -2
  54. package/dist/{registry-REKWHOHS.js → registry-NQHC7ZAV.js} +2 -2
  55. package/dist/{request-planner-MS5BS6HY.js → request-planner-3LA5RAKG.js} +2 -2
  56. package/dist/{review-candidates-2F4QK6QQ.js → review-candidates-QV66TOCL.js} +2 -2
  57. package/dist/{routing-SU5Q4IPM.js → routing-HF4XVD4Y.js} +2 -2
  58. package/dist/schedule-tool-V66FX5XL.js +2 -0
  59. package/dist/scheduler-XVMWASQR.js +2 -0
  60. package/dist/{seat-PZBFMYQL.js → seat-NQTZUIKH.js} +2 -2
  61. package/dist/{select-D3XOFXA5.js → select-3GVC5RDA.js} +2 -2
  62. package/dist/{set-enabled-DNDRQ3CZ.js → set-enabled-SXCE2MZX.js} +2 -2
  63. package/dist/{tool-FB6SPVIS.js → tool-23GOQNUW.js} +2 -2
  64. package/dist/{tool-RRGOHJW6.js → tool-E6JBENAN.js} +2 -2
  65. package/dist/wiki-VM2RTHVF.js +2 -0
  66. package/package.json +1 -1
  67. package/dist/chunk-ECM2QEXF.js.map +0 -1
  68. package/dist/config-HCJ5NZW5.js +0 -2
  69. package/dist/config-mutator-PGR2OGWC.js +0 -2
  70. package/dist/program-M5LDV6UQ.js.map +0 -1
  71. package/dist/schedule-tool-24KHZY2Z.js +0 -2
  72. package/dist/scheduler-ALDZOUKJ.js +0 -2
  73. package/dist/wiki-3DH2QYTX.js +0 -2
  74. /package/dist/{App-EYUDDF6K.js.map → App-A7WZMOGA.js.map} +0 -0
  75. /package/dist/{ChatApp-F5LZLBI3.js.map → ChatApp-EWNT36ZE.js.map} +0 -0
  76. /package/dist/{agent-XF3BWMOB.js.map → agent-MUGC4RZP.js.map} +0 -0
  77. /package/dist/{board-dashboard-TVSOWW32.js.map → board-dashboard-IRMCGCU5.js.map} +0 -0
  78. /package/dist/{chunk-ZJXDBVBT.js.map → chunk-25RQQ55U.js.map} +0 -0
  79. /package/dist/{chunk-YOCQ2MWL.js.map → chunk-32BPHJ4I.js.map} +0 -0
  80. /package/dist/{chunk-AYNZAOJN.js.map → chunk-76KJXOEV.js.map} +0 -0
  81. /package/dist/{chunk-V6W3FFW7.js.map → chunk-BEFKOHRC.js.map} +0 -0
  82. /package/dist/{chunk-QRD3ZG27.js.map → chunk-BUAVQUHR.js.map} +0 -0
  83. /package/dist/{chunk-PYCTWI2I.js.map → chunk-CUS7WGZT.js.map} +0 -0
  84. /package/dist/{chunk-EXPIKLUN.js.map → chunk-FZ7VHFL5.js.map} +0 -0
  85. /package/dist/{chunk-RWSCQMLD.js.map → chunk-HE4PDESB.js.map} +0 -0
  86. /package/dist/{chunk-HMDM5MCR.js.map → chunk-HVPRCHRG.js.map} +0 -0
  87. /package/dist/{chunk-S337S2M7.js.map → chunk-IOPAWHKW.js.map} +0 -0
  88. /package/dist/{chunk-Y6POV2X5.js.map → chunk-MVLNVMWI.js.map} +0 -0
  89. /package/dist/{chunk-HQJW3BC5.js.map → chunk-N4IWNCH3.js.map} +0 -0
  90. /package/dist/{chunk-MWLX3QCD.js.map → chunk-NWNVHL57.js.map} +0 -0
  91. /package/dist/{chunk-5UO6BBDG.js.map → chunk-OLUAEBHJ.js.map} +0 -0
  92. /package/dist/{chunk-XO55WKCX.js.map → chunk-Q57GZPDA.js.map} +0 -0
  93. /package/dist/{chunk-TXFIMVVF.js.map → chunk-UXTAK5WD.js.map} +0 -0
  94. /package/dist/{chunk-GSFB46YC.js.map → chunk-WTFNEPJ7.js.map} +0 -0
  95. /package/dist/{chunk-EEZI2K7S.js.map → chunk-XHUOWYNY.js.map} +0 -0
  96. /package/dist/{chunk-N57ES35J.js.map → chunk-ZBKKOUNJ.js.map} +0 -0
  97. /package/dist/{client-526OCGWD.js.map → client-ZX7AY7H3.js.map} +0 -0
  98. /package/dist/{config-HCJ5NZW5.js.map → config-BXOS2PLC.js.map} +0 -0
  99. /package/dist/{config-mutator-PGR2OGWC.js.map → config-mutator-KRAUD3CA.js.map} +0 -0
  100. /package/dist/{doctor-AC5ONEO2.js.map → doctor-P3QQP33C.js.map} +0 -0
  101. /package/dist/{promote-CNKIINYK.js.map → promote-FHX4Q62Z.js.map} +0 -0
  102. /package/dist/{query-A2N2LIR7.js.map → query-WBK3YEPV.js.map} +0 -0
  103. /package/dist/{registry-REKWHOHS.js.map → registry-NQHC7ZAV.js.map} +0 -0
  104. /package/dist/{request-planner-MS5BS6HY.js.map → request-planner-3LA5RAKG.js.map} +0 -0
  105. /package/dist/{review-candidates-2F4QK6QQ.js.map → review-candidates-QV66TOCL.js.map} +0 -0
  106. /package/dist/{routing-SU5Q4IPM.js.map → routing-HF4XVD4Y.js.map} +0 -0
  107. /package/dist/{schedule-tool-24KHZY2Z.js.map → schedule-tool-V66FX5XL.js.map} +0 -0
  108. /package/dist/{scheduler-ALDZOUKJ.js.map → scheduler-XVMWASQR.js.map} +0 -0
  109. /package/dist/{seat-PZBFMYQL.js.map → seat-NQTZUIKH.js.map} +0 -0
  110. /package/dist/{select-D3XOFXA5.js.map → select-3GVC5RDA.js.map} +0 -0
  111. /package/dist/{set-enabled-DNDRQ3CZ.js.map → set-enabled-SXCE2MZX.js.map} +0 -0
  112. /package/dist/{tool-FB6SPVIS.js.map → tool-23GOQNUW.js.map} +0 -0
  113. /package/dist/{tool-RRGOHJW6.js.map → tool-E6JBENAN.js.map} +0 -0
  114. /package/dist/{wiki-3DH2QYTX.js.map → wiki-VM2RTHVF.js.map} +0 -0
@@ -14,14 +14,21 @@ enum PlayRead {
14
14
  /// Shows the system's request, once; after that macOS only answers no.
15
15
  static func ask() { CGRequestScreenCaptureAccess() }
16
16
 
17
- /// What is on `screen` now.
18
- static func picture(of screen: NSScreen) -> CGImage? {
17
+ /// What is on `screen` now, without the windows numbered `without`:
18
+ /// the character stays on its edge while the picture is taken, and
19
+ /// must not be in it twice (#580). The app's other windows stay in
20
+ /// it, its menu-bar icon among them (#583).
21
+ static func picture(of screen: NSScreen, without: [Int]) -> CGImage? {
19
22
  // Screens are measured from the bottom of the first one; the
20
23
  // picture is asked for from its top.
21
24
  guard let first = NSScreen.screens.first else { return nil }
22
25
  let f = screen.frame
23
26
  let rect = CGRect(x: f.minX, y: first.frame.maxY - f.maxY, width: f.width, height: f.height)
24
- return CGWindowListCreateImage(rect, .optionOnScreenOnly, kCGNullWindowID, [.bestResolution])
27
+ let shown = CGWindowListCopyWindowInfo([.optionOnScreenOnly], kCGNullWindowID) as? [[String: Any]] ?? []
28
+ var others: [UnsafeRawPointer?] = shown.compactMap { $0[kCGWindowNumber as String] as? Int }
29
+ .filter { !without.contains($0) }.map { UnsafeRawPointer(bitPattern: $0) }
30
+ guard let list = CFArrayCreate(nil, &others, others.count, nil) else { return nil }
31
+ return CGImage(windowListFromArrayScreenBounds: rect, windowArray: list, imageOption: [.bestResolution])
25
32
  }
26
33
 
27
34
  /// The lines of text in `image`, top to bottom, in points of a picture
@@ -34,7 +34,7 @@ enum PlayDraw {
34
34
  }
35
35
  let shown = CharacterSim.Frame(pose: frame.pose, x: frame.at.x, face: frame.face, t: frame.t)
36
36
  CharacterDraw.draw(shown, in: ctx, edge: CGPoint(x: frame.at.x, y: frame.at.y), origin: 0,
37
- unit: CGFloat(PlayMath.unit), stops: stops)
37
+ unit: CGFloat(PlayMath.unit * frame.scale), stops: stops)
38
38
  }
39
39
 
40
40
  private static func cg(_ r: PlayMath.Rect) -> CGRect { CGRect(x: r.x, y: r.y, width: r.w, height: r.h) }
@@ -120,7 +120,8 @@ final class PlayHost {
120
120
  let view = PlayView(frame: bounds)
121
121
  view.stops = stops
122
122
  view.picture = picture
123
- view.shown = Play.Frame(at: foot, pose: CharacterMath.pose(.working))
123
+ // As big as on its edge, where it stood: it shrinks once it jumps (#580).
124
+ view.shown = Play.Frame(at: foot, pose: CharacterMath.pose(.working), scale: PlayMath.edge)
124
125
  view.onInput = { [weak self] in self?.end("a key or a click") }
125
126
  backdrop.addSubview(view)
126
127
  panel.contentView = backdrop
@@ -174,11 +175,13 @@ final class PlayHost {
174
175
  timer = nil
175
176
  for (center, observer) in observers { center.removeObserver(observer) }
176
177
  observers = []
178
+ // The character is back on its edge before the picture goes, so
179
+ // it is never off the screen in between (#580).
180
+ onEnd?()
177
181
  panel.orderOut(nil)
178
182
  panel.contentView?.layer?.contents = nil
179
183
  panel.contentView = nil
180
184
  Log.info("play: ended, \(why)")
181
- onEnd?()
182
185
  }
183
186
  }
184
187
 
@@ -59,6 +59,8 @@ struct LookSection: View {
59
59
  var startReduced: Binding<Bool>?
60
60
  /// Nil hides the control: the daemon is older than the stroll.
61
61
  var stroll: Binding<Bool>?
62
+ /// Nil hides the control: the daemon is older than the animations.
63
+ var animations: Binding<String>?
62
64
 
63
65
  var body: some View {
64
66
  Section {
@@ -74,6 +76,15 @@ struct LookSection: View {
74
76
  Toggle("Character strolls when idle", isOn: stroll)
75
77
  .disabled(look != "character")
76
78
  }
79
+ if let animations {
80
+ Picker("Character plays when idle", selection: animations) {
81
+ Text("Never").tag("off")
82
+ Text("Rarely").tag("rarely")
83
+ Text("Sometimes").tag("sometimes")
84
+ Text("Often").tag("often")
85
+ }
86
+ .disabled(look != "character")
87
+ }
77
88
  } header: {
78
89
  Text("Assistant")
79
90
  } footer: {
@@ -381,7 +381,10 @@ private struct GeneralTab: View {
381
381
  set: { model.draft?.general.startReduced = $0 }),
382
382
  stroll: draft.general.stroll == nil ? nil
383
383
  : Binding(get: { model.draft?.general.stroll ?? false },
384
- set: { model.draft?.general.stroll = $0 }))
384
+ set: { model.draft?.general.stroll = $0 }),
385
+ animations: draft.general.animations == nil ? nil
386
+ : Binding(get: { model.draft?.general.animations ?? "off" },
387
+ set: { model.draft?.general.animations = $0 }))
385
388
  }
386
389
  if draft.general.card != nil {
387
390
  AnswerCardSection(card: Binding(get: { model.draft?.general.card ?? .standard },
@@ -35,14 +35,18 @@ struct VoiceSettings: Codable, Equatable {
35
35
  /// The character takes a stroll when it has nothing to do. Nil
36
36
  /// from a daemon older than the stroll.
37
37
  var stroll: Bool?
38
+ /// How often the character plays a small animation by itself:
39
+ /// "off", "rarely", "sometimes" or "often". Nil from a daemon
40
+ /// older than the animations.
41
+ var animations: String?
38
42
 
39
43
  init(provider: String, fallback: String, stt: String, localStt: String = "mlx-whisper",
40
44
  endOfTurn: String = "vad", hotkeys: Hotkeys, card: Card? = nil, look: String? = nil,
41
- startReduced: Bool? = nil, stroll: Bool? = nil) {
45
+ startReduced: Bool? = nil, stroll: Bool? = nil, animations: String? = nil) {
42
46
  self.provider = provider; self.fallback = fallback; self.stt = stt
43
47
  self.localStt = localStt; self.endOfTurn = endOfTurn; self.hotkeys = hotkeys
44
48
  self.card = card; self.look = look; self.startReduced = startReduced
45
- self.stroll = stroll
49
+ self.stroll = stroll; self.animations = animations
46
50
  }
47
51
 
48
52
  /// A daemon from before these fields leaves them out: the defaults.
@@ -58,6 +62,7 @@ struct VoiceSettings: Codable, Equatable {
58
62
  look = try c.decodeIfPresent(String.self, forKey: .look)
59
63
  startReduced = try c.decodeIfPresent(Bool.self, forKey: .startReduced)
60
64
  stroll = try c.decodeIfPresent(Bool.self, forKey: .stroll)
65
+ animations = try c.decodeIfPresent(String.self, forKey: .animations)
61
66
  }
62
67
  }
63
68
  struct Voice: Codable, Equatable {
@@ -119,6 +124,7 @@ struct VoiceSettings: Codable, Equatable {
119
124
  if let look = self.general.look, look != old.general.look { general["look"] = look }
120
125
  if let start = self.general.startReduced, start != old.general.startReduced { general["startReduced"] = start }
121
126
  if let stroll = self.general.stroll, stroll != old.general.stroll { general["stroll"] = stroll }
127
+ if let often = self.general.animations, often != old.general.animations { general["animations"] = often }
122
128
  var keys: [String: Any] = [:]
123
129
  if self.general.hotkeys.talk != old.general.hotkeys.talk { keys["talk"] = self.general.hotkeys.talk }
124
130
  if self.general.hotkeys.stop != old.general.hotkeys.stop { keys["stop"] = self.general.hotkeys.stop }
@@ -88,6 +88,8 @@ final class App: NSObject, NSApplicationDelegate {
88
88
  private let guideWatcher = GuideWatcher()
89
89
  /// A play runs, or its picture is being taken (#562).
90
90
  private var playing = false
91
+ /// When the app started, for the hint in the character's bubble.
92
+ private let launched = ProcessInfo.processInfo.systemUptime
91
93
  private let ringer = Ringer()
92
94
  /// The call ringing on the pill now.
93
95
  private var ringingCall: IncomingCall?
@@ -218,7 +220,9 @@ final class App: NSObject, NSApplicationDelegate {
218
220
  panel.setShowsOrb(!asCharacter)
219
221
  character.setShown(asCharacter)
220
222
  character.strolls = saved.general.stroll == true
223
+ character.animates = IdlePlay.gap(saved.general.animations)
221
224
  if !asCharacter { panel.detach() }
225
+ idleWords()
222
226
  // voice.startReduced is how the assistant starts: read once.
223
227
  if !startApplied {
224
228
  startApplied = true
@@ -240,16 +244,19 @@ final class App: NSObject, NSApplicationDelegate {
240
244
 
241
245
  /// What the idle bubble says (#562): no hint at a guide stop, on the
242
246
  /// way there or during a play; the stop's caption if it has one.
247
+ /// The character's bubble says the hint only just after the app
248
+ /// starts, then there is none at idle (#576).
243
249
  private func idleWords() {
244
- panel.setIdle(GuideMath.idle(caption: character.caption, away: character.sent || playing))
250
+ let hint = GuideMath.hintShows(character: settings?.general.look == "character",
251
+ sinceStart: ProcessInfo.processInfo.systemUptime - launched, held: Hold.isOn)
252
+ panel.setIdle(GuideMath.idle(caption: character.caption, away: character.sent || playing, hint: hint))
245
253
  }
246
254
 
247
255
  /// "Play on this page" (#505): one picture of the character's screen, the
248
256
  /// lines of text read on it, and the character plays on the picture,
249
257
  /// differently each time. The page itself is never touched.
250
258
  private func startPlay() {
251
- let foot = character.foot
252
- guard canPlay, let screen = NSScreen.screens.first(where: { $0.frame.contains(foot) }) ?? NSScreen.screens.first
259
+ guard canPlay, let screen = NSScreen.screens.first(where: { $0.frame.contains(character.foot) }) ?? NSScreen.screens.first
253
260
  else { return }
254
261
  guard PlayRead.allowed else {
255
262
  PlayRead.ask()
@@ -259,21 +266,23 @@ final class App: NSObject, NSApplicationDelegate {
259
266
  return
260
267
  }
261
268
  let stops = character.stops, size = screen.frame.size
262
- let start = PlayMath.Point(x: foot.x - screen.frame.minX, y: screen.frame.maxY - foot.y)
263
- // Off its edge, so it is not in the picture twice; its idle
264
- // bubble too, which would stay in the picture all the play long.
265
- character.setShown(false)
269
+ // No idle bubble while it is away. The picture leaves the character
270
+ // and its bubble out, so the character stays where it is meanwhile.
266
271
  playing = true
267
272
  idleWords()
268
273
  Task { @MainActor in
269
274
  try? await Task.sleep(nanoseconds: 150_000_000)
270
- guard let picture = PlayRead.picture(of: screen), !busy, !recorder.isRecording else {
275
+ guard let picture = PlayRead.picture(of: screen, without: character.windows + [panel.windowNumber]), !busy, !recorder.isRecording else {
271
276
  playing = false
272
- character.setShown(settings?.general.look == "character")
273
277
  idleWords()
274
278
  return
275
279
  }
280
+ let foot = character.foot
281
+ let start = PlayMath.Point(x: foot.x - screen.frame.minX, y: screen.frame.maxY - foot.y)
276
282
  play.start(picture: picture, on: screen, stops: stops, at: start)
283
+ // It is on the picture now, where it stood and as big: its own
284
+ // window goes from under it, and it never disappears (#580).
285
+ character.setAway(true)
277
286
  let number = play.number
278
287
  let asked = ProcessInfo.processInfo.systemUptime
279
288
  let lines = await Task.detached { PlayRead.lines(in: picture, size: size) }.value
@@ -417,7 +426,7 @@ final class App: NSObject, NSApplicationDelegate {
417
426
  play.onEnd = { [weak self] in
418
427
  guard let self else { return }
419
428
  self.playing = false
420
- self.character.setShown(self.settings?.general.look == "character")
429
+ self.character.setAway(false)
421
430
  self.idleWords()
422
431
  }
423
432
  panel.onShown = { [weak self] in self?.character.redraw() }
@@ -507,6 +516,7 @@ final class App: NSObject, NSApplicationDelegate {
507
516
  // and this switch is not that.
508
517
  statusMenu.onHoldChanged = { [weak self] nowOn in
509
518
  guard let self else { return }
519
+ self.idleWords()
510
520
  self.panel.render(.idle)
511
521
  if !nowOn { Hold.flushHeld() }
512
522
  Log.info(nowOn ? "notifications held" : "notifications delivering")
@@ -526,8 +536,10 @@ final class App: NSObject, NSApplicationDelegate {
526
536
  callWatcher.start()
527
537
  // The answering agent sends the character to something (#482).
528
538
  guideWatcher.wanted = { [weak self] in self?.character.onScreen == true }
529
- guideWatcher.onCommand = { [weak self] rect, mark, caption in self?.character.guide(to: rect, mark: mark, caption: caption) }
539
+ guideWatcher.onCommand = { [weak self] rect, mark, caption, asked in self?.character.guide(to: rect, mark: mark, caption: caption, asked: asked) }
530
540
  character.onGuide = { [weak self] in self?.idleWords() }
541
+ // The hint has had its seconds: no bubble at idle from here.
542
+ DispatchQueue.main.asyncAfter(deadline: .now() + GuideMath.hintSeconds) { [weak self] in self?.idleWords() }
531
543
  guideWatcher.start()
532
544
  character.onScreenChanged = { [weak self] in self?.guideWatcher.start() }
533
545
 
@@ -1,8 +1,8 @@
1
- import{a as F,b as L,c as U,d as N,e as O,f as H,g as j}from"./chunk-U2CKL755.js";import{b as B,c as D,d as A,e as P,g as M}from"./chunk-PYCTWI2I.js";import"./chunk-ECM2QEXF.js";import"./chunk-RJ7DASOU.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";import{useEffect as R,useReducer as V,useRef as G}from"react";import{Box as i,Text as o,useApp as W,useInput as J}from"ink";import{randomUUID as z}from"crypto";async function*q(e){let r=[];e.type&&r.push(`type=${encodeURIComponent(e.type)}`);let t=`${e.baseUrl.replace(/\/+$/,"")}/events${r.length?`?${r.join("&")}`:""}`,n={Accept:"text/event-stream"};e.token&&(n.Authorization=`Bearer ${e.token}`);let s=await fetch(t,{headers:n,signal:e.signal});if(!s.ok||!s.body)throw new Error(`SSE connect failed: HTTP ${s.status}`);let u=s.body.getReader(),p=new TextDecoder,y="";try{for(;;){let{done:f,value:l}=await u.read();if(f)return;y+=p.decode(l,{stream:!0});let d;for(;(d=y.indexOf(`
1
+ import{a as F,b as L,c as U,d as N,e as O,f as H,g as j}from"./chunk-U2CKL755.js";import{b as B,c as D,d as A,e as P,g as M}from"./chunk-CUS7WGZT.js";import"./chunk-IA3BC7M3.js";import"./chunk-RJ7DASOU.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";import{useEffect as R,useReducer as V,useRef as G}from"react";import{Box as i,Text as o,useApp as W,useInput as J}from"ink";import{randomUUID as z}from"crypto";async function*q(e){let r=[];e.type&&r.push(`type=${encodeURIComponent(e.type)}`);let t=`${e.baseUrl.replace(/\/+$/,"")}/events${r.length?`?${r.join("&")}`:""}`,n={Accept:"text/event-stream"};e.token&&(n.Authorization=`Bearer ${e.token}`);let s=await fetch(t,{headers:n,signal:e.signal});if(!s.ok||!s.body)throw new Error(`SSE connect failed: HTTP ${s.status}`);let u=s.body.getReader(),p=new TextDecoder,y="";try{for(;;){let{done:f,value:l}=await u.read();if(f)return;y+=p.decode(l,{stream:!0});let d;for(;(d=y.indexOf(`
2
2
 
3
3
  `))>=0;){let h=y.slice(0,d);y=y.slice(d+2);let m=X(h);m&&(yield m)}}}finally{try{u.releaseLock()}catch{}}}function X(e){let r="message",t="";for(let s of e.split(`
4
4
  `))s.startsWith("event: ")?r=s.slice(7):s.startsWith("data: ")&&(t=s.slice(6));if(!t)return null;let n;try{n=JSON.parse(t)}catch{n=t}return{event:r,data:n}}import{jsx as a,jsxs as c}from"react/jsx-runtime";function $(e,r){return r<=0||e<0?0:e>=r?r-1:e}function E(){return`tui:${z().slice(0,12)}`}function k(e,r){let t=[...e,r];return t.length>50&&t.splice(0,t.length-50),t}function Y(e,r){switch(r.type){case"agents":return{...e,agents:r.data,cursor:{...e.cursor,agents:$(e.cursor.agents,r.data.length)}};case"processes":return{...e,processes:r.data,cursor:{...e.cursor,processes:$(e.cursor.processes,r.data.length)}};case"crons":return{...e,crons:r.data};case"event":{let t=[r.row,...e.events];t.length>200&&(t.length=200);let n=e.channels;return r.channelTally&&(n=new Map(e.channels),n.set(r.channelTally.channel,r.channelTally)),{...e,events:t,channels:n}}case"connError":return{...e,connError:r.error};case"tick":return{...e,lastTick:Date.now()};case"focus":return{...e,focus:r.pane};case"cursor":{let t=r.pane==="agents"?e.agents.length:r.pane==="processes"?e.processes.length:e.events.length;return{...e,cursor:{...e.cursor,[r.pane]:$(e.cursor[r.pane]+r.delta,t)}}}case"bottomRight":return{...e,bottomRight:r.pane};case"chatStart":return{...e,chat:{active:!0,agentId:r.agentId,chatId:E(),history:[],text:"",status:"idle",error:null}};case"chatExit":return{...e,chat:{...e.chat,active:!1}};case"chatClear":return{...e,chat:{...e.chat,chatId:E(),history:[],text:"",status:"idle",error:null}};case"chatText":return{...e,chat:{...e.chat,text:r.text}};case"chatSubmitStart":return{...e,chat:{...e.chat,history:k(e.chat.history,r.you),text:"",status:"sending",error:null}};case"chatSubmitDone":return{...e,chat:{...e.chat,history:k(e.chat.history,r.reply),status:"idle",error:null}};case"chatSubmitError":return{...e,chat:{...e.chat,history:k(e.chat.history,{role:"error",text:r.error,at:Date.now()}),status:"idle",error:r.error}};case"chatStreamStart":{let t=k(e.chat.history,r.you),n=k(t,{role:"agent",text:"",at:Date.now(),streaming:!0,tools:[]});return{...e,chat:{...e.chat,history:n,text:"",status:"sending",error:null}}}case"chatStreamDelta":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]={...n,text:n.text+r.text}),{...e,chat:{...e.chat,history:t}}}case"chatStreamThinking":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]={...n,thinking:(n.thinking??"")+r.text}),{...e,chat:{...e.chat,history:t}}}case"chatStreamTool":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]={...n,tools:[...n.tools??[],{name:r.name,arg:r.arg,error:r.error}]}),{...e,chat:{...e.chat,history:t}}}case"chatStreamEnd":{let t=e.chat.history.slice(),n=t[t.length-1];return n?.role==="agent"&&n.streaming&&(t[t.length-1]=r.error?{...n,streaming:!1,role:"error",text:r.error}:{...n,streaming:!1,elapsedMs:r.elapsedMs,outTokens:r.outTokens}),{...e,chat:{...e.chat,history:t,status:"idle",error:r.error??null}}}case"toast":return{...e,toast:{text:r.text,color:r.color,at:Date.now()}};case"clearToast":return{...e,toast:null}}}var _={agents:[],processes:[],crons:[],events:[],channels:new Map,connError:null,lastTick:0,focus:"agents",cursor:{agents:0,processes:0,events:0},bottomRight:"crons",chat:{active:!1,agentId:null,chatId:E(),history:[],text:"",status:"idle",error:null},toast:null};function be({conn:e,pollMs:r=3e3}){let[t,n]=V(Y,_),{exit:s}=W(),u=G(null),p=G(null),y=t.agents.map(l=>l.id),f=t.chat.active?L(t.chat.text,y,process.cwd()):null;return R(()=>{if(!t.toast)return;let l=setTimeout(()=>n({type:"clearToast"}),3500);return()=>clearTimeout(l)},[t.toast]),J((l,d)=>{if(t.chat.active){if(d.escape){n({type:"chatExit"});return}if(d.ctrl&&l==="l"){n({type:"chatClear"});return}if(d.tab){let m=U(t.chat.text,p,y,process.cwd());m!==null&&n({type:"chatText",text:m});return}if(d.backspace||d.delete){p.current=null,n({type:"chatText",text:t.chat.text.slice(0,-1)});return}if(d.ctrl||d.meta)return;let h=N(l??"",d.return,t.chat.text);if(h.kind==="paste"||h.kind==="type"){p.current=null,n({type:"chatText",text:t.chat.text+h.text});return}if(h.kind==="continue"){n({type:"chatText",text:h.buffer});return}if(h.kind==="submit"){let m=h.text.trim(),g=t.chat.agentId;if(!m||!g||t.chat.status==="sending"){n({type:"chatText",text:""});return}p.current=null;let b=Date.now(),w=t.chat.chatId;n({type:"chatStreamStart",you:{role:"you",text:m,at:b}}),(async()=>{try{let C=await M(e,g,m,{channel:"tui",chatId:w,onText:x=>n({type:"chatStreamDelta",text:x}),onThinking:x=>n({type:"chatStreamThinking",text:x}),onTool:x=>{x.status==="start"&&x.name?n({type:"chatStreamTool",name:x.name,arg:x.arg}):x.status==="result"&&x.error&&n({type:"chatStreamTool",name:x.name??"tool",error:!0})}});n({type:"chatStreamEnd",elapsedMs:Date.now()-b,outTokens:C.usage?.outputTokens,error:C.error})}catch(C){n({type:"chatStreamEnd",elapsedMs:Date.now()-b,error:C?.message||String(C)})}})();return}return}if(l==="q"||d.ctrl&&l==="c"){u.current?.abort(),s();return}if(d.tab){let h=["agents","processes","events"],m=h.indexOf(t.focus);n({type:"focus",pane:h[(m+1)%h.length]});return}if(l==="a"){n({type:"focus",pane:"agents"});return}if(l==="p"){n({type:"focus",pane:"processes"});return}if(l==="e"){n({type:"focus",pane:"events"});return}if(l==="c"){n({type:"bottomRight",pane:t.bottomRight==="crons"?"channels":"crons"});return}if(d.upArrow){n({type:"cursor",pane:t.focus,delta:-1});return}if(d.downArrow){n({type:"cursor",pane:t.focus,delta:1});return}if(d.return&&t.focus==="agents"){let h=t.agents[t.cursor.agents];if(!h){n({type:"toast",text:"no agent selected",color:"yellow"});return}n({type:"chatStart",agentId:h.id});return}if(l==="k"&&t.focus==="processes"){let h=t.processes[t.cursor.processes];if(!h){n({type:"toast",text:"no process selected",color:"yellow"});return}(async()=>{try{await P(e,h.key,"tui"),n({type:"toast",text:`killed ${h.key.agentId}/${h.key.channel}/${h.key.chatId}`,color:"green"})}catch(m){n({type:"toast",text:`kill failed: ${m?.message||m}`,color:"red"})}})();return}}),R(()=>{let l=new AbortController;u.current=l;let d=!1,h=async()=>{try{let[g,b,w]=await Promise.all([B(e,l.signal).catch(()=>[]),D(e,l.signal).catch(()=>[]),A(e,l.signal).catch(()=>[])]);if(d)return;n({type:"agents",data:g}),n({type:"processes",data:b}),n({type:"crons",data:w}),n({type:"tick"}),n({type:"connError",error:null})}catch(g){d||n({type:"connError",error:g?.message||String(g)})}};h();let m=setInterval(h,r);return()=>{d=!0,clearInterval(m),l.abort()}},[e.baseUrl,e.token,r]),R(()=>{let l=!1,d=new AbortController,h=new Map;return(async()=>{let m=500;for(;!l;){try{for await(let g of q({baseUrl:e.baseUrl,token:e.token,signal:d.signal})){let b=ae(g),w;if(g.event==="channel"&&typeof g.data?.channel=="string"){let S=h.get(g.data.channel)??{channel:g.data.channel,inbound:0,outbound:0,lastAt:0,lastPreview:""},C=S.inbound+(g.data.direction==="in"?1:0),x=S.outbound+(g.data.direction==="out"?1:0);w={channel:g.data.channel,inbound:C,outbound:x,lastAt:b.at,lastPreview:(g.data.textPreview||"").slice(0,60)},h.set(g.data.channel,w)}n({type:"event",row:b,channelTally:w}),m=500}}catch(g){if(l)return;n({type:"connError",error:`events: ${g?.message||g}`})}await new Promise(g=>setTimeout(g,m)),m=Math.min(m*2,1e4)}})(),()=>{l=!0,d.abort()}},[e.baseUrl,e.token]),c(i,{flexDirection:"column",width:"100%",children:[a(K,{conn:e,lastTick:t.lastTick,connError:t.connError,chat:t.chat}),c(i,{flexDirection:"row",flexGrow:1,children:[c(i,{flexDirection:"column",width:"50%",children:[a(v,{title:"AGENTS",focused:!t.chat.active&&t.focus==="agents",children:a(Z,{rows:t.agents,cursor:t.cursor.agents,focused:!t.chat.active&&t.focus==="agents",talkingTo:t.chat.active?t.chat.agentId:null})}),a(v,{title:"PROCESSES",focused:!t.chat.active&&t.focus==="processes",children:a(ee,{rows:t.processes,cursor:t.cursor.processes,focused:!t.chat.active&&t.focus==="processes"})})]}),t.chat.active?a(oe,{chat:t.chat,suggest:f,agents:t.agents}):c(i,{flexDirection:"column",width:"50%",children:[a(v,{title:"LIVE EVENTS",focused:t.focus==="events",children:a(ne,{rows:t.events,cursor:t.cursor.events,focused:t.focus==="events"})}),a(v,{title:t.bottomRight==="crons"?"CRONS / SCHEDULES":"CHANNELS",focused:!1,children:t.bottomRight==="crons"?a(te,{rows:t.crons}):a(re,{rows:Array.from(t.channels.values())})})]})]}),a(Q,{focus:t.focus,bottomRight:t.bottomRight,chat:t.chat,toast:t.toast})]})}function K({conn:e,lastTick:r,connError:t,chat:n}){let s=t?c(o,{color:"red",children:["\u25CF ",t]}):r===0?a(o,{color:"yellow",children:"\u25CF connecting\u2026"}):a(o,{color:"green",children:"\u25CF live"}),u=n.active?c(o,{color:"green",bold:!0,children:["CHAT @",n.agentId]}):a(o,{bold:!0,children:"agentx tui"});return c(i,{paddingX:1,justifyContent:"space-between",children:[a(i,{children:u}),a(o,{dimColor:!0,children:e.baseUrl}),a(i,{children:s})]})}function Q({focus:e,bottomRight:r,chat:t,toast:n}){let s=t.active?["[Enter] send","[Esc] exit chat","[Ctrl-L] new session"]:[`[Tab/a/p/e] focus (now: ${e})`,e==="agents"?"[Enter] chat":null,e==="processes"?"[k] kill":null,`[c] ${r==="crons"?"\u2192channels":"\u2192crons"}`,"[\u2191/\u2193] move","[q] quit"].filter(Boolean);return c(i,{paddingX:1,borderStyle:"single",borderTop:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,justifyContent:"space-between",children:[a(o,{dimColor:!0,children:s.join(" \xB7 ")}),n?a(o,{color:n.color,children:n.text}):a(o,{children:" "})]})}function v({title:e,focused:r,children:t}){return c(i,{flexDirection:"column",width:"100%",borderStyle:r?"double":"single",borderColor:r?"cyan":void 0,paddingX:1,children:[c(o,{bold:!0,color:r?"cyan":"white",children:[e,r?" \u25CF":""]}),a(i,{flexDirection:"column",marginTop:1,children:t})]})}function I(e,r){return e&&r?{inverse:!0}:{}}function Z({rows:e,cursor:r,focused:t,talkingTo:n}){return e.length===0?a(o,{dimColor:!0,children:"no agents"}):a(i,{flexDirection:"column",children:e.slice(0,12).map((s,u)=>{let p=I(t,u===r),y=s.errors>0?"red":s.active>0?"yellow":"green",f=s.id===n;return c(i,{children:[a(o,{...p,color:y,children:"\u25CF"}),c(o,{...p,children:[" ",T(s.name,14)]}),c(o,{...p,children:[T(s.tier,6)," "]}),c(o,{...p,children:[s.active,"/",s.total]}),s.errors>0?c(o,{...p,color:"red",children:[" err=",s.errors]}):null,f?a(o,{color:"green",children:" \u2194 chatting"}):null]},s.id)})})}function ee({rows:e,cursor:r,focused:t}){if(e.length===0)return a(o,{dimColor:!0,children:"no live processes"});let n=Date.now();return a(i,{flexDirection:"column",children:e.slice(0,12).map((s,u)=>{let p=I(t,u===r),y=Math.max(0,Math.round((n-(s.lastTurnAt||s.spawnedAt))/1e3)),f=s.state==="dead"?"red":s.state==="warm-hot"?"green":"yellow";return c(i,{children:[a(o,{...p,color:f,children:T(s.state,10)}),a(o,{...p,children:T(s.key.agentId,12)}),a(o,{...p,children:T(s.key.channel,10)}),c(o,{...p,children:[s.turnCount,"t ",y,"s"]})]},`${s.key.agentId}-${s.key.channel}-${s.key.chatId}-${u}`)})})}function te({rows:e}){return e.length===0?a(o,{dimColor:!0,children:"no crons"}):a(i,{flexDirection:"column",children:e.slice(0,12).map(r=>{let t=r.enabled?r.consecutiveErrors>0?a(o,{color:"red",children:"err"}):a(o,{color:"green",children:"ok"}):a(o,{dimColor:!0,children:"off"}),n=r.nextRun?new Date(r.nextRun).toLocaleTimeString():"\u2014";return c(i,{children:[a(o,{children:T(r.id,16)}),a(o,{dimColor:!0,children:T(r.schedule,12)}),a(o,{children:T(n,10)}),a(i,{children:t})]},r.id)})})}function re({rows:e}){if(e.length===0)return a(o,{dimColor:!0,children:"(waiting for channel events\u2026)"});let r=[...e].sort((t,n)=>n.lastAt-t.lastAt);return a(i,{flexDirection:"column",children:r.slice(0,12).map(t=>c(i,{children:[a(o,{children:T(t.channel,12)}),c(o,{color:"cyan",children:["\u2190",T(String(t.inbound),4)]}),c(o,{color:"magenta",children:["\u2192",T(String(t.outbound),4)]}),a(o,{dimColor:!0,children:t.lastPreview})]},t.channel))})}function ne({rows:e,cursor:r,focused:t}){return e.length===0?a(o,{dimColor:!0,children:"(waiting for events\u2026)"}):a(i,{flexDirection:"column",children:e.slice(0,18).map((n,s)=>{let u=I(t,s===r);return c(i,{children:[a(o,{...u,dimColor:!0,children:new Date(n.at).toLocaleTimeString().padEnd(10)}),a(o,{...u,color:ce(n.kind),children:T(n.kind,8)}),a(o,{...u,children:n.line})]},`${n.at}-${s}`)})})}function oe({chat:e,suggest:r,agents:t}){let n=e.history.slice(-14),s=t.find(f=>f.id===e.agentId),u=H(s?.tier??"",s?.model),p=e.status==="sending"?[...e.history].reverse().find(f=>f.role==="agent"&&f.streaming):void 0,y=e.status==="sending"?a(O,{startedAt:p?.at??Date.now(),phase:p?.text?"responding":"thinking",indent:""}):e.error?c(o,{color:"red",children:["\u25CF ",e.error]}):a(o,{dimColor:!0,children:"\u25CF ready"});return c(i,{flexDirection:"column",width:"50%",borderStyle:"double",borderColor:"green",paddingX:1,children:[c(i,{justifyContent:"space-between",children:[c(o,{bold:!0,color:"green",children:["CHAT \xB7 @",e.agentId]}),a(i,{children:y})]}),c(o,{children:[c(o,{color:u.color,bold:!0,children:[u.glyph," ",u.label]}),s?.model?c(o,{dimColor:!0,children:[" ",j(s.model)]}):null,c(o,{dimColor:!0,children:[" \xB7 ",e.chatId]})]}),a(i,{flexDirection:"column",flexGrow:1,marginTop:1,children:n.length===0?a(o,{dimColor:!0,children:"(type a message and press Enter \u2014 Esc exits, Ctrl-L starts fresh)"}):n.map((f,l)=>a(se,{turn:f,agentId:e.agentId},`${f.at}-${l}`))}),r?c(o,{dimColor:!0,children:[a(o,{color:"cyan",children:"\u21B9"})," ",r.items.slice(0,5).map((f,l)=>l===0?a(o,{color:"cyan",children:f},l):c(o,{children:[" ",f]},l))]}):null,c(i,{children:[a(o,{color:"cyan",children:"you \u203A "}),a(o,{children:e.text}),a(o,{inverse:!0,children:" "})]})]})}function se({turn:e,agentId:r}){if(e.role==="you")return c(i,{flexDirection:"column",marginBottom:1,children:[a(o,{color:"cyan",children:"you"}),e.text.split(`
5
5
  `).map((s,u)=>c(o,{children:[" ",s]},u))]});if(e.role==="error")return c(i,{flexDirection:"column",marginBottom:1,children:[a(o,{color:"red",children:"error"}),c(o,{color:"red",children:[" ",e.text]})]});let t=e.elapsedMs!=null?` \xB7 ${(e.elapsedMs/1e3).toFixed(1)}s${e.outTokens!=null?`, ${e.outTokens} tok`:""}`:e.streaming?" \xB7 \u2026":"",n=F(e.text,58,{balance:e.streaming});return c(i,{flexDirection:"column",marginBottom:1,children:[c(o,{color:"green",children:["@",r??"agent",a(o,{dimColor:!0,children:t})]}),e.thinking?e.thinking.split(`
6
6
  `).filter(s=>s.trim()).slice(-2).map((s,u)=>c(o,{dimColor:!0,italic:!0,children:[" ",s]},`th${u}`)):null,(e.tools??[]).map((s,u)=>c(o,{color:s.error?"red":"green",children:[" \u25CF ",c(o,{bold:!s.error,dimColor:s.error,children:[s.name,s.arg?c(o,{dimColor:!0,children:["(",s.arg,")"]}):null,s.error?" failed":""]})]},`tool${u}`)),n.split(`
7
7
  `).slice(0,14).map((s,u)=>c(o,{children:[" ",s]},u))]})}function ae(e){let r=e.data??{},t=typeof r.at=="string"||typeof r.at=="number"?new Date(r.at).getTime():Date.now(),n="";switch(e.event){case"run":n=`${r.phase??""} ${r.workflowId??""} ${(r.runId??"").slice(0,8)} ${r.nodeId??""}`.trim();break;case"task":n=`${r.phase??""} ${r.workflowId??""} ${Array.isArray(r.assignedTo)?r.assignedTo.join(","):""} ${r.title?`"${r.title}"`:""}`.trim();break;case"signal":n=`${r.name??""} (${r.scope??""}) ${r.workflowId??""}`.trim();break;case"mesh":n=`${r.peer??""} ${r.healthy?"healthy":"lost"} ${r.delta??""}`.trim();break;case"channel":{n=`${r.direction==="in"?"\u2190":"\u2192"} ${r.channel??""}:${r.chatId??""} ${r.textPreview??""}`.trim();break}case"status":n=`node=${r.node??""} agents=${r.agents??0} active=${(r.active??[]).length}`;break;default:n=typeof r=="string"?r:JSON.stringify(r).slice(0,80)}return{at:Number.isFinite(t)?t:Date.now(),kind:e.event,line:n}}function ce(e){switch(e){case"run":return"cyan";case"task":return"magenta";case"signal":return"green";case"mesh":return"blue";case"channel":return"yellow";default:return"white"}}function T(e,r){let t=(e??"").toString();return t.length>=r?t.slice(0,r-1)+" ":t+" ".repeat(r-t.length)}export{be as App};
8
- //# sourceMappingURL=App-EYUDDF6K.js.map
8
+ //# sourceMappingURL=App-A7WZMOGA.js.map
@@ -1,7 +1,7 @@
1
- import{a as Y,b as Z,c as _,d as ee,e as te,f as ne,g as re}from"./chunk-U2CKL755.js";import{b as Q,g as X}from"./chunk-PYCTWI2I.js";import"./chunk-ECM2QEXF.js";import"./chunk-RJ7DASOU.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";import{useCallback as oe,useMemo as H,useRef as P,useState as k}from"react";import{Box as g,Text as t,useApp as he,useInput as xe,useStdout as Te}from"ink";import{randomUUID as se}from"crypto";var m={accent:"cyan",agent:"green",working:"magenta",error:"red",muted:"gray"},q="\u25C7 agentx",F="\u258C";import{jsx as c,jsxs as o}from"react/jsx-runtime";var ie="/help /agent <id> /agents /clear /who /exit",be=[{cmd:"/agent",desc:"switch the target agent (/agent <id>)"},{cmd:"/agents",desc:"list registered agents"},{cmd:"/clear",desc:"start a fresh session"},{cmd:"/who",desc:"show agent + chat id"},{cmd:"/help",desc:"list commands"},{cmd:"/exit",desc:"quit the chat"}];function Pe({conn:n,agentId:p,channel:f,chatId:a,agents:h}){let{exit:w}=he(),{stdout:O}=Te(),V=Math.max(40,Math.min((O?.columns||80)-4,100)),[z,U]=k([]),[$,S]=k(null),[T,le]=k(p),[A,ae]=k(h),[E,ue]=k(a),[y,x]=k(""),[J,de]=k(""),W=P([]),u=P(-1),M=P(null),R=P(null),v=$?.live??!1,j=H(()=>Z(y,A.map(s=>s.id),process.cwd()),[y,A]),N=H(()=>{let s=/^\/(\w*)$/.exec(y);if(!s)return null;let e=be.filter(r=>r.cmd.slice(1).startsWith(s[1].toLowerCase()));return e.length?e:null},[y]),b=s=>de(s),K=oe(s=>{let e=se().slice(0,8),r=Date.now(),i=new AbortController;R.current=i;let d={id:e,you:s,agentId:T,segs:[],live:!0,startedAt:r};S({...d});let L=()=>S({...d,segs:d.segs.map(C=>({...C}))});(async()=>{try{let C=await X(n,T,s,{channel:f,chatId:E,signal:i.signal,onText:l=>{let I=d.segs[d.segs.length-1];I&&I.type==="text"?I.content=(I.content??"")+l:d.segs.push({type:"text",content:l}),L()},onThinking:l=>{d.thinking=(d.thinking??"")+l,L()},onTool:l=>{l.status==="start"&&l.name?(d.segs.push({type:"tool",name:l.name,arg:l.arg}),L()):l.status==="result"&&l.error&&(d.segs.push({type:"tool",name:l.name??"tool",error:!0}),L())}});U(l=>[...l,{...d,live:!1,elapsedMs:Date.now()-r,outTokens:C.usage?.outputTokens,error:C.error}]),S(null)}catch(C){let l=i.signal.aborted||C?.name==="AbortError";U(I=>[...I,{...d,live:!1,elapsedMs:Date.now()-r,interrupted:l,error:l?void 0:C?.message||String(C)}]),S(null)}finally{R.current===i&&(R.current=null)}})()},[n,T,f,E]),me=oe(s=>{let e=s.trim();if(e){if(W.current.push(e),u.current=-1,e==="/exit"||e==="/quit"){w();return}if(e==="/help"){b(ie);return}if(e==="/who"){b(`@${T} \xB7 chatId=${E} \xB7 channel=${f}`);return}if(e==="/clear"){let r=`chat-cli:${se().slice(0,12)}`;ue(r),U([]),b(`fresh chatId=${r} (warm process dropped)`);return}if(e==="/agents"){Q(n).then(r=>{ae(r),b(r.map(i=>i.id===T?`[${i.id}]`:i.id).join(" "))}).catch(r=>b(`failed to list agents: ${r?.message||r}`));return}if(e.startsWith("/agent ")){let r=e.slice(7).replace(/^@/,"").trim();if(!r){b("usage: /agent <id>");return}if(!A.find(i=>i.id===r)){b(`unknown agent: @${r}`);return}le(r),b(`now talking to @${r}`);return}if(e.startsWith("/")){b(`unknown command \xB7 ${ie}`);return}K(e)}},[n,T,A,f,E,w,K]);xe((s,e)=>{if(e.ctrl&&s==="c"){w();return}if(e.escape){if(v&&R.current){R.current.abort();return}w();return}if(e.tab){if(N){x(N[0].cmd+" ");return}let i=_(y,M,A.map(d=>d.id),process.cwd());i!==null&&(x(i),u.current=-1);return}if(e.upArrow){let i=W.current;if(!i.length)return;u.current=u.current<0?i.length-1:Math.max(0,u.current-1),x(i[u.current]??"");return}if(e.downArrow){let i=W.current;if(u.current<0)return;if(u.current=u.current+1,u.current>=i.length){u.current=-1,x("");return}x(i[u.current]??"");return}if(e.backspace||e.delete){M.current=null,x(i=>i.slice(0,-1));return}if(e.ctrl||e.meta)return;let r=ee(s??"",e.return,y);switch(r.kind){case"paste":M.current=null,x(i=>i+r.text),u.current=-1;return;case"type":M.current=null,x(i=>i+r.text),u.current=-1;return;case"continue":x(r.buffer);return;case"submit":if(v)return;M.current=null,x(""),me(r.text);return;case"none":return}});let G=v?m.working:m.accent,ge=y.length?y.split(`
1
+ import{a as Y,b as Z,c as _,d as ee,e as te,f as ne,g as re}from"./chunk-U2CKL755.js";import{b as Q,g as X}from"./chunk-CUS7WGZT.js";import"./chunk-IA3BC7M3.js";import"./chunk-RJ7DASOU.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";import{useCallback as oe,useMemo as H,useRef as P,useState as k}from"react";import{Box as g,Text as t,useApp as he,useInput as xe,useStdout as Te}from"ink";import{randomUUID as se}from"crypto";var m={accent:"cyan",agent:"green",working:"magenta",error:"red",muted:"gray"},q="\u25C7 agentx",F="\u258C";import{jsx as c,jsxs as o}from"react/jsx-runtime";var ie="/help /agent <id> /agents /clear /who /exit",be=[{cmd:"/agent",desc:"switch the target agent (/agent <id>)"},{cmd:"/agents",desc:"list registered agents"},{cmd:"/clear",desc:"start a fresh session"},{cmd:"/who",desc:"show agent + chat id"},{cmd:"/help",desc:"list commands"},{cmd:"/exit",desc:"quit the chat"}];function Pe({conn:n,agentId:p,channel:f,chatId:a,agents:h}){let{exit:w}=he(),{stdout:O}=Te(),V=Math.max(40,Math.min((O?.columns||80)-4,100)),[z,U]=k([]),[$,S]=k(null),[T,le]=k(p),[A,ae]=k(h),[E,ue]=k(a),[y,x]=k(""),[J,de]=k(""),W=P([]),u=P(-1),M=P(null),R=P(null),v=$?.live??!1,j=H(()=>Z(y,A.map(s=>s.id),process.cwd()),[y,A]),N=H(()=>{let s=/^\/(\w*)$/.exec(y);if(!s)return null;let e=be.filter(r=>r.cmd.slice(1).startsWith(s[1].toLowerCase()));return e.length?e:null},[y]),b=s=>de(s),K=oe(s=>{let e=se().slice(0,8),r=Date.now(),i=new AbortController;R.current=i;let d={id:e,you:s,agentId:T,segs:[],live:!0,startedAt:r};S({...d});let L=()=>S({...d,segs:d.segs.map(C=>({...C}))});(async()=>{try{let C=await X(n,T,s,{channel:f,chatId:E,signal:i.signal,onText:l=>{let I=d.segs[d.segs.length-1];I&&I.type==="text"?I.content=(I.content??"")+l:d.segs.push({type:"text",content:l}),L()},onThinking:l=>{d.thinking=(d.thinking??"")+l,L()},onTool:l=>{l.status==="start"&&l.name?(d.segs.push({type:"tool",name:l.name,arg:l.arg}),L()):l.status==="result"&&l.error&&(d.segs.push({type:"tool",name:l.name??"tool",error:!0}),L())}});U(l=>[...l,{...d,live:!1,elapsedMs:Date.now()-r,outTokens:C.usage?.outputTokens,error:C.error}]),S(null)}catch(C){let l=i.signal.aborted||C?.name==="AbortError";U(I=>[...I,{...d,live:!1,elapsedMs:Date.now()-r,interrupted:l,error:l?void 0:C?.message||String(C)}]),S(null)}finally{R.current===i&&(R.current=null)}})()},[n,T,f,E]),me=oe(s=>{let e=s.trim();if(e){if(W.current.push(e),u.current=-1,e==="/exit"||e==="/quit"){w();return}if(e==="/help"){b(ie);return}if(e==="/who"){b(`@${T} \xB7 chatId=${E} \xB7 channel=${f}`);return}if(e==="/clear"){let r=`chat-cli:${se().slice(0,12)}`;ue(r),U([]),b(`fresh chatId=${r} (warm process dropped)`);return}if(e==="/agents"){Q(n).then(r=>{ae(r),b(r.map(i=>i.id===T?`[${i.id}]`:i.id).join(" "))}).catch(r=>b(`failed to list agents: ${r?.message||r}`));return}if(e.startsWith("/agent ")){let r=e.slice(7).replace(/^@/,"").trim();if(!r){b("usage: /agent <id>");return}if(!A.find(i=>i.id===r)){b(`unknown agent: @${r}`);return}le(r),b(`now talking to @${r}`);return}if(e.startsWith("/")){b(`unknown command \xB7 ${ie}`);return}K(e)}},[n,T,A,f,E,w,K]);xe((s,e)=>{if(e.ctrl&&s==="c"){w();return}if(e.escape){if(v&&R.current){R.current.abort();return}w();return}if(e.tab){if(N){x(N[0].cmd+" ");return}let i=_(y,M,A.map(d=>d.id),process.cwd());i!==null&&(x(i),u.current=-1);return}if(e.upArrow){let i=W.current;if(!i.length)return;u.current=u.current<0?i.length-1:Math.max(0,u.current-1),x(i[u.current]??"");return}if(e.downArrow){let i=W.current;if(u.current<0)return;if(u.current=u.current+1,u.current>=i.length){u.current=-1,x("");return}x(i[u.current]??"");return}if(e.backspace||e.delete){M.current=null,x(i=>i.slice(0,-1));return}if(e.ctrl||e.meta)return;let r=ee(s??"",e.return,y);switch(r.kind){case"paste":M.current=null,x(i=>i+r.text),u.current=-1;return;case"type":M.current=null,x(i=>i+r.text),u.current=-1;return;case"continue":x(r.buffer);return;case"submit":if(v)return;M.current=null,x(""),me(r.text);return;case"none":return}});let G=v?m.working:m.accent,ge=y.length?y.split(`
2
2
  `):[""],B=A.find(s=>s.id===T),D=ne(B?.tier??"",B?.model),pe=O?.rows||24,fe=z.slice(-40);return o(g,{flexDirection:"column",height:pe,children:[o(g,{flexDirection:"column",flexGrow:1,justifyContent:"flex-end",overflow:"hidden",children:[z.length===0&&!$?o(g,{flexDirection:"column",children:[o(t,{children:[c(t,{color:m.accent,bold:!0,children:q}),c(t,{dimColor:!0,children:" \u2014 chat with "}),o(t,{color:m.accent,children:["@",T]}),c(t,{dimColor:!0,children:" via "}),o(t,{color:D.color,bold:!0,children:[D.glyph," ",D.label]}),B?.model?o(t,{dimColor:!0,children:[" (",B.model,")"]}):null]}),c(t,{dimColor:!0,children:"streaming \xB7 markdown \xB7 tools \xB7 type a message, or / for commands"})]}):null,fe.map(s=>c(ce,{turn:s,width:V},s.id)),$?c(ce,{turn:$,width:V}):null]}),N?c(g,{flexDirection:"column",marginTop:1,children:N.map((s,e)=>o(g,{children:[c(t,{color:e===0?m.accent:m.muted,bold:e===0,children:s.cmd.padEnd(10)}),c(t,{dimColor:!0,children:s.desc})]},s.cmd))}):j?o(g,{marginTop:1,children:[c(t,{color:m.accent,children:"\u21B9 "}),j.items.map((s,e)=>o(t,{color:e===0?m.accent:m.muted,children:[s,e<j.items.length-1?" ":""]},e))]}):J?c(g,{marginTop:1,children:c(t,{dimColor:!0,children:J})}):null,c(g,{borderStyle:"single",borderColor:G,borderLeft:!1,borderRight:!1,borderDimColor:!v,width:"100%",children:c(g,{flexDirection:"column",width:"100%",children:ge.map((s,e,r)=>o(g,{children:[c(t,{color:G,bold:!0,children:e===0?"\u203A ":" "}),c(t,{children:s}),e===r.length-1&&!v?c(t,{color:G,children:"\u258F"}):null]},e))})}),o(g,{justifyContent:"space-between",children:[o(t,{children:[c(t,{color:m.accent,bold:!0,children:q}),o(t,{dimColor:!0,children:[" \xB7 @",T," \xB7 "]}),o(t,{color:D.color,bold:!0,children:[D.glyph," ",D.label]}),B?.model?o(t,{dimColor:!0,children:[" ",re(B.model)]}):null]}),o(t,{dimColor:!0,children:["\u21B5 send / cmds @ mention esc ",v?"stop":"exit"]})]})]})}function ce({turn:n,width:p}){let f=H(()=>ye(n,p),[n,p]),a=n.segs.some(h=>h.type==="text"&&h.content);return o(g,{flexDirection:"column",marginBottom:1,children:[o(t,{color:m.accent,bold:!0,children:[F," you"]}),n.you.split(`
3
3
  `).map((h,w)=>o(t,{color:"white",children:[" ",h]},`u${w}`)),o(t,{color:m.agent,bold:!0,children:[F," ",n.agentId??"agent"]}),n.thinking?c(g,{flexDirection:"column",children:we(n.thinking,n.live?3:2).map((h,w)=>o(t,{dimColor:!0,italic:!0,children:[" ",h]},`th${w}`))}):null,f,n.live?c(te,{startedAt:n.startedAt,phase:a?"responding":"thinking",hint:"esc to interrupt"}):n.interrupted?o(t,{dimColor:!0,children:[" \u2298 interrupted \xB7 ",(n.elapsedMs/1e3).toFixed(1),"s"]}):n.error?o(t,{color:"red",children:[" \u2717 ",n.error]}):n.elapsedMs!=null?o(t,{dimColor:!0,children:[" \xB7 ",(n.elapsedMs/1e3).toFixed(1),"s",n.outTokens!=null?`, ${n.outTokens} tok`:""]}):null]})}function we(n,p){return n.split(`
4
4
  `).filter(a=>a.trim()).slice(-p)}function ye(n,p){let f=[];return n.segs.forEach((a,h)=>{a.type==="tool"?f.push(o(t,{color:a.error?"red":"green",children:[" ","\u25CF ",o(t,{bold:!a.error,dimColor:a.error,children:[a.name,a.arg?o(t,{dimColor:!0,children:["(",a.arg,")"]}):null,a.error?" failed":""]})]},h)):a.content&&f.push(c(t,{children:Ce(Y(a.content,p,{balance:n.live}))},h))}),f}function Ce(n){return n.split(`
5
5
  `).map(p=>p.length?" "+p:p).join(`
6
6
  `)}export{Pe as ChatApp};
7
- //# sourceMappingURL=ChatApp-F5LZLBI3.js.map
7
+ //# sourceMappingURL=ChatApp-EWNT36ZE.js.map
@@ -1,2 +1,2 @@
1
- import{A as a,B as b,C as c}from"./chunk-HMDM5MCR.js";import"./chunk-SFQUP3BP.js";import"./chunk-QOYAX2FT.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-JHCI6XCJ.js";import"./chunk-DSYKYZMT.js";import"./chunk-QIJLFPWE.js";export{a as createAgentContext,b as generate,c as generateStream};
2
- //# sourceMappingURL=agent-XF3BWMOB.js.map
1
+ import{A as a,B as b,C as c}from"./chunk-HVPRCHRG.js";import"./chunk-SFQUP3BP.js";import"./chunk-QOYAX2FT.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-JHCI6XCJ.js";import"./chunk-DSYKYZMT.js";import"./chunk-QIJLFPWE.js";export{a as createAgentContext,b as generate,c as generateStream};
2
+ //# sourceMappingURL=agent-MUGC4RZP.js.map