agentix-cli 0.97.0 → 0.98.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.
- package/apps/mac-voice/Sources/AgentXVoice/PlayActs.swift +35 -8
- package/apps/mac-voice/Sources/AgentXVoice/PlayMath.swift +17 -9
- package/apps/mac-voice/Sources/AgentXVoice/PlayMotion.swift +110 -0
- package/apps/mac-voice/Sources/AgentXVoice/PlayStage.swift +43 -5
- package/dist/{App-6R4I6QPE.js → App-XLQDP26J.js} +2 -2
- package/dist/{ChatApp-R3O4BJ24.js → ChatApp-DRDUXZ66.js} +2 -2
- package/dist/{agent-P6GPE7HD.js → agent-QHM3J2XS.js} +2 -2
- package/dist/{board-dashboard-AKQHIY4J.js → board-dashboard-AIT26JTK.js} +4 -4
- package/dist/{chunk-QPIMPKZ2.js → chunk-4BCAH7XI.js} +2 -2
- package/dist/{chunk-3S4IYAOC.js → chunk-B32A6OOY.js} +2 -2
- package/dist/{chunk-QHAO6U7U.js → chunk-BERHVF3T.js} +2 -2
- package/dist/{chunk-TWC4CYTU.js → chunk-BHKWXFJD.js} +5 -5
- package/dist/{chunk-Q53XKCRL.js → chunk-BTLW2RML.js} +2 -2
- package/dist/{chunk-55HM3SUN.js → chunk-DRUEPGLP.js} +2 -2
- package/dist/{chunk-SZ5TGL25.js → chunk-DXJRMPGH.js} +2 -2
- package/dist/{chunk-ZCQCUA4J.js → chunk-GJ5EJVMZ.js} +2 -2
- package/dist/{chunk-2GFSHO24.js → chunk-IQJ7UZVV.js} +2 -2
- package/dist/{chunk-6W3SCPDK.js → chunk-J4JVKVEK.js} +2 -2
- package/dist/{chunk-MDFUSQ6S.js → chunk-J64VIHL5.js} +2 -2
- package/dist/{chunk-ERPEU2ZR.js → chunk-JREA25GJ.js} +3 -3
- package/dist/chunk-JREA25GJ.js.map +1 -0
- package/dist/{chunk-WLKO6FOL.js → chunk-JZJ7AZJD.js} +2 -2
- package/dist/{chunk-4BG3WJSP.js → chunk-LXJGLNVG.js} +2 -2
- package/dist/{chunk-LXHTVVJV.js → chunk-OFVMUBIP.js} +2 -2
- package/dist/{chunk-TOGRRWBX.js → chunk-QUU5RJ7D.js} +2 -2
- package/dist/{chunk-F3DW5ZJN.js → chunk-S2GPUSBU.js} +2 -2
- package/dist/{chunk-C2POHIWJ.js → chunk-SJMOZY7Y.js} +2 -2
- package/dist/{chunk-3SF7PLHF.js → chunk-WWCVQHV3.js} +6 -6
- package/dist/{chunk-3SF7PLHF.js.map → chunk-WWCVQHV3.js.map} +1 -1
- package/dist/{chunk-X4S2I233.js → chunk-YYCFI4VP.js} +2 -2
- package/dist/{chunk-DGVTRG5Q.js → chunk-Z4FY64BS.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/{client-UQKCIEHA.js → client-BLUCLNIS.js} +2 -2
- package/dist/{config-OE23UC5C.js → config-ZUMI4IY4.js} +2 -2
- package/dist/config-mutator-S3CD2IWQ.js +2 -0
- package/dist/{doctor-QQ7YLJK4.js → doctor-XGQW5SMD.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{program-O5RQ6NRG.js → program-FK7REU2M.js} +14 -14
- package/dist/{promote-AW4TJXXT.js → promote-K5LP5Q6Z.js} +2 -2
- package/dist/{query-24BGIJCZ.js → query-LHXSINM2.js} +2 -2
- package/dist/{registry-GZT2OSBK.js → registry-OQUO6NCW.js} +2 -2
- package/dist/{request-planner-U6HHKWLX.js → request-planner-TW5OCKTF.js} +2 -2
- package/dist/{review-candidates-LJUJCVFA.js → review-candidates-EFELFOSY.js} +2 -2
- package/dist/{routing-WCYPBKFH.js → routing-TSRZLD7B.js} +2 -2
- package/dist/schedule-tool-JUHRVU5D.js +2 -0
- package/dist/scheduler-EHJPTULN.js +2 -0
- package/dist/{seat-5PBTFTGS.js → seat-NIPWHLKC.js} +2 -2
- package/dist/{select-JD7MSY25.js → select-UAKDLN76.js} +2 -2
- package/dist/{set-enabled-MUSO2KJL.js → set-enabled-74DLXMSM.js} +2 -2
- package/dist/{tool-Y7SOGJ2S.js → tool-CEBL57UW.js} +2 -2
- package/dist/{tool-FMKGK474.js → tool-TEGHFORD.js} +2 -2
- package/dist/wiki-WOK4SCB7.js +2 -0
- package/package.json +1 -1
- package/dist/chunk-ERPEU2ZR.js.map +0 -1
- package/dist/config-mutator-2UK5GX4B.js +0 -2
- package/dist/schedule-tool-E7ER2XOI.js +0 -2
- package/dist/scheduler-FK3LOWU2.js +0 -2
- package/dist/wiki-SJRTAYMT.js +0 -2
- /package/dist/{App-6R4I6QPE.js.map → App-XLQDP26J.js.map} +0 -0
- /package/dist/{ChatApp-R3O4BJ24.js.map → ChatApp-DRDUXZ66.js.map} +0 -0
- /package/dist/{agent-P6GPE7HD.js.map → agent-QHM3J2XS.js.map} +0 -0
- /package/dist/{board-dashboard-AKQHIY4J.js.map → board-dashboard-AIT26JTK.js.map} +0 -0
- /package/dist/{chunk-QPIMPKZ2.js.map → chunk-4BCAH7XI.js.map} +0 -0
- /package/dist/{chunk-3S4IYAOC.js.map → chunk-B32A6OOY.js.map} +0 -0
- /package/dist/{chunk-QHAO6U7U.js.map → chunk-BERHVF3T.js.map} +0 -0
- /package/dist/{chunk-TWC4CYTU.js.map → chunk-BHKWXFJD.js.map} +0 -0
- /package/dist/{chunk-Q53XKCRL.js.map → chunk-BTLW2RML.js.map} +0 -0
- /package/dist/{chunk-55HM3SUN.js.map → chunk-DRUEPGLP.js.map} +0 -0
- /package/dist/{chunk-SZ5TGL25.js.map → chunk-DXJRMPGH.js.map} +0 -0
- /package/dist/{chunk-ZCQCUA4J.js.map → chunk-GJ5EJVMZ.js.map} +0 -0
- /package/dist/{chunk-2GFSHO24.js.map → chunk-IQJ7UZVV.js.map} +0 -0
- /package/dist/{chunk-6W3SCPDK.js.map → chunk-J4JVKVEK.js.map} +0 -0
- /package/dist/{chunk-MDFUSQ6S.js.map → chunk-J64VIHL5.js.map} +0 -0
- /package/dist/{chunk-WLKO6FOL.js.map → chunk-JZJ7AZJD.js.map} +0 -0
- /package/dist/{chunk-4BG3WJSP.js.map → chunk-LXJGLNVG.js.map} +0 -0
- /package/dist/{chunk-LXHTVVJV.js.map → chunk-OFVMUBIP.js.map} +0 -0
- /package/dist/{chunk-TOGRRWBX.js.map → chunk-QUU5RJ7D.js.map} +0 -0
- /package/dist/{chunk-F3DW5ZJN.js.map → chunk-S2GPUSBU.js.map} +0 -0
- /package/dist/{chunk-C2POHIWJ.js.map → chunk-SJMOZY7Y.js.map} +0 -0
- /package/dist/{chunk-X4S2I233.js.map → chunk-YYCFI4VP.js.map} +0 -0
- /package/dist/{chunk-DGVTRG5Q.js.map → chunk-Z4FY64BS.js.map} +0 -0
- /package/dist/{client-UQKCIEHA.js.map → client-BLUCLNIS.js.map} +0 -0
- /package/dist/{config-OE23UC5C.js.map → config-ZUMI4IY4.js.map} +0 -0
- /package/dist/{config-mutator-2UK5GX4B.js.map → config-mutator-S3CD2IWQ.js.map} +0 -0
- /package/dist/{doctor-QQ7YLJK4.js.map → doctor-XGQW5SMD.js.map} +0 -0
- /package/dist/{program-O5RQ6NRG.js.map → program-FK7REU2M.js.map} +0 -0
- /package/dist/{promote-AW4TJXXT.js.map → promote-K5LP5Q6Z.js.map} +0 -0
- /package/dist/{query-24BGIJCZ.js.map → query-LHXSINM2.js.map} +0 -0
- /package/dist/{registry-GZT2OSBK.js.map → registry-OQUO6NCW.js.map} +0 -0
- /package/dist/{request-planner-U6HHKWLX.js.map → request-planner-TW5OCKTF.js.map} +0 -0
- /package/dist/{review-candidates-LJUJCVFA.js.map → review-candidates-EFELFOSY.js.map} +0 -0
- /package/dist/{routing-WCYPBKFH.js.map → routing-TSRZLD7B.js.map} +0 -0
- /package/dist/{schedule-tool-E7ER2XOI.js.map → schedule-tool-JUHRVU5D.js.map} +0 -0
- /package/dist/{scheduler-FK3LOWU2.js.map → scheduler-EHJPTULN.js.map} +0 -0
- /package/dist/{seat-5PBTFTGS.js.map → seat-NIPWHLKC.js.map} +0 -0
- /package/dist/{select-JD7MSY25.js.map → select-UAKDLN76.js.map} +0 -0
- /package/dist/{set-enabled-MUSO2KJL.js.map → set-enabled-74DLXMSM.js.map} +0 -0
- /package/dist/{tool-Y7SOGJ2S.js.map → tool-CEBL57UW.js.map} +0 -0
- /package/dist/{tool-FMKGK474.js.map → tool-TEGHFORD.js.map} +0 -0
- /package/dist/{wiki-SJRTAYMT.js.map → wiki-WOK4SCB7.js.map} +0 -0
|
@@ -5,12 +5,23 @@ import Foundation
|
|
|
5
5
|
/// different play each time. Numbers only, like `PlayMath`.
|
|
6
6
|
extension PlayMath {
|
|
7
7
|
/// A piece cut out of the picture and drawn somewhere else: which
|
|
8
|
-
/// part of the picture, where its top-left corner is now,
|
|
9
|
-
///
|
|
8
|
+
/// part of the picture, where its top-left corner is now, how far it
|
|
9
|
+
/// has turned (radians), and the page's colour around it, which is
|
|
10
|
+
/// left out so only its ink moves.
|
|
10
11
|
struct Piece: Equatable {
|
|
11
12
|
var from: Rect
|
|
12
13
|
var at: Point
|
|
13
14
|
var turn = 0.0
|
|
15
|
+
var paper: UInt32 = 0xFFFFFF
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// How much of a pixel of a moved piece is drawn, 0…1: none of the
|
|
19
|
+
/// page's colour, all of the ink, and the soft edge of a letter in
|
|
20
|
+
/// between. Without it a flying letter carries a box of page with it
|
|
21
|
+
/// and covers the text it passes.
|
|
22
|
+
static func ink(r: UInt8, g: UInt8, b: UInt8, paper: UInt32) -> Double {
|
|
23
|
+
let far = max(abs(Int(r) - Int(paper >> 16 & 0xFF)), abs(Int(g) - Int(paper >> 8 & 0xFF)), abs(Int(b) - Int(paper & 0xFF)))
|
|
24
|
+
return min(max(Double(far - 10) / 40, 0), 1)
|
|
14
25
|
}
|
|
15
26
|
|
|
16
27
|
/// A piece from the moment it leaves its place. Its place is covered
|
|
@@ -36,18 +47,22 @@ extension PlayMath {
|
|
|
36
47
|
static let gravity = 1400.0
|
|
37
48
|
static let lift = 0.35
|
|
38
49
|
|
|
39
|
-
/// Where a thrown piece is `seconds` after it left. It
|
|
40
|
-
/// bottom of the picture and at its sides.
|
|
50
|
+
/// Where a thrown piece is `seconds` after it left. It bounces once
|
|
51
|
+
/// on the bottom of the picture and lies still, and stops at its sides.
|
|
41
52
|
static func thrown(_ source: Rect, v: Point, spin: Double, rise: Double, after seconds: Double,
|
|
42
53
|
width: Double, height: Double) -> Piece {
|
|
43
54
|
let floor = max(height - source.h - rise, source.y)
|
|
44
55
|
let landing = (-v.y + (v.y * v.y + 2 * gravity * (floor - source.y)).squareRoot()) / gravity
|
|
45
56
|
let s = min(max(seconds, 0), landing)
|
|
46
|
-
|
|
57
|
+
// How fast it comes down, and the bounce that makes: a third as
|
|
58
|
+
// fast, sideways too.
|
|
59
|
+
let hit = v.y + gravity * landing
|
|
60
|
+
let more = min(max(seconds - landing, 0), PlayMotion.bounceTime(speed: hit, gravity: gravity))
|
|
61
|
+
let x = min(max(source.x + v.x * (s + more / 3), 0), max(width - source.w, 0))
|
|
47
62
|
// It turns about as fast as `spin`, and lands flat: the right way
|
|
48
63
|
// up or upside down.
|
|
49
64
|
let flat = (spin * landing / .pi).rounded() * .pi
|
|
50
|
-
return Piece(from: source, at: Point(x: x, y: source.y + v.y * s + gravity * s * s / 2), turn: landing > 0 ? flat * s / landing : 0)
|
|
65
|
+
return Piece(from: source, at: Point(x: x, y: source.y + v.y * s + gravity * s * s / 2 - PlayMotion.bounce(more, speed: hit, gravity: gravity)), turn: landing > 0 ? flat * s / landing : 0)
|
|
51
66
|
}
|
|
52
67
|
|
|
53
68
|
/// What it can do to a line.
|
|
@@ -107,17 +122,29 @@ extension Play {
|
|
|
107
122
|
f.gone.append((cover(cut.source), cut.paper))
|
|
108
123
|
switch cut.path {
|
|
109
124
|
case .thrown(let v, let spin, let rise):
|
|
110
|
-
|
|
125
|
+
var piece = P.thrown(cut.source, v: v, spin: spin, rise: rise, after: f.t - cut.start, width: size.x, height: size.y)
|
|
126
|
+
piece.paper = cut.paper
|
|
127
|
+
f.pieces.append(piece)
|
|
111
128
|
case .held(let until, let to):
|
|
112
129
|
// From its place to above the head, and from there down.
|
|
113
130
|
let head = P.Point(x: f.at.x - cut.source.w / 2, y: f.at.y - P.top - cut.source.h)
|
|
114
131
|
let a = f.t < until ? P.Point(x: cut.source.x, y: cut.source.y) : head, b = f.t < until ? head : to
|
|
115
132
|
let q = M.ease(f.t < until ? M.span(f.t, cut.start, cut.start + P.lift) : M.span(f.t, until, until + P.lift))
|
|
116
|
-
f.pieces.append(P.Piece(from: cut.source, at: P.Point(x: a.x + (b.x - a.x) * q, y: a.y + (b.y - a.y) * q)))
|
|
133
|
+
f.pieces.append(P.Piece(from: cut.source, at: P.Point(x: a.x + (b.x - a.x) * q, y: a.y + (b.y - a.y) * q), paper: cut.paper))
|
|
117
134
|
}
|
|
118
135
|
}
|
|
119
136
|
}
|
|
120
137
|
|
|
138
|
+
/// How far along a move it is: a jump crouches first and lands at the
|
|
139
|
+
/// end, a walk and a wipe start and stop, the rest keep one pace.
|
|
140
|
+
func body(_ m: Move, at t: Double) -> PlayMotion.Body {
|
|
141
|
+
switch m.kind {
|
|
142
|
+
case .jump, .carry: return PlayMotion.jump(t - m.start, of: m.duration)
|
|
143
|
+
case .walk, .wipe: return PlayMotion.glide(t - m.start, of: m.duration)
|
|
144
|
+
default: return PlayMotion.Body(travel: M.span(t, m.start, m.end))
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
121
148
|
/// Which way it faces during a move, and its pose without the motion.
|
|
122
149
|
func look(_ m: Move) -> (face: Double, pose: M.Pose) {
|
|
123
150
|
let way: Double = m.to.x >= m.from.x ? 1 : -1
|
|
@@ -90,6 +90,7 @@ enum PlayMath {
|
|
|
90
90
|
struct Play {
|
|
91
91
|
typealias P = PlayMath
|
|
92
92
|
typealias M = CharacterMath
|
|
93
|
+
typealias Mo = PlayMotion
|
|
93
94
|
|
|
94
95
|
enum Kind { case jump, walk, eat, wipe, kick, stomp, fall, lift, carry, drop, rest }
|
|
95
96
|
|
|
@@ -131,13 +132,16 @@ struct Play {
|
|
|
131
132
|
self.lines = lines
|
|
132
133
|
self.size = size
|
|
133
134
|
var at = start, now = 0.0
|
|
135
|
+
/// The seconds of a jump over `points`: its crouch, its time in
|
|
136
|
+
/// the air and its landing.
|
|
137
|
+
func leap(_ points: Double) -> Double { Mo.crouch + 0.34 + points / 900 + Mo.landing }
|
|
134
138
|
func add(_ kind: Kind, to: P.Point, _ seconds: Double, line: Int = 0, words: Range<Int> = 0..<0) -> Move {
|
|
135
139
|
Move(kind: kind, from: at, to: to, start: now, duration: seconds, line: line, words: words)
|
|
136
140
|
}
|
|
137
141
|
/// Get to `to` first: a jump, unless it is already there.
|
|
138
142
|
func reach(_ to: P.Point, into list: inout [Move]) {
|
|
139
143
|
guard at != to else { return }
|
|
140
|
-
let m = add(.jump, to: to,
|
|
144
|
+
let m = add(.jump, to: to, leap(hypot(to.x - at.x, to.y - at.y)))
|
|
141
145
|
list.append(m); at = to; now = m.end
|
|
142
146
|
}
|
|
143
147
|
var list: [Move] = [], cuts: [P.Cut] = []
|
|
@@ -183,8 +187,10 @@ struct Play {
|
|
|
183
187
|
let word = lines[i].words[w]
|
|
184
188
|
reach(P.Point(x: word.rect.x - P.mouth - 4, y: lines[i].rect.midY + P.middle), into: &list)
|
|
185
189
|
let m = stay(.kick, 0.6, line: i)
|
|
186
|
-
|
|
187
|
-
|
|
190
|
+
// The letters leave one after the other, the nearest first.
|
|
191
|
+
let letters = P.letters(of: word)
|
|
192
|
+
for (k, letter) in letters.enumerated() {
|
|
193
|
+
throwing(letter, line: i, at: m.start + 0.25 + Mo.stagger(k, of: letters.count), v: P.Point(x: 150 + 40 * Double(k), y: -320 - 30 * Double(k % 3)),
|
|
188
194
|
spin: 4 + Double(k % 3))
|
|
189
195
|
}
|
|
190
196
|
case .stomp(let i):
|
|
@@ -207,7 +213,7 @@ struct Play {
|
|
|
207
213
|
let word = lines[i].words[w].rect, home = lines[j].rect
|
|
208
214
|
reach(P.Point(x: word.x - P.mouth - 4, y: lines[i].rect.midY + P.middle), into: &list)
|
|
209
215
|
let up = stay(.lift, P.lift, line: i)
|
|
210
|
-
let m = add(.carry, to: P.Point(x: home.maxX - 4, y: home.y),
|
|
216
|
+
let m = add(.carry, to: P.Point(x: home.maxX - 4, y: home.y), leap(hypot(home.maxX - 4 - at.x, home.y - at.y)), line: j)
|
|
211
217
|
list.append(m); at = m.to; now = m.end
|
|
212
218
|
let down = stay(.drop, P.lift, line: j)
|
|
213
219
|
// After the line, or on top of its end when the page stops there.
|
|
@@ -228,12 +234,13 @@ struct Play {
|
|
|
228
234
|
let m = moves[i], p = M.span(t, m.start, m.end)
|
|
229
235
|
var f = Frame(t: t, done: t >= duration)
|
|
230
236
|
|
|
231
|
-
|
|
237
|
+
let body = body(m, at: t)
|
|
238
|
+
f.at = P.Point(x: m.from.x + (m.to.x - m.from.x) * body.travel, y: m.from.y + (m.to.y - m.from.y) * body.travel)
|
|
232
239
|
switch m.kind {
|
|
233
240
|
case .jump, .carry:
|
|
234
241
|
// An arc over both ends, kept inside the picture.
|
|
235
242
|
let rise = 30 + hypot(m.to.x - m.from.x, m.to.y - m.from.y) * 0.12
|
|
236
|
-
f.at.y -= min(rise, max(min(m.from.y, m.to.y) - P.top, 0)) *
|
|
243
|
+
f.at.y -= min(rise, max(min(m.from.y, m.to.y) - P.top, 0)) * body.air
|
|
237
244
|
// Three hops on the spot.
|
|
238
245
|
case .stomp: f.at.y -= min(22, max(m.from.y - P.top, 0)) * abs(sin(3 * .pi * p))
|
|
239
246
|
// Faster and faster.
|
|
@@ -249,10 +256,11 @@ struct Play {
|
|
|
249
256
|
f.face = before.face + (now.face - before.face) * into
|
|
250
257
|
f.pose = M.blend(before.pose, now.pose, eyes: into, body: into, marks: into)
|
|
251
258
|
switch m.kind {
|
|
252
|
-
|
|
259
|
+
// A step every 50 points, smaller while it starts and stops.
|
|
260
|
+
case .walk: f.pose.lift += 3 * body.speed * abs(sin(.pi * abs(f.at.x - m.from.x) / 50))
|
|
253
261
|
case .jump, .carry:
|
|
254
|
-
|
|
255
|
-
f.pose.
|
|
262
|
+
f.pose.sy *= body.sy; f.pose.sx *= body.sx
|
|
263
|
+
f.pose.lift *= 1 - 0.5 * body.dip
|
|
256
264
|
case .eat:
|
|
257
265
|
let bite = into * (0.5 + 0.5 * sin(2 * .pi * t / P.perLetter))
|
|
258
266
|
f.pose.sy *= 1 - 0.08 * bite; f.pose.sx *= 1 + 0.05 * bite
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// How things move in play mode (#505), after the rules the videos are
|
|
4
|
+
/// made with: nothing starts or stops at full speed, a jump is announced
|
|
5
|
+
/// by a crouch and ends in a soft landing, letters leave one after the
|
|
6
|
+
/// other, and what falls bounces once before it lies still. Numbers only.
|
|
7
|
+
enum PlayMotion {
|
|
8
|
+
typealias M = CharacterMath
|
|
9
|
+
|
|
10
|
+
/// Fast start, slow stop; and slow start, fast end.
|
|
11
|
+
static func out(_ p: Double) -> Double { 1 - into(1 - p) }
|
|
12
|
+
static func into(_ p: Double) -> Double {
|
|
13
|
+
let p = min(max(p, 0), 1)
|
|
14
|
+
return p * p
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/// The body at one moment of a move: how far along its way (0…1),
|
|
18
|
+
/// how high in its arc (0…1), its stretch, how deep it sits on its
|
|
19
|
+
/// feet (0…1) and how fast it goes (0…1).
|
|
20
|
+
struct Body: Equatable {
|
|
21
|
+
var travel = 0.0, air = 0.0
|
|
22
|
+
var sx = 1.0, sy = 1.0
|
|
23
|
+
var dip = 0.0
|
|
24
|
+
var speed = 0.0
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// Seconds: the crouch before a jump, the landing after it, and the
|
|
28
|
+
/// start and the stop of a walk.
|
|
29
|
+
static let crouch = 0.16
|
|
30
|
+
static let landing = 0.26
|
|
31
|
+
static let walkUp = 0.2
|
|
32
|
+
static let walkDown = 0.26
|
|
33
|
+
/// How much taller the body is at full stretch, and how much shorter
|
|
34
|
+
/// at the deepest of a crouch and of a landing.
|
|
35
|
+
static let stretch = 0.14
|
|
36
|
+
static let squat = 0.16
|
|
37
|
+
static let squash = 0.2
|
|
38
|
+
|
|
39
|
+
/// A jump of `duration` seconds, `t` seconds in. It crouches first
|
|
40
|
+
/// and goes nowhere, leaves stretched, is round at the top, comes
|
|
41
|
+
/// down stretched, and lands: squashed, a little too tall once, then
|
|
42
|
+
/// still. It has arrived when the landing begins.
|
|
43
|
+
static func jump(_ t: Double, of duration: Double) -> Body {
|
|
44
|
+
guard duration > 0 else { return Body(travel: 1) }
|
|
45
|
+
let t = min(max(t, 0), duration)
|
|
46
|
+
let before = min(crouch, duration * 0.25), after = min(landing, duration * 0.3)
|
|
47
|
+
// A jump too short for a whole landing changes shape less, not faster.
|
|
48
|
+
let long = stretch * after / landing, flat = squash * after / landing
|
|
49
|
+
if t < before {
|
|
50
|
+
// Down slowly, up fast: the push.
|
|
51
|
+
let q = t / before
|
|
52
|
+
let deep = q < 0.65 ? out(q / 0.65) : 1 - into((q - 0.65) / 0.35)
|
|
53
|
+
return Body(sx: 1 + squat * 0.7 * deep, sy: 1 - squat * deep, dip: deep)
|
|
54
|
+
}
|
|
55
|
+
if t <= duration - after {
|
|
56
|
+
let u = M.span(t, before, duration - after)
|
|
57
|
+
// Stretched while it moves fast up or down, round at the top.
|
|
58
|
+
let more = long * abs(1 - 2 * u) * min(u / 0.12, 1)
|
|
59
|
+
return Body(travel: u, air: 4 * u * (1 - u), sx: 1 - more * 0.6, sy: 1 + more, speed: 1)
|
|
60
|
+
}
|
|
61
|
+
let more = keys([(0, long), (0.4, -flat), (0.72, 0.04), (1, 0)], at: (t - (duration - after)) / after)
|
|
62
|
+
return Body(travel: 1, sx: 1 - more * 0.6, sy: 1 + more, dip: max(-more / flat, 0))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// A walk, or a wipe, of `duration` seconds, `t` seconds in: it gets
|
|
66
|
+
/// up to speed, keeps it, and slows to a stop.
|
|
67
|
+
static func glide(_ t: Double, of duration: Double) -> Body {
|
|
68
|
+
guard duration > 0 else { return Body(travel: 1) }
|
|
69
|
+
let t = min(max(t, 0), duration)
|
|
70
|
+
let up = min(walkUp, duration / 3), down = min(walkDown, duration / 3)
|
|
71
|
+
// Full speed, in ways a second.
|
|
72
|
+
let top = 1 / (duration - up / 2 - down / 2)
|
|
73
|
+
if t < up { return Body(travel: top * t * t / (2 * up), speed: t / up) }
|
|
74
|
+
if t <= duration - down { return Body(travel: top * (t - up / 2), speed: 1) }
|
|
75
|
+
let left = duration - t
|
|
76
|
+
return Body(travel: 1 - top * left * left / (2 * down), speed: left / down)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// When the `k`th of `count` things starts after the first: one after
|
|
80
|
+
/// the other, and all gone within 0.4 seconds, so it reads as one go.
|
|
81
|
+
static func stagger(_ k: Int, of count: Int) -> Double {
|
|
82
|
+
guard count > 1 else { return 0 }
|
|
83
|
+
return Double(k) * min(0.035, 0.4 / Double(count - 1))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/// How high something is above where it landed, `seconds` after it
|
|
87
|
+
/// hit at `speed` (points a second) under `gravity`: one bounce, a
|
|
88
|
+
/// third as fast as it came down, then it lies still.
|
|
89
|
+
static func bounce(_ seconds: Double, speed: Double, gravity: Double) -> Double {
|
|
90
|
+
let up = abs(speed) / 3
|
|
91
|
+
guard seconds > 0, gravity > 0 else { return 0 }
|
|
92
|
+
return max(up * seconds - gravity * seconds * seconds / 2, 0)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/// The seconds that bounce lasts.
|
|
96
|
+
static func bounceTime(speed: Double, gravity: Double) -> Double {
|
|
97
|
+
gravity > 0 ? 2 * abs(speed) / 3 / gravity : 0
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// The value at `p` between (place, value) keys in order, eased from
|
|
101
|
+
/// each key to the next.
|
|
102
|
+
static func keys(_ keys: [(at: Double, value: Double)], at p: Double) -> Double {
|
|
103
|
+
guard let first = keys.first, let last = keys.last else { return 0 }
|
|
104
|
+
if p <= first.at { return first.value }
|
|
105
|
+
for (a, b) in zip(keys, keys.dropFirst()) where p <= b.at {
|
|
106
|
+
return a.value + (b.value - a.value) * M.ease(M.span(p, a.at, b.at))
|
|
107
|
+
}
|
|
108
|
+
return last.value
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -4,7 +4,7 @@ import AppKit
|
|
|
4
4
|
/// words are gone, the pieces that moved, the cloth, and the character. The context is flipped,
|
|
5
5
|
/// in the picture's points.
|
|
6
6
|
enum PlayDraw {
|
|
7
|
-
static func draw(_ frame: Play.Frame, in ctx: CGContext, stops: [NSColor],
|
|
7
|
+
static func draw(_ frame: Play.Frame, in ctx: CGContext, stops: [NSColor], cutouts: PlayCutouts?) {
|
|
8
8
|
for gone in frame.gone {
|
|
9
9
|
let c = gone.paper
|
|
10
10
|
ctx.setFillColor(CGColor(srgbRed: CGFloat(c >> 16 & 0xFF) / 255, green: CGFloat(c >> 8 & 0xFF) / 255,
|
|
@@ -13,7 +13,7 @@ enum PlayDraw {
|
|
|
13
13
|
}
|
|
14
14
|
for piece in frame.pieces {
|
|
15
15
|
let from = cg(piece.from)
|
|
16
|
-
guard let part =
|
|
16
|
+
guard let part = cutouts?.image(from, paper: piece.paper) else { continue }
|
|
17
17
|
ctx.saveGState()
|
|
18
18
|
ctx.translateBy(x: piece.at.x + from.width / 2, y: piece.at.y + from.height / 2)
|
|
19
19
|
ctx.rotate(by: piece.turn)
|
|
@@ -40,6 +40,41 @@ enum PlayDraw {
|
|
|
40
40
|
private static func cg(_ r: PlayMath.Rect) -> CGRect { CGRect(x: r.x, y: r.y, width: r.w, height: r.h) }
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/// The pieces of the picture that move, each cut out once: the ink alone,
|
|
44
|
+
/// the page's colour around it left out (`PlayMath.ink`).
|
|
45
|
+
final class PlayCutouts {
|
|
46
|
+
private let picture: CGImage
|
|
47
|
+
/// Pixels of the picture per point.
|
|
48
|
+
private let scale: CGFloat
|
|
49
|
+
private var made: [[CGFloat]: CGImage] = [:]
|
|
50
|
+
|
|
51
|
+
init(picture: CGImage, scale: CGFloat) {
|
|
52
|
+
self.picture = picture
|
|
53
|
+
self.scale = scale
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// The part of the picture at `from` (points), without its paper.
|
|
57
|
+
func image(_ from: CGRect, paper: UInt32) -> CGImage? {
|
|
58
|
+
let key = [from.minX, from.minY, from.width, from.height]
|
|
59
|
+
if let done = made[key] { return done }
|
|
60
|
+
guard let part = picture.cropping(to: from.applying(CGAffineTransform(scaleX: scale, y: scale))),
|
|
61
|
+
let ctx = CGContext(data: nil, width: part.width, height: part.height, bitsPerComponent: 8, bytesPerRow: part.width * 4,
|
|
62
|
+
space: CGColorSpace(name: CGColorSpace.sRGB)!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue),
|
|
63
|
+
let data = ctx.data else { return nil }
|
|
64
|
+
ctx.draw(part, in: CGRect(x: 0, y: 0, width: part.width, height: part.height))
|
|
65
|
+
let px = data.bindMemory(to: UInt8.self, capacity: part.width * part.height * 4)
|
|
66
|
+
for i in stride(from: 0, to: part.width * part.height * 4, by: 4) {
|
|
67
|
+
let a = PlayMath.ink(r: px[i], g: px[i + 1], b: px[i + 2], paper: paper)
|
|
68
|
+
// Premultiplied: the colour fades with it.
|
|
69
|
+
for k in 0..<3 { px[i + k] = UInt8(Double(px[i + k]) * a) }
|
|
70
|
+
px[i + 3] = UInt8(255 * a)
|
|
71
|
+
}
|
|
72
|
+
let image = ctx.makeImage()
|
|
73
|
+
made[key] = image
|
|
74
|
+
return image
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
43
78
|
/// The stage: a frozen picture of the screen laid over everything, with
|
|
44
79
|
/// the character playing on it. The real page is never touched: nothing
|
|
45
80
|
/// is clicked, typed or changed, and what looks eaten or wiped is only
|
|
@@ -157,7 +192,8 @@ private final class PlayView: NSView {
|
|
|
157
192
|
var shown = Play.Frame()
|
|
158
193
|
var stops = CharacterDraw.stops(tint: Brand.accent, colors: nil)
|
|
159
194
|
/// The picture under it: moved pieces are cut from it.
|
|
160
|
-
var picture: CGImage?
|
|
195
|
+
var picture: CGImage? { didSet { cutouts = nil } }
|
|
196
|
+
private var cutouts: PlayCutouts?
|
|
161
197
|
var onInput: (() -> Void)?
|
|
162
198
|
|
|
163
199
|
override var isFlipped: Bool { true }
|
|
@@ -166,8 +202,10 @@ private final class PlayView: NSView {
|
|
|
166
202
|
|
|
167
203
|
override func draw(_ dirtyRect: NSRect) {
|
|
168
204
|
guard let ctx = NSGraphicsContext.current?.cgContext else { return }
|
|
169
|
-
|
|
170
|
-
|
|
205
|
+
if cutouts == nil, let picture {
|
|
206
|
+
cutouts = PlayCutouts(picture: picture, scale: CGFloat(picture.width) / max(bounds.width, 1))
|
|
207
|
+
}
|
|
208
|
+
PlayDraw.draw(shown, in: ctx, stops: stops, cutouts: cutouts)
|
|
171
209
|
}
|
|
172
210
|
|
|
173
211
|
override func keyDown(with event: NSEvent) { onInput?() }
|
|
@@ -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-
|
|
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-GJ5EJVMZ.js";import"./chunk-JREA25GJ.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-
|
|
8
|
+
//# sourceMappingURL=App-XLQDP26J.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-
|
|
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-GJ5EJVMZ.js";import"./chunk-JREA25GJ.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-
|
|
7
|
+
//# sourceMappingURL=ChatApp-DRDUXZ66.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{A as a,B as b,C as c}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=agent-
|
|
1
|
+
import{A as a,B as b,C as c}from"./chunk-OFVMUBIP.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-QHM3J2XS.js.map
|