codex-flow 2.1.13__py3-none-any.whl

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 (113) hide show
  1. codex_flow/__init__.py +28 -0
  2. codex_flow/__main__.py +9 -0
  3. codex_flow/cli.py +242 -0
  4. codex_flow/data/LICENSE +21 -0
  5. codex_flow/data/README.en.md +303 -0
  6. codex_flow/data/README.md +305 -0
  7. codex_flow/data/VERSION +1 -0
  8. codex_flow/data/apps/chatgpt-mcp/README.md +86 -0
  9. codex_flow/data/apps/chatgpt-mcp/__init__.py +1 -0
  10. codex_flow/data/apps/chatgpt-mcp/adapter.py +458 -0
  11. codex_flow/data/apps/chatgpt-mcp/server.py +358 -0
  12. codex_flow/data/apps/chatgpt-mcp/widget.html +927 -0
  13. codex_flow/data/apps/macos-overlay/README.en.md +121 -0
  14. codex_flow/data/apps/macos-overlay/README.md +123 -0
  15. codex_flow/data/apps/macos-overlay/Sources/Controllers/OverlayRuntimeState.swift +126 -0
  16. codex_flow/data/apps/macos-overlay/Sources/Controllers/OverlayScreenGeometry.swift +82 -0
  17. codex_flow/data/apps/macos-overlay/Sources/Controllers/OverlayWindowController.swift +1052 -0
  18. codex_flow/data/apps/macos-overlay/Sources/Localization.swift +197 -0
  19. codex_flow/data/apps/macos-overlay/Sources/Models/TelemetryData.swift +1557 -0
  20. codex_flow/data/apps/macos-overlay/Sources/Services/AccountSnapshotService.swift +1101 -0
  21. codex_flow/data/apps/macos-overlay/Sources/Services/FlowPilotInstanceLock.swift +153 -0
  22. codex_flow/data/apps/macos-overlay/Sources/Services/IPCServer.swift +298 -0
  23. codex_flow/data/apps/macos-overlay/Sources/Services/TelemetryQueryEngine.swift +800 -0
  24. codex_flow/data/apps/macos-overlay/Sources/Services/TelemetryWatcher.swift +135 -0
  25. codex_flow/data/apps/macos-overlay/Sources/Services/UpdateService.swift +610 -0
  26. codex_flow/data/apps/macos-overlay/Sources/Views/AccountView.swift +610 -0
  27. codex_flow/data/apps/macos-overlay/Sources/Views/AnalyticsView.swift +566 -0
  28. codex_flow/data/apps/macos-overlay/Sources/Views/AutostartView.swift +293 -0
  29. codex_flow/data/apps/macos-overlay/Sources/Views/BubbleView.swift +317 -0
  30. codex_flow/data/apps/macos-overlay/Sources/Views/HistoryView.swift +1124 -0
  31. codex_flow/data/apps/macos-overlay/Sources/Views/HoverRevealText.swift +165 -0
  32. codex_flow/data/apps/macos-overlay/Sources/Views/InspectorSkillsToolsView.swift +121 -0
  33. codex_flow/data/apps/macos-overlay/Sources/Views/LogoView.swift +182 -0
  34. codex_flow/data/apps/macos-overlay/Sources/Views/SleekSwitch.swift +117 -0
  35. codex_flow/data/apps/macos-overlay/Sources/Views/StrategyModeView.swift +561 -0
  36. codex_flow/data/apps/macos-overlay/Sources/Views/SummaryView.swift +1273 -0
  37. codex_flow/data/apps/macos-overlay/Sources/Views/UpdateView.swift +352 -0
  38. codex_flow/data/apps/macos-overlay/Sources/main.swift +340 -0
  39. codex_flow/data/apps/macos-overlay/Tests/OverlayScreenGeometryTests.swift +163 -0
  40. codex_flow/data/apps/macos-overlay/Tests/TelemetryPhase1ContractTests.swift +357 -0
  41. codex_flow/data/apps/macos-overlay/Tests/TelemetryQueryEngineConcurrencyTests.swift +221 -0
  42. codex_flow/data/apps/macos-overlay/Tests/TelemetryQuotaSelectionTests.swift +158 -0
  43. codex_flow/data/apps/macos-overlay/Tests/TelemetryWorkerTokenTests.swift +122 -0
  44. codex_flow/data/apps/macos-overlay/build.sh +75 -0
  45. codex_flow/data/benchmark/corpus.json +103 -0
  46. codex_flow/data/benchmark/manifest.example.json +41 -0
  47. codex_flow/data/benchmark/manifest.schema.json +137 -0
  48. codex_flow/data/benchmark/prices/gpt-5.6-2026-08-30.json +5 -0
  49. codex_flow/data/benchmark/profiles.json +90 -0
  50. codex_flow/data/benchmark/schema.json +77 -0
  51. codex_flow/data/benchmark/tasks.json +50 -0
  52. codex_flow/data/completions/codex-flow.bash +34 -0
  53. codex_flow/data/completions/codex-flow.zsh +52 -0
  54. codex_flow/data/glama.json +6 -0
  55. codex_flow/data/install-release.ps1 +126 -0
  56. codex_flow/data/install-release.sh +155 -0
  57. codex_flow/data/install.ps1 +349 -0
  58. codex_flow/data/install.sh +362 -0
  59. codex_flow/data/policy/benchmark.toml +49 -0
  60. codex_flow/data/policy/defaults.toml +70 -0
  61. codex_flow/data/scripts/analyze-benchmark.py +510 -0
  62. codex_flow/data/scripts/benchmark-local.py +171 -0
  63. codex_flow/data/scripts/check-recommendation.py +277 -0
  64. codex_flow/data/scripts/doctor.py +449 -0
  65. codex_flow/data/scripts/generate-release-manifest.py +74 -0
  66. codex_flow/data/scripts/localization.py +192 -0
  67. codex_flow/data/scripts/manage-hooks.py +448 -0
  68. codex_flow/data/scripts/manage-instructions.py +389 -0
  69. codex_flow/data/scripts/manage-shell.py +151 -0
  70. codex_flow/data/scripts/materialize-corpus.py +193 -0
  71. codex_flow/data/scripts/menu.py +646 -0
  72. codex_flow/data/scripts/migrations/0001_update_settings.py +80 -0
  73. codex_flow/data/scripts/package-release.py +132 -0
  74. codex_flow/data/scripts/render-benchmark-report.py +292 -0
  75. codex_flow/data/scripts/run-benchmark.py +829 -0
  76. codex_flow/data/scripts/strategies/__init__.py +28 -0
  77. codex_flow/data/scripts/strategies/balanced.py +115 -0
  78. codex_flow/data/scripts/strategies/base.py +363 -0
  79. codex_flow/data/scripts/strategies/efficient.py +158 -0
  80. codex_flow/data/scripts/strategies/lifecycle_runtime.py +590 -0
  81. codex_flow/data/scripts/strategies/quality.py +209 -0
  82. codex_flow/data/scripts/strategies/speed.py +108 -0
  83. codex_flow/data/scripts/strategies/task_budget_runtime.py +644 -0
  84. codex_flow/data/scripts/strategies/task_phase_runtime.py +341 -0
  85. codex_flow/data/scripts/strategies/work_unit_runtime.py +421 -0
  86. codex_flow/data/scripts/strategy_runtime.py +1091 -0
  87. codex_flow/data/scripts/telemetry.py +400 -0
  88. codex_flow/data/scripts/telemetry_core/__init__.py +192 -0
  89. codex_flow/data/scripts/telemetry_core/app_server.py +1192 -0
  90. codex_flow/data/scripts/telemetry_core/collector.py +1247 -0
  91. codex_flow/data/scripts/telemetry_core/common.py +421 -0
  92. codex_flow/data/scripts/telemetry_core/latency.py +593 -0
  93. codex_flow/data/scripts/telemetry_core/query.py +427 -0
  94. codex_flow/data/scripts/telemetry_core/quota_ledger.py +598 -0
  95. codex_flow/data/scripts/telemetry_core/render.py +460 -0
  96. codex_flow/data/scripts/telemetry_core/repair.py +223 -0
  97. codex_flow/data/scripts/ui.py +266 -0
  98. codex_flow/data/scripts/update-homebrew-formula.py +146 -0
  99. codex_flow/data/scripts/update_runtime_config.py +134 -0
  100. codex_flow/data/scripts/updater.py +1718 -0
  101. codex_flow/data/smithery.yaml +18 -0
  102. codex_flow/data/templates/agents/worker-explorer.toml +24 -0
  103. codex_flow/data/templates/agents/worker-implementer.toml +49 -0
  104. codex_flow/data/templates/agents/worker-reviewer.toml +25 -0
  105. codex_flow/data/templates/flow-pilot-instructions.md +35 -0
  106. codex_flow/data/templates/skills/flow-pilot/SKILL.md +577 -0
  107. codex_flow/mcp.py +35 -0
  108. codex_flow-2.1.13.dist-info/METADATA +342 -0
  109. codex_flow-2.1.13.dist-info/RECORD +113 -0
  110. codex_flow-2.1.13.dist-info/WHEEL +5 -0
  111. codex_flow-2.1.13.dist-info/entry_points.txt +3 -0
  112. codex_flow-2.1.13.dist-info/licenses/LICENSE +21 -0
  113. codex_flow-2.1.13.dist-info/top_level.txt +1 -0
