agentix-cli 0.92.3 → 0.93.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/Character.swift +52 -4
- package/apps/mac-voice/Sources/AgentXVoice/CharacterSim.swift +7 -1
- package/apps/mac-voice/Sources/AgentXVoice/Panel.swift +44 -3
- package/apps/mac-voice/Sources/AgentXVoice/PillPlacement.swift +12 -0
- package/apps/mac-voice/Sources/AgentXVoice/main.swift +9 -0
- package/dist/{board-dashboard-KE765RZZ.js → board-dashboard-MHMYOBKA.js} +5 -4
- package/dist/board-dashboard-MHMYOBKA.js.map +1 -0
- package/dist/{chunk-KB2FN3G7.js → chunk-UQMJSMET.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-WWHLK63O.js → program-RO5BWG6I.js} +4 -4
- package/package.json +1 -1
- package/dist/board-dashboard-KE765RZZ.js.map +0 -1
- /package/dist/{chunk-KB2FN3G7.js.map → chunk-UQMJSMET.js.map} +0 -0
- /package/dist/{program-WWHLK63O.js.map → program-RO5BWG6I.js.map} +0 -0
|
@@ -18,6 +18,9 @@ final class CharacterHost {
|
|
|
18
18
|
private static let size = NSSize(width: 440, height: 150)
|
|
19
19
|
/// The edge it hovers above, from the bottom of its window.
|
|
20
20
|
private static let ground: CGFloat = 8
|
|
21
|
+
/// Above the edge, clear of its body at the top of a hop: where its
|
|
22
|
+
/// speech bubble's tail ends.
|
|
23
|
+
private static let head: CGFloat = 78
|
|
21
24
|
|
|
22
25
|
private let window: NSPanel
|
|
23
26
|
private let view = CharacterView(frame: NSRect(origin: .zero, size: CharacterHost.size))
|
|
@@ -34,6 +37,11 @@ final class CharacterHost {
|
|
|
34
37
|
var levelSource: (() -> Float)?
|
|
35
38
|
/// Where the pointer is, in screen coordinates.
|
|
36
39
|
var pointerSource: () -> NSPoint = { NSEvent.mouseLocation }
|
|
40
|
+
/// Its speech bubble (#491), the pill: told every frame where the
|
|
41
|
+
/// character's head is and on which screen, it answers with where the
|
|
42
|
+
/// bubble is, or nil while it is hidden. Set by the app.
|
|
43
|
+
var bubble: ((NSPoint, NSRect) -> NSRect?)?
|
|
44
|
+
private var bubbleFrame: NSRect?
|
|
37
45
|
|
|
38
46
|
init() {
|
|
39
47
|
window = NSPanel(contentRect: NSRect(origin: .zero, size: Self.size),
|
|
@@ -79,6 +87,12 @@ final class CharacterHost {
|
|
|
79
87
|
func show(_ activity: CharacterMath.Activity, tint: NSColor, colors: [NSColor]?) {
|
|
80
88
|
self.activity = activity
|
|
81
89
|
view.stops = CharacterDraw.stops(tint: tint, colors: colors)
|
|
90
|
+
redraw()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// Standing still, it is drawn again when something changes: its
|
|
94
|
+
/// state, or its bubble showing or hiding.
|
|
95
|
+
func redraw() {
|
|
82
96
|
if shown && timer == nil { tick() }
|
|
83
97
|
}
|
|
84
98
|
|
|
@@ -101,10 +115,10 @@ final class CharacterHost {
|
|
|
101
115
|
// The screen with the menu bar, less the menu bar and the Dock.
|
|
102
116
|
guard let screen = NSScreen.screens.first else { return }
|
|
103
117
|
let visible = screen.visibleFrame
|
|
104
|
-
// It rests
|
|
105
|
-
// goes no further right
|
|
118
|
+
// It rests under the right end of its bubble, the bubble in the
|
|
119
|
+
// pill's own corner, and goes no further right.
|
|
106
120
|
let left = Double(visible.minX + 44)
|
|
107
|
-
let home = max(Double(visible.maxX - PillPlacement.inset -
|
|
121
|
+
let home = max(Double(visible.maxX - PillPlacement.inset - PillPlacement.bubbleReach), left)
|
|
108
122
|
let range = left...home
|
|
109
123
|
|
|
110
124
|
let frame: CharacterSim.Frame
|
|
@@ -118,11 +132,18 @@ final class CharacterHost {
|
|
|
118
132
|
}
|
|
119
133
|
let mouse = pointerSource()
|
|
120
134
|
let pointer = screen.frame.contains(mouse) ? (x: Double(mouse.x), y: Double(mouse.y - visible.minY)) : nil
|
|
135
|
+
// The gap its tail fills counts as the bubble, so a pointer a
|
|
136
|
+
// little under a button does not send both away.
|
|
137
|
+
let held = bubbleFrame?.insetBy(dx: 0, dy: -PillPlacement.tail).contains(mouse) ?? false
|
|
121
138
|
frame = sim.step(to: ProcessInfo.processInfo.systemUptime,
|
|
122
|
-
CharacterSim.Input(activity: activity, level: level, pointer: pointer,
|
|
139
|
+
CharacterSim.Input(activity: activity, level: level, pointer: pointer, held: held,
|
|
140
|
+
home: home, range: range))
|
|
123
141
|
}
|
|
124
142
|
let origin = NSPoint(x: (CGFloat(frame.x) - Self.size.width / 2).rounded(), y: visible.minY - Self.ground)
|
|
125
143
|
if window.frame.origin != origin { window.setFrameOrigin(origin) }
|
|
144
|
+
// The bubble goes with the window, so the two move as one.
|
|
145
|
+
bubbleFrame = bubble?(NSPoint(x: origin.x + Self.size.width / 2, y: visible.minY + Self.head), visible)
|
|
146
|
+
view.bubble = bubbleFrame?.offsetBy(dx: -origin.x, dy: -origin.y)
|
|
126
147
|
view.origin = origin.x
|
|
127
148
|
view.shown = frame
|
|
128
149
|
view.needsDisplay = true
|
|
@@ -138,6 +159,8 @@ final class CharacterView: NSView {
|
|
|
138
159
|
/// Under the character, in this view; and the view's left edge on screen.
|
|
139
160
|
var edge = CGPoint.zero
|
|
140
161
|
var origin: CGFloat = 0
|
|
162
|
+
/// Its speech bubble in this window, origin bottom-left; nil while hidden.
|
|
163
|
+
var bubble: NSRect?
|
|
141
164
|
|
|
142
165
|
override var isFlipped: Bool { true }
|
|
143
166
|
override func hitTest(_ point: NSPoint) -> NSView? { nil }
|
|
@@ -148,5 +171,30 @@ final class CharacterView: NSView {
|
|
|
148
171
|
// to the nearest point; the rest of the way is drawn here.
|
|
149
172
|
let at = CGPoint(x: CGFloat(shown.x) - origin, y: edge.y)
|
|
150
173
|
CharacterDraw.draw(shown, in: ctx, edge: at, origin: origin, unit: unit, stops: stops)
|
|
174
|
+
if let bubble { drawTail(in: ctx, from: bubble) }
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/// The bubble's tail: a small point from its bottom edge down to the
|
|
178
|
+
/// character, in the bubble's own colours.
|
|
179
|
+
private func drawTail(in ctx: CGContext, from bubble: NSRect) {
|
|
180
|
+
let half: CGFloat = 7, corner = Brand.Radius.lg + half
|
|
181
|
+
let x = min(max(bounds.midX, bubble.minX + corner), bubble.maxX - corner)
|
|
182
|
+
// One point up into the bubble, so no gap shows between the two.
|
|
183
|
+
let top = bounds.height - bubble.minY - 1
|
|
184
|
+
let tip = CGPoint(x: x, y: top + 1 + PillPlacement.tail)
|
|
185
|
+
effectiveAppearance.performAsCurrentDrawingAppearance {
|
|
186
|
+
ctx.move(to: CGPoint(x: x - half, y: top))
|
|
187
|
+
ctx.addLine(to: tip)
|
|
188
|
+
ctx.addLine(to: CGPoint(x: x + half, y: top))
|
|
189
|
+
ctx.closePath()
|
|
190
|
+
ctx.setFillColor(NSColor.windowBackgroundColor.withAlphaComponent(0.92).cgColor)
|
|
191
|
+
ctx.fillPath()
|
|
192
|
+
ctx.move(to: CGPoint(x: x - half, y: top + 1))
|
|
193
|
+
ctx.addLine(to: tip)
|
|
194
|
+
ctx.addLine(to: CGPoint(x: x + half, y: top + 1))
|
|
195
|
+
ctx.setStrokeColor(NSColor.separatorColor.cgColor)
|
|
196
|
+
ctx.setLineWidth(1)
|
|
197
|
+
ctx.strokePath()
|
|
198
|
+
}
|
|
151
199
|
}
|
|
152
200
|
}
|
|
@@ -17,6 +17,9 @@ struct CharacterSim {
|
|
|
17
17
|
/// The pointer: along the edge, and its height above it. Nil when
|
|
18
18
|
/// it is on another screen.
|
|
19
19
|
var pointer: (x: Double, y: Double)?
|
|
20
|
+
/// The pointer is on its speech bubble: it stays where it is, so
|
|
21
|
+
/// the bubble is not pulled from under the pointer.
|
|
22
|
+
var held = false
|
|
20
23
|
/// Where it rests, and how far it may go.
|
|
21
24
|
var home = 0.0
|
|
22
25
|
var range: ClosedRange<Double> = 0...0
|
|
@@ -99,7 +102,10 @@ struct CharacterSim {
|
|
|
99
102
|
// The pointer comes close: out of its way. Left alone: back home,
|
|
100
103
|
// unless the pointer is resting there.
|
|
101
104
|
let near = input.pointer.map { abs($0.x - x) < reach && $0.y < tall } ?? false
|
|
102
|
-
if
|
|
105
|
+
if input.held {
|
|
106
|
+
target = x
|
|
107
|
+
awayUntil = max(awayUntil, now + Self.awayFor)
|
|
108
|
+
} else if near {
|
|
103
109
|
target = M.aside(x: x, pointer: input.pointer!.x, clear: Self.clear, range: input.range)
|
|
104
110
|
awayUntil = now + Self.awayFor
|
|
105
111
|
restSince = now
|
|
@@ -107,11 +107,18 @@ final class Panel: NSPanel {
|
|
|
107
107
|
|
|
108
108
|
/// Told what the orb is shown, so the character can show the same.
|
|
109
109
|
var onLook: ((State, NSColor, [NSColor]?) -> Void)?
|
|
110
|
+
/// Told when it comes on screen or leaves it, so a still character
|
|
111
|
+
/// draws its bubble's tail again.
|
|
112
|
+
var onShown: (() -> Void)?
|
|
110
113
|
|
|
111
114
|
/// Off while the character stands in for the orb (Character.swift):
|
|
112
115
|
/// the words start where the orb was.
|
|
113
116
|
private(set) var showsOrb = true
|
|
114
117
|
|
|
118
|
+
/// Set while the pill is the character's speech bubble: where the
|
|
119
|
+
/// character's head is, and the screen it is on.
|
|
120
|
+
private(set) var bubble: (head: NSPoint, visible: NSRect)?
|
|
121
|
+
|
|
115
122
|
/// Told of every state rendered, so the menu-bar icon can follow.
|
|
116
123
|
var onRender: ((State) -> Void)?
|
|
117
124
|
|
|
@@ -332,18 +339,50 @@ final class Panel: NSPanel {
|
|
|
332
339
|
@MainActor
|
|
333
340
|
func restorePosition() {
|
|
334
341
|
collapse(animated: false)
|
|
342
|
+
if let bubble {
|
|
343
|
+
place(PillPlacement.bubble(size: frame.size, head: bubble.head, visible: bubble.visible))
|
|
344
|
+
return
|
|
345
|
+
}
|
|
335
346
|
let screens = NSScreen.screens.map(\.visibleFrame)
|
|
336
347
|
let fallback = (NSScreen.main ?? NSScreen.screens.first)?.visibleFrame ?? .zero
|
|
337
348
|
place(PillPlacement.clamp(saved: Config.pillOrigin, size: frame.size, screens: screens, fallback: fallback))
|
|
338
349
|
}
|
|
339
350
|
|
|
340
351
|
/// Back to the bottom-right corner, forgetting where it was dragged.
|
|
352
|
+
/// Not while it is the character's bubble: nothing would move, and
|
|
353
|
+
/// the place kept for the orb look would be lost.
|
|
341
354
|
@MainActor
|
|
342
355
|
func resetPosition() {
|
|
356
|
+
guard bubble == nil else { return }
|
|
343
357
|
Config.pillOrigin = nil
|
|
344
358
|
restorePosition()
|
|
345
359
|
}
|
|
346
360
|
|
|
361
|
+
/// The character's speech bubble (#491): the pill sits above `head`,
|
|
362
|
+
/// the top of the character, and goes where it goes, grown or not. It
|
|
363
|
+
/// is not dragged by itself, and the place it was dragged to as a
|
|
364
|
+
/// pill is kept for the orb look.
|
|
365
|
+
@MainActor
|
|
366
|
+
func attach(head: NSPoint, visible: NSRect) {
|
|
367
|
+
bubble = (head, visible)
|
|
368
|
+
isMovableByWindowBackground = false
|
|
369
|
+
// Growing or collapsing: it catches up on the next frame.
|
|
370
|
+
guard placing == 0 else { return }
|
|
371
|
+
let to = PillPlacement.bubble(size: Self.size, head: head, visible: visible)
|
|
372
|
+
let from = collapsedFrame().origin
|
|
373
|
+
let moved = PillPlacement.inside(frame.offsetBy(dx: to.x - from.x, dy: to.y - from.y), visible)
|
|
374
|
+
if moved.origin != frame.origin { place(moved.origin) }
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/// The orb look again: a pill of its own, back where it was left.
|
|
378
|
+
@MainActor
|
|
379
|
+
func detach() {
|
|
380
|
+
guard bubble != nil else { return }
|
|
381
|
+
bubble = nil
|
|
382
|
+
isMovableByWindowBackground = true
|
|
383
|
+
restorePosition()
|
|
384
|
+
}
|
|
385
|
+
|
|
347
386
|
@MainActor
|
|
348
387
|
private func place(_ origin: NSPoint) {
|
|
349
388
|
placing += 1
|
|
@@ -398,7 +437,7 @@ final class Panel: NSPanel {
|
|
|
398
437
|
func show() {
|
|
399
438
|
orb.setOnScreen(showsOrb)
|
|
400
439
|
miniOrbs.setOnScreen(!miniOrbs.isHidden)
|
|
401
|
-
if !isVisible { orderFrontRegardless() }
|
|
440
|
+
if !isVisible { orderFrontRegardless(); onShown?() }
|
|
402
441
|
}
|
|
403
442
|
|
|
404
443
|
@MainActor
|
|
@@ -406,7 +445,7 @@ final class Panel: NSPanel {
|
|
|
406
445
|
closeButton.isHidden = true
|
|
407
446
|
orb.setOnScreen(false)
|
|
408
447
|
miniOrbs.setOnScreen(false)
|
|
409
|
-
if isVisible { orderOut(nil) }
|
|
448
|
+
if isVisible { orderOut(nil); onShown?() }
|
|
410
449
|
}
|
|
411
450
|
|
|
412
451
|
@objc private func closeClicked() { onDismiss?() }
|
|
@@ -461,7 +500,6 @@ final class Panel: NSPanel {
|
|
|
461
500
|
default: colors = agentPalette()
|
|
462
501
|
}
|
|
463
502
|
orb.show(state.orbPhase, tint: tint, colors: colors)
|
|
464
|
-
onLook?(state, tint, colors)
|
|
465
503
|
|
|
466
504
|
if state.isMeta {
|
|
467
505
|
stopMarquee()
|
|
@@ -477,6 +515,9 @@ final class Panel: NSPanel {
|
|
|
477
515
|
// Grown into an answer, it stays until it collapses, idle or not;
|
|
478
516
|
// so does a pill with agents still busy in its mini orbs.
|
|
479
517
|
if dismissed || (state.isMeta && !alwaysVisible && !expanded && busyCount == 0) { hide() } else { show() }
|
|
518
|
+
// After showing or hiding: a still character draws its bubble's
|
|
519
|
+
// tail only while the bubble is on screen.
|
|
520
|
+
onLook?(state, tint, colors)
|
|
480
521
|
armCollapse()
|
|
481
522
|
onRender?(state)
|
|
482
523
|
}
|
|
@@ -68,6 +68,18 @@ enum PillPlacement {
|
|
|
68
68
|
width: size.width, height: size.height)
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/// How far the bubble reaches to the right of the character's middle,
|
|
72
|
+
/// and the gap above its head that the bubble's tail fills.
|
|
73
|
+
static let bubbleReach: CGFloat = 64
|
|
74
|
+
static let tail: CGFloat = 10
|
|
75
|
+
|
|
76
|
+
/// The pill as the character's speech bubble (#491): above `head`,
|
|
77
|
+
/// the top of the character, most of it to the left, kept on screen.
|
|
78
|
+
static func bubble(size: CGSize, head: CGPoint, visible: CGRect) -> CGPoint {
|
|
79
|
+
inside(CGRect(x: head.x + bubbleReach - size.width, y: head.y + tail,
|
|
80
|
+
width: size.width, height: size.height), visible).origin
|
|
81
|
+
}
|
|
82
|
+
|
|
71
83
|
/// `frame` moved the least distance that puts it inside `bounds`. A
|
|
72
84
|
/// frame larger than `bounds` keeps its top-left corner in view.
|
|
73
85
|
static func inside(_ frame: CGRect, _ bounds: CGRect) -> CGRect {
|
|
@@ -204,6 +204,7 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
204
204
|
let asCharacter = saved.general.look == "character"
|
|
205
205
|
panel.setShowsOrb(!asCharacter)
|
|
206
206
|
character.setShown(asCharacter)
|
|
207
|
+
if !asCharacter { panel.detach() }
|
|
207
208
|
if settingsWindow.model.recording == nil { registerHotkeys() }
|
|
208
209
|
// Colours may have changed.
|
|
209
210
|
statusMenu.refresh()
|
|
@@ -314,9 +315,17 @@ final class App: NSObject, NSApplicationDelegate {
|
|
|
314
315
|
panel.orb.levelSource = { [weak self] in self?.recorder.level ?? 0 }
|
|
315
316
|
character.setAnimated(Config.animatedOrb)
|
|
316
317
|
character.levelSource = { [weak self] in self?.recorder.level ?? 0 }
|
|
318
|
+
// The pill is the character's speech bubble: it goes where the
|
|
319
|
+
// character goes.
|
|
320
|
+
character.bubble = { [weak self] head, visible in
|
|
321
|
+
guard let panel = self?.panel else { return nil }
|
|
322
|
+
panel.attach(head: head, visible: visible)
|
|
323
|
+
return panel.isVisible ? panel.frame : nil
|
|
324
|
+
}
|
|
317
325
|
panel.onLook = { [weak self] state, tint, colors in
|
|
318
326
|
self?.character.show(state.activity, tint: tint, colors: colors)
|
|
319
327
|
}
|
|
328
|
+
panel.onShown = { [weak self] in self?.character.redraw() }
|
|
320
329
|
panel.onDismiss = { [weak self] in self?.dismissPill() }
|
|
321
330
|
panel.agentPalette = { [weak self] in
|
|
322
331
|
guard let self else { return nil }
|
|
@@ -1046,7 +1046,7 @@ body { margin: 0; overflow: hidden; }
|
|
|
1046
1046
|
text-align: center;
|
|
1047
1047
|
}
|
|
1048
1048
|
`;import{createServer as Im}from"http";import{appendFileSync as Mm,existsSync as fl,mkdirSync as Lm}from"fs";import{readFile as Rm}from"fs/promises";import{fileURLToPath as $m}from"url";import{dirname as Pm,resolve as at}from"path";Al();function He(t,e){if(!t)return"absent";let a=Ln(t),n=e.list().find(r=>r.hash===a);return n&&(n.revokedAt||n.expiresAt&&Date.parse(n.expiresAt)<Date.now())?"revoked":"invalid"}var Ee=class{constructor(e=r=>console.log(r),a=Date.now,n=6e4){this.log=e;this.now=a;this.everyMs=n}last=new Map;record(e,a){let n=Object.entries(a).map(([i,l])=>`${i}=${l}`).join(" "),r=`${e} ${a.cookie??""} ${a.bearer??""}`,o=this.now(),s=this.last.get(r);s!==void 0&&o-s<this.everyMs||(this.last.size>500&&this.prune(o),this.last.set(r,o),this.log(`[app] unauthenticated ${e} ${n}`))}prune(e){for(let[a,n]of this.last)e-n>=this.everyMs&&this.last.delete(a);this.last.size>500&&this.last.clear()}};function $t(t,e,a){let n={cookie:e};return a&&(n.bearer=a),n.mode=jr(t.headers["sec-fetch-mode"]),n.site=jr(t.headers["sec-fetch-site"]),n}function jr(t){let e=Array.isArray(t)?t[0]:t;return e&&/^[a-z-]{1,20}$/.test(e)?e:"-"}import{deflateSync as Bl}from"zlib";var zl=[41,121,255],ql=[255,255,255],Or=new Map;function Be(t){let e=Or.get(t);return e||(e=Ul(t,Fl(t)),Or.set(t,e)),e}function Fl(t){let e=1+t*3,a=Buffer.alloc(e*t),n=t/2,r=t*.22;for(let o=0;o<t;o++)for(let s=0;s<t;s++){let i=s+.5-n,l=o+.5-n,c=i*i+l*l<=r*r?ql:zl;a.set(c,o*e+1+s*3)}return a}function Ul(t,e){let a=Buffer.alloc(13);return a.writeUInt32BE(t,0),a.writeUInt32BE(t,4),a[8]=8,a[9]=2,Buffer.concat([Buffer.from([137,80,78,71,13,10,26,10]),pa("IHDR",a),pa("IDAT",Bl(e)),pa("IEND",Buffer.alloc(0))])}function pa(t,e){let a=Buffer.alloc(4);a.writeUInt32BE(e.length);let n=Buffer.concat([Buffer.from(t,"ascii"),e]),r=Buffer.alloc(4);return r.writeUInt32BE(Gl(n)),Buffer.concat([a,n,r])}var Wl=Array.from({length:256},(t,e)=>{let a=e;for(let n=0;n<8;n++)a=a&1?3988292384^a>>>1:a>>>1;return a>>>0});function Gl(t){let e=4294967295;for(let a of t)e=Wl[(e^a)&255]^e>>>8;return(e^4294967295)>>>0}lt();Tl();var Xl=7,Kl={gitlab:"GitLab",github:"GitHub",telegram:"Telegram",whatsapp:"WhatsApp",slack:"Slack",discord:"Discord",voice:"Voice",app:"Phone app",dashboard:"Dashboard",webrtc:"Call"};function Jl(t,e){let a=t.toLowerCase().split("@")[0],n=Kl[a]??t,r=/^(.+):(issue|merge_request|pull):(\d+)$/.exec(e);if(r){let o=r[2]==="issue"?"issue":r[2]==="pull"?"pull request":"merge request";return`${n} ${o} #${r[3]} in ${r[1]}`}return n}function Nr(t,e,a){let n=t.toLowerCase().split("@")[0],r=/^(.+):(issue|merge_request|pull):(\d+)$/.exec(e);if(!r)return null;let[,o,s,i]=r;return n==="gitlab"?`${(a.gitlab||"https://gitlab.com").replace(/\/+$/,"")}/${o}/-/${s==="issue"?"issues":"merge_requests"}/${i}`:n==="github"?`${(a.github||"https://github.com").replace(/\/+$/,"")}/${o}/${s==="issue"?"issues":"pull"}/${i}`:null}function Dr(t,e,a={}){let n=a.now??Date.now(),s=(t.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'requests'").get()?t.prepare("PRAGMA table_info(requests)").all():[]).some(u=>u.name==="person"),i=u=>({id:u.id,state:u.state,agentId:u.agent_id,text:u.text,channel:u.channel,chatId:u.chat_id,createdAt:u.created_at,updatedAt:u.updated_at,closedAt:u.closed_at??null,question:u.question??null,attentionReason:u.attention_reason??null,evidence:u.evidence??null,where:{label:Jl(u.channel,u.chat_id),url:a.linkFor?.(u.channel,u.chat_id)??null}}),l=s?t.prepare(`SELECT * FROM requests WHERE person = ? AND state IN (${aa.map(()=>"?").join(",")}) ORDER BY created_at, rowid`).all(e,...aa).map(i):[],c=s?t.prepare(`SELECT * FROM requests WHERE person = ? AND state IN (${na.map(()=>"?").join(",")}) AND COALESCE(closed_at, updated_at) >= ?
|
|
1049
|
-
ORDER BY COALESCE(closed_at, updated_at) DESC LIMIT 50`).all(e,...na,n-Xl*864e5).map(i):[],p=[];try{p=It(t,e,10)}catch{}return{open:l,recent:c,runs:p}}function Hr(t){return t>=200&&t<300?"retry":t===401?"lock":"keep"}function Br(t,e){return!t||e-t>=3e4||t>e}function Pt(t,e){let a="23456789ABCDEFGHJKMNPQRSTUVWXYZ",n=String(t||"").toUpperCase(),r=Math.max(0,Math.min(Number(e)||0,n.length)),o="",s=0;for(let l=0;l<n.length&&o.length<8;l++)a.indexOf(n.charAt(l))<0||(o+=n.charAt(l),l<r&&s++);let i=o.length>4?o.slice(0,4)+"-"+o.slice(4):o;return{value:i,caret:Math.min(s>4?s+1:s,i.length)}}function zr(t){let e=String(t||"").trim(),a=/^https?:[/][/][^/#?]+[/]app[/]pair[/]?#(.*)$/i.exec(e);if(a){let r=a[1].split("&");for(let o=0;o<r.length;o++){if(r[o].indexOf("token=")!==0)continue;let s="";try{s=decodeURIComponent(r[o].slice(6))}catch{return{kind:"none"}}return/^agx_live_[0-9a-f]{64}$/.test(s)?{kind:"token",token:s}:{kind:"none"}}return{kind:"none"}}let n=e.toUpperCase();return/^[A-Z0-9]{4}-?[A-Z0-9]{4}$/.test(n)?{kind:"code",code:n.slice(0,4)+"-"+n.slice(-4)}:{kind:"none"}}function qr(t,e,a,n){return e?
|
|
1049
|
+
ORDER BY COALESCE(closed_at, updated_at) DESC LIMIT 50`).all(e,...na,n-Xl*864e5).map(i):[],p=[];try{p=It(t,e,10)}catch{}return{open:l,recent:c,runs:p}}function Hr(t){return t>=200&&t<300?"retry":t===401?"lock":"keep"}function Br(t,e){return!t||e-t>=3e4||t>e}function Pt(t,e){let a="23456789ABCDEFGHJKMNPQRSTUVWXYZ",n=String(t||"").toUpperCase(),r=Math.max(0,Math.min(Number(e)||0,n.length)),o="",s=0;for(let l=0;l<n.length&&o.length<8;l++)a.indexOf(n.charAt(l))<0||(o+=n.charAt(l),l<r&&s++);let i=o.length>4?o.slice(0,4)+"-"+o.slice(4):o;return{value:i,caret:Math.min(s>4?s+1:s,i.length)}}function zr(t){let e=String(t||"").trim(),a=/^https?:[/][/][^/#?]+[/]app[/]pair[/]?#(.*)$/i.exec(e);if(a){let r=a[1].split("&");for(let o=0;o<r.length;o++){if(r[o].indexOf("token=")!==0)continue;let s="";try{s=decodeURIComponent(r[o].slice(6))}catch{return{kind:"none"}}return/^agx_live_[0-9a-f]{64}$/.test(s)?{kind:"token",token:s}:{kind:"none"}}return{kind:"none"}}let n=e.toUpperCase();return/^[A-Z0-9]{4}-?[A-Z0-9]{4}$/.test(n)?{kind:"code",code:n.slice(0,4)+"-"+n.slice(-4)}:{kind:"none"}}function qr(t,e,a,n){return t?e?{text:"Can't reach the server. "+(n?"Showing what was last loaded. ":"")+"Trying again every "+a+" seconds.",retry:!0}:{text:"Offline. Showing what was last loaded; live state needs a connection.",retry:!1}:null}function Fr(t){return String(t??"").replace(/```[\w-]*|`/g,"").replace(/!?\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/^[ \t]*(?:#{1,6}|>+|[-*+]|\d+[.)])[ \t]+(?:\[[ xX]\][ \t]+)?/gm,"").replace(/\*\*|~~/g,"").replace(/(^|[\s(])\*(\S(?:[^*\n]*\S)?)\*(?=[\s).,;:!?]|$)/gm,"$1$2").replace(/\s+/g," ").trim()}var Ur=`
|
|
1050
1050
|
(function () {
|
|
1051
1051
|
var POLL_S = 30, RETRY_S = 20, GIVE_UP_MS = 15000;
|
|
1052
1052
|
var who = document.getElementById('who');
|
|
@@ -1056,7 +1056,8 @@ body { margin: 0; overflow: hidden; }
|
|
|
1056
1056
|
var install = document.getElementById('install');
|
|
1057
1057
|
var updated = document.getElementById('updated');
|
|
1058
1058
|
var theme = document.getElementById('theme');
|
|
1059
|
-
|
|
1059
|
+
// No network counts as a failed load until a load works (#496).
|
|
1060
|
+
var failed = navigator.onLine === false, loaded = false, named = false, busy = false, timer = null;
|
|
1060
1061
|
theme.addEventListener('click', function () {
|
|
1061
1062
|
var cur = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
|
|
1062
1063
|
document.documentElement.setAttribute('data-theme', cur);
|
|
@@ -1075,7 +1076,7 @@ body { margin: 0; overflow: hidden; }
|
|
|
1075
1076
|
retry.hidden = !note.retry;
|
|
1076
1077
|
}
|
|
1077
1078
|
window.addEventListener('online', function () { failed = false; showConn(); load(); });
|
|
1078
|
-
window.addEventListener('offline', showConn);
|
|
1079
|
+
window.addEventListener('offline', function () { failed = true; showConn(); });
|
|
1079
1080
|
retry.addEventListener('click', function () { load(); });
|
|
1080
1081
|
// A 401 or 403 means this machine's key ended: /member then shows the pairing page.
|
|
1081
1082
|
function get(url) {
|
|
@@ -19345,4 +19346,4 @@ data: ${h.replace(/\n/g," ")}
|
|
|
19345
19346
|
`)}catch{}}};s.stdout?.on("data",l),s.stderr?.on("data",l);let c=setInterval(()=>{try{e.write(`: hb
|
|
19346
19347
|
|
|
19347
19348
|
`)}catch{}},15e3),p=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",p),s.on("exit",p),s.on("error",p)}async function ml(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((u,f)=>{let h=[];t.on("data",k=>h.push(k)),t.on("end",()=>u(Buffer.concat(h))),t.on("error",f)}):void 0,l={},c=t.headers["content-type"];c&&(l["Content-Type"]=Array.isArray(c)?c[0]:c);let p=t.headers["x-requested-with"];p&&(l["X-Requested-With"]=Array.isArray(p)?p[0]:p),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let u=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),f=Buffer.from(await u.arrayBuffer());e.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json","Cache-Control":"no-store"}),e.end(f)}catch(u){b(e,502,{error:`proxy to peer failed: ${u?.message||u}`,target:r})}}function nt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:bl(n),token:n.dashboardToken||n.token}:null}export{Jm as applyAttachSessions,qm as fetchDaemonAgents,Om as handleBoardRequest,Qy as resetLiveCaches,we as resolveNodeTargets,Yy as startBoardDashboard,Km as withLastGood};
|
|
19348
|
-
//# sourceMappingURL=board-dashboard-
|
|
19349
|
+
//# sourceMappingURL=board-dashboard-MHMYOBKA.js.map
|