relay-codex 0.5.2 → 0.5.3
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/docs/publishing.md +2 -2
- package/package.json +1 -1
- package/python/Menu.swift +37 -7
- package/python/router.py +1 -1
package/docs/publishing.md
CHANGED
|
@@ -8,8 +8,8 @@ Friends can run `npx relay-codex` or install it with `npm install -g relay-codex
|
|
|
8
8
|
The GitHub repository is enough for friends to install or try Relay:
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
-
npm install -g github:blackspider-ops/relay#v0.5.
|
|
12
|
-
npx --yes github:blackspider-ops/relay#v0.5.
|
|
11
|
+
npm install -g github:blackspider-ops/relay#v0.5.3
|
|
12
|
+
npx --yes github:blackspider-ops/relay#v0.5.3 --version
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
`npx` runs packages; it is not a separate publishing service. Publishing
|
package/package.json
CHANGED
package/python/Menu.swift
CHANGED
|
@@ -127,8 +127,28 @@ final class MenuController: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
|
|
127
127
|
entry.target = self; entry.representedObject = args
|
|
128
128
|
entry.identifier = NSUserInterfaceItemIdentifier("action:" + args.joined(separator: "|")); menu.addItem(entry)
|
|
129
129
|
}
|
|
130
|
+
struct TimingRow {
|
|
131
|
+
let title: String
|
|
132
|
+
let at: Double?
|
|
133
|
+
}
|
|
134
|
+
static func timestamp(_ value: Any?) -> Double? {
|
|
135
|
+
guard let seconds = value as? Double, seconds.isFinite, seconds > 0 else { return nil }
|
|
136
|
+
return seconds
|
|
137
|
+
}
|
|
138
|
+
static func accountTimingRows(_ account: [String: Any]) -> [TimingRow] {
|
|
139
|
+
var rows: [TimingRow] = []
|
|
140
|
+
if let primary = account["primary"] as? [String: Any], let at = timestamp(primary["resetsAt"]) {
|
|
141
|
+
rows.append(TimingRow(title: "Short reset", at: at))
|
|
142
|
+
}
|
|
143
|
+
if let secondary = account["secondary"] as? [String: Any], let at = timestamp(secondary["resetsAt"]) {
|
|
144
|
+
rows.append(TimingRow(title: "Weekly reset", at: at))
|
|
145
|
+
}
|
|
146
|
+
if let at = timestamp(account["next_check"]) { rows.append(TimingRow(title: "Next allowance check", at: at)) }
|
|
147
|
+
else { rows.append(TimingRow(title: "Allowance checked when needed", at: nil)) }
|
|
148
|
+
return rows
|
|
149
|
+
}
|
|
130
150
|
func date(_ value: Any?) -> String {
|
|
131
|
-
guard let seconds = value
|
|
151
|
+
guard let seconds = MenuController.timestamp(value) else { return "Not available" }
|
|
132
152
|
return Date(timeIntervalSince1970: seconds).formatted(date: .abbreviated, time: .shortened)
|
|
133
153
|
}
|
|
134
154
|
func countdown(_ title: String, value: Any, into menu: NSMenu) {
|
|
@@ -140,8 +160,9 @@ final class MenuController: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
|
|
140
160
|
for entry in menu.items {
|
|
141
161
|
if let data = entry.representedObject as? [String: Any], let at = data["at"] as? Double, let label = data["label"] as? String {
|
|
142
162
|
let seconds = max(0, Int(at - Date().timeIntervalSince1970))
|
|
143
|
-
let remaining = seconds < 60 ? "under a minute" : seconds < 3600 ? "\(seconds / 60)m" : "\(seconds / 3600)h \((seconds % 3600) / 60)m"
|
|
144
|
-
|
|
163
|
+
let remaining = seconds < 60 ? "under a minute" : seconds < 3600 ? "\(seconds / 60)m" : seconds < 86400 ? "\(seconds / 3600)h \((seconds % 3600) / 60)m" : "\(seconds / 86400)d \((seconds % 86400) / 3600)h"
|
|
164
|
+
let elapsed = label.contains("reset") ? "reported time passed" : "due now"
|
|
165
|
+
entry.title = label + ": " + (seconds == 0 ? elapsed : "in " + remaining) + " · " + date(at)
|
|
145
166
|
}
|
|
146
167
|
if let child = entry.submenu { updateTimes(child) }
|
|
147
168
|
}
|
|
@@ -168,8 +189,12 @@ final class MenuController: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
|
|
168
189
|
if let email = account["email"] as? String { text(email, into: submenu) }
|
|
169
190
|
text("Short window: \(remaining)", into: submenu)
|
|
170
191
|
if weekly != "?" { text("Weekly window: \(weekly) left", into: submenu) }
|
|
171
|
-
|
|
172
|
-
|
|
192
|
+
for row in MenuController.accountTimingRows(account) {
|
|
193
|
+
if let at = row.at { countdown(row.title, value: at, into: submenu) }
|
|
194
|
+
else { text(row.title, into: submenu) }
|
|
195
|
+
}
|
|
196
|
+
let lastChecked = MenuController.timestamp(account["usage_checked_at"]).map { date($0) } ?? "Not checked yet"
|
|
197
|
+
text("Last checked: \(lastChecked)", into: submenu)
|
|
173
198
|
let entry = NSMenuItem(title: "\(name) · \(label)", action: nil, keyEquivalent: "")
|
|
174
199
|
entry.identifier = NSUserInterfaceItemIdentifier("account:" + (account["id"] as? String ?? name))
|
|
175
200
|
entry.submenu = submenu; menu.addItem(entry)
|
|
@@ -182,7 +207,7 @@ final class MenuController: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
|
|
182
207
|
let submenu = NSMenu()
|
|
183
208
|
text("Account: \(session["account_name"] as? String ?? session["account"] as? String ?? "unknown")", into: submenu)
|
|
184
209
|
text("Model: \(session["model"] as? String ?? "unknown")", into: submenu)
|
|
185
|
-
if let next = session["next_wake"] { countdown("Next action", value: next, into: submenu) }
|
|
210
|
+
if let next = MenuController.timestamp(session["next_wake"]) { countdown("Next action", value: next, into: submenu) }
|
|
186
211
|
if let reason = session["reason"] as? String { text(reason.replacingOccurrences(of: "_", with: " "), into: submenu) }
|
|
187
212
|
action("Copy reconnect command", args: ["copy", "relay attach " + id], into: submenu)
|
|
188
213
|
action("Pause recovery", args: ["pause", id, "--wait"], into: submenu)
|
|
@@ -199,6 +224,7 @@ final class MenuController: NSObject, NSApplicationDelegate, NSMenuDelegate {
|
|
|
199
224
|
login.state = FileManager.default.fileExists(atPath: NSHomeDirectory() + "/Library/LaunchAgents/local.relay.menu.plist") ? .on : .off
|
|
200
225
|
menu.addItem(login)
|
|
201
226
|
let quit = NSMenuItem(title: "Quit Relay menu", action: #selector(quitMenu), keyEquivalent: "q"); quit.target = self; menu.addItem(quit)
|
|
227
|
+
updateTimes(menu)
|
|
202
228
|
if let visible = item.menu { MenuController.synchronise(visible, with: menu) }
|
|
203
229
|
else { item.menu = menu }
|
|
204
230
|
}
|
|
@@ -251,7 +277,11 @@ if CommandLine.arguments.contains("--self-check") {
|
|
|
251
277
|
MenuController.synchronise(visible, with: replacement)
|
|
252
278
|
let safeIdentity = visible.items[0] !== existing && visible.items[0].identifier == newItem.identifier
|
|
253
279
|
print("Session action identity preserved: \(safeIdentity)")
|
|
254
|
-
|
|
280
|
+
let timing = MenuController.accountTimingRows(["next_check": NSNull(), "primary": ["resetsAt": 2000000000.0], "secondary": ["resetsAt": 2000100000.0]])
|
|
281
|
+
let scheduled = MenuController.accountTimingRows(["next_check": 2000200000.0])
|
|
282
|
+
let correctTiming = timing.map { $0.title } == ["Short reset", "Weekly reset", "Allowance checked when needed"] && scheduled.first?.title == "Next allowance check" && scheduled.first?.at == 2000200000.0
|
|
283
|
+
print("Empty retry schedule handled: \(correctTiming)")
|
|
284
|
+
exit(normal != nil && attention != nil && liveUpdate && safeIdentity && correctTiming ? 0 : 1)
|
|
255
285
|
} else {
|
|
256
286
|
let app = NSApplication.shared
|
|
257
287
|
let delegate = MenuController(); app.delegate = delegate; app.run()
|
package/python/router.py
CHANGED
|
@@ -24,7 +24,7 @@ from pool import Pool, blocked, reset_time, failure_kind, file_lock
|
|
|
24
24
|
from launch import translate, RESUME_FIELDS
|
|
25
25
|
import settings
|
|
26
26
|
|
|
27
|
-
VERSION = "0.5.
|
|
27
|
+
VERSION = "0.5.3"
|
|
28
28
|
_support = Path.home() / "Library/Application Support"
|
|
29
29
|
_legacy = _support / "Codex Accounts"
|
|
30
30
|
_default_state = _legacy if (_legacy / "accounts").exists() else _support / "Relay"
|