@@ -0,0 +1,197 @@
1
+ import Foundation
2
+ import Combine
3
+
4
+ public enum AppLanguage: String {
5
+ case zh
6
+ case en
7
+ }
8
+
9
+ public final class AppLocalization: ObservableObject {
10
+ public static let shared = AppLocalization()
11
+
12
+ @Published public private(set) var language: AppLanguage
13
+ private var refreshTimer: Timer?
14
+
15
+ private init() {
16
+ language = Self.resolveLanguage()
17
+ refreshTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
18
+ guard let self = self else { return }
19
+ let resolved = Self.resolveLanguage()
20
+ if resolved != self.language {
21
+ self.language = resolved
22
+ }
23
+ }
24
+ }
25
+
26
+ deinit {
27
+ refreshTimer?.invalidate()
28
+ }
29
+
30
+ public func text(_ english: String, _ chinese: String) -> String {
31
+ language == .zh ? chinese : english
32
+ }
33
+
34
+ public static func resolveLanguage() -> AppLanguage {
35
+ let env = ProcessInfo.processInfo.environment
36
+ if let rawOverride = env["CODEX_FLOW_LANGUAGE"], !rawOverride.isEmpty {
37
+ return resolve(normalize(rawOverride) ?? "auto")
38
+ }
39
+ return resolve(configuredLanguage())
40
+ }
41
+
42
+ public static func configuredLanguage() -> String {
43
+ let env = ProcessInfo.processInfo.environment
44
+ let home = FileManager.default.homeDirectoryForCurrentUser
45
+ let codexHome = env["CODEX_HOME"] ?? home.appendingPathComponent(".codex").path
46
+ let policy = URL(fileURLWithPath: codexHome).appendingPathComponent("codex-flow.toml")
47
+ guard let text = try? String(contentsOf: policy, encoding: .utf8) else { return "auto" }
48
+
49
+ var inUI = false
50
+ for rawLine in text.components(separatedBy: .newlines) {
51
+ let line = rawLine.trimmingCharacters(in: .whitespacesAndNewlines)
52
+ if line.hasPrefix("[") && line.hasSuffix("]") {
53
+ inUI = line == "[ui]"
54
+ continue
55
+ }
56
+ guard inUI else { continue }
57
+ let noComment = line.split(separator: "#", maxSplits: 1, omittingEmptySubsequences: false)[0]
58
+ .trimmingCharacters(in: .whitespacesAndNewlines)
59
+ guard let eq = noComment.firstIndex(of: "=") else { continue }
60
+ let key = noComment[..<eq].trimmingCharacters(in: .whitespacesAndNewlines)
61
+ guard key == "language" else { continue }
62
+ let rawValue = noComment[noComment.index(after: eq)...]
63
+ .trimmingCharacters(in: .whitespacesAndNewlines)
64
+ .trimmingCharacters(in: CharacterSet(charactersIn: "\"'"))
65
+ return normalize(rawValue) ?? "auto"
66
+ }
67
+ return "auto"
68
+ }
69
+
70
+ public static func systemLanguage() -> AppLanguage {
71
+ for candidate in Locale.preferredLanguages {
72
+ if let normalized = normalize(candidate), normalized != "auto" {
73
+ return normalized == "zh" ? .zh : .en
74
+ }
75
+ }
76
+
77
+ let env = ProcessInfo.processInfo.environment
78
+ for key in ["LC_ALL", "LC_MESSAGES", "LANGUAGE", "LANG"] {
79
+ if let normalized = normalize(env[key]), normalized != "auto" {
80
+ return normalized == "zh" ? .zh : .en
81
+ }
82
+ }
83
+ return .en
84
+ }
85
+
86
+ private static func resolve(_ normalized: String) -> AppLanguage {
87
+ switch normalized {
88
+ case "zh": return .zh
89
+ case "en": return .en
90
+ default: return systemLanguage()
91
+ }
92
+ }
93
+
94
+ private static func normalize(_ raw: String?) -> String? {
95
+ let value = (raw ?? "")
96
+ .trimmingCharacters(in: .whitespacesAndNewlines)
97
+ .lowercased()
98
+ .replacingOccurrences(of: "_", with: "-")
99
+ if value.isEmpty || ["auto", "system", "default"].contains(value) { return "auto" }
100
+ if value == "zh" || value.hasPrefix("zh-") || value.hasPrefix("chinese") { return "zh" }
101
+ if value == "en" || value.hasPrefix("en-") || value.hasPrefix("english") { return "en" }
102
+ return nil
103
+ }
104
+ }
105
+
106
+ private enum FlowPilotDateFormatters {
107
+ static let lock = NSLock()
108
+ static let clock = make("HH:mm")
109
+ static let dateTime = make("MM-dd HH:mm")
110
+ static let fullDateTime = make("yyyy-MM-dd HH:mm")
111
+
112
+ private static func make(_ format: String) -> DateFormatter {
113
+ let formatter = DateFormatter()
114
+ formatter.dateFormat = format
115
+ return formatter
116
+ }
117
+
118
+ static func string(from date: Date, format: DateFormatter) -> String {
119
+ lock.lock()
120
+ defer { lock.unlock() }
121
+ // Locale and time zone can change while a long-running menu-bar app is
122
+ // alive, so refresh those lightweight properties while reusing the
123
+ // expensive formatter instances themselves.
124
+ format.locale = Locale.current
125
+ format.timeZone = TimeZone.current
126
+ return format.string(from: date)
127
+ }
128
+ }
129
+
130
+ @inline(__always)
131
+ public func L(_ english: String, _ chinese: String) -> String {
132
+ AppLocalization.shared.text(english, chinese)
133
+ }
134
+
135
+ /// User-facing local date/time with a calendar date. Same-year timestamps stay
136
+ /// compact; cross-year timestamps include the year to avoid ambiguity.
137
+ public func formatLocalDateTime(_ date: Date) -> String {
138
+ let currentYear = Calendar.current.component(.year, from: Date())
139
+ let targetYear = Calendar.current.component(.year, from: date)
140
+ let formatter = currentYear == targetYear
141
+ ? FlowPilotDateFormatters.dateTime
142
+ : FlowPilotDateFormatters.fullDateTime
143
+ return FlowPilotDateFormatters.string(from: date, format: formatter)
144
+ }
145
+
146
+ public func localizedRole(_ role: String) -> String {
147
+ switch role.lowercased() {
148
+ case "parent": return L("parent", "父 Agent")
149
+ case "worker", "subagent": return L("worker", "Worker")
150
+ default: return role
151
+ }
152
+ }
153
+
154
+ public extension OverlayTab {
155
+ var localizedTitle: String {
156
+ switch self {
157
+ case .inspector: return L("Inspector", "任务")
158
+ case .history: return L("History", "历史")
159
+ case .analytics: return L("Analytics", "统计")
160
+ }
161
+ }
162
+ }
163
+
164
+ public extension QuotaWindow {
165
+ /// User-facing reset time deliberately includes a calendar date. A bare
166
+ /// clock time is ambiguous for weekly windows and was especially confusing
167
+ /// around midnight/year boundaries.
168
+ var localizedFormattedResetsAt: String? {
169
+ guard let r = resetsAt, r > 0 else { return nil }
170
+ let date = Date(timeIntervalSince1970: r > 1_000_000_000_000 ? r / 1000.0 : r)
171
+ if date <= Date() {
172
+ return L("resets now", "立即重置")
173
+ }
174
+
175
+ let value = formatLocalDateTime(date)
176
+ return L("resets \(value)", "\(value) 重置")
177
+ }
178
+ }
179
+
180
+ public extension TaskRun {
181
+ var localizedFormattedDate: String {
182
+ guard let s = startedAtMs else { return "--:--" }
183
+ let date = Date(timeIntervalSince1970: s / 1000.0)
184
+ if Calendar.current.isDateInToday(date) {
185
+ let value = FlowPilotDateFormatters.string(from: date, format: FlowPilotDateFormatters.clock)
186
+ return L("Today \(value)", "今天 \(value)")
187
+ }
188
+ return FlowPilotDateFormatters.string(from: date, format: FlowPilotDateFormatters.dateTime)
189
+ }
190
+ }
191
+
192
+ public extension ChatSession {
193
+ var localizedRunsSummary: String {
194
+ let count = runs.count
195
+ return count == 1 ? L("1 session", "1 次会话") : L("\(count) sessions", "\(count) 轮会话")
196
+ }
197
+ }