@very_aq/codex-cli-web 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +228 -0
  3. package/README.zh-CN.md +228 -0
  4. package/package.json +38 -0
  5. package/server/dist/admin/userAdminRoutes.d.ts +7 -0
  6. package/server/dist/admin/userAdminRoutes.js +91 -0
  7. package/server/dist/admin/userAdminRoutes.js.map +1 -0
  8. package/server/dist/app.d.ts +22 -0
  9. package/server/dist/app.js +993 -0
  10. package/server/dist/app.js.map +1 -0
  11. package/server/dist/auth/adminInit.d.ts +41 -0
  12. package/server/dist/auth/adminInit.js +126 -0
  13. package/server/dist/auth/adminInit.js.map +1 -0
  14. package/server/dist/auth/bootstrapAdmin.d.ts +6 -0
  15. package/server/dist/auth/bootstrapAdmin.js +11 -0
  16. package/server/dist/auth/bootstrapAdmin.js.map +1 -0
  17. package/server/dist/auth/httpAuth.d.ts +16 -0
  18. package/server/dist/auth/httpAuth.js +31 -0
  19. package/server/dist/auth/httpAuth.js.map +1 -0
  20. package/server/dist/auth/password.d.ts +2 -0
  21. package/server/dist/auth/password.js +68 -0
  22. package/server/dist/auth/password.js.map +1 -0
  23. package/server/dist/auth/requireAdmin.d.ts +2 -0
  24. package/server/dist/auth/requireAdmin.js +14 -0
  25. package/server/dist/auth/requireAdmin.js.map +1 -0
  26. package/server/dist/auth/roles.d.ts +3 -0
  27. package/server/dist/auth/roles.js +13 -0
  28. package/server/dist/auth/roles.js.map +1 -0
  29. package/server/dist/auth/session.d.ts +24 -0
  30. package/server/dist/auth/session.js +127 -0
  31. package/server/dist/auth/session.js.map +1 -0
  32. package/server/dist/auth/sqlite/authDb.d.ts +18 -0
  33. package/server/dist/auth/sqlite/authDb.js +26 -0
  34. package/server/dist/auth/sqlite/authDb.js.map +1 -0
  35. package/server/dist/auth/sqlite/legacyImport.d.ts +22 -0
  36. package/server/dist/auth/sqlite/legacyImport.js +208 -0
  37. package/server/dist/auth/sqlite/legacyImport.js.map +1 -0
  38. package/server/dist/auth/sqlite/schema.d.ts +11 -0
  39. package/server/dist/auth/sqlite/schema.js +47 -0
  40. package/server/dist/auth/sqlite/schema.js.map +1 -0
  41. package/server/dist/auth/sqlite/sqliteUserStore.d.ts +12 -0
  42. package/server/dist/auth/sqlite/sqliteUserStore.js +194 -0
  43. package/server/dist/auth/sqlite/sqliteUserStore.js.map +1 -0
  44. package/server/dist/auth/userStore.d.ts +19 -0
  45. package/server/dist/auth/userStore.js +26 -0
  46. package/server/dist/auth/userStore.js.map +1 -0
  47. package/server/dist/auth/userTypes.d.ts +13 -0
  48. package/server/dist/auth/userTypes.js +3 -0
  49. package/server/dist/auth/userTypes.js.map +1 -0
  50. package/server/dist/chat/attachmentPathRedaction.d.ts +5 -0
  51. package/server/dist/chat/attachmentPathRedaction.js +67 -0
  52. package/server/dist/chat/attachmentPathRedaction.js.map +1 -0
  53. package/server/dist/chat/chatItemEnricher.d.ts +5 -0
  54. package/server/dist/chat/chatItemEnricher.js +40 -0
  55. package/server/dist/chat/chatItemEnricher.js.map +1 -0
  56. package/server/dist/chat/codexEventProjector.d.ts +33 -0
  57. package/server/dist/chat/codexEventProjector.js +482 -0
  58. package/server/dist/chat/codexEventProjector.js.map +1 -0
  59. package/server/dist/chat/contextUsageProjector.d.ts +10 -0
  60. package/server/dist/chat/contextUsageProjector.js +472 -0
  61. package/server/dist/chat/contextUsageProjector.js.map +1 -0
  62. package/server/dist/chat/fileChangeExtractor.d.ts +5 -0
  63. package/server/dist/chat/fileChangeExtractor.js +121 -0
  64. package/server/dist/chat/fileChangeExtractor.js.map +1 -0
  65. package/server/dist/chat/markdown/markdownAst.d.ts +5 -0
  66. package/server/dist/chat/markdown/markdownAst.js +154 -0
  67. package/server/dist/chat/markdown/markdownAst.js.map +1 -0
  68. package/server/dist/chat/systemToolCallSummary.d.ts +10 -0
  69. package/server/dist/chat/systemToolCallSummary.js +112 -0
  70. package/server/dist/chat/systemToolCallSummary.js.map +1 -0
  71. package/server/dist/chat/terminal/terminalPlainText.d.ts +14 -0
  72. package/server/dist/chat/terminal/terminalPlainText.js +139 -0
  73. package/server/dist/chat/terminal/terminalPlainText.js.map +1 -0
  74. package/server/dist/chat/textMetrics.d.ts +9 -0
  75. package/server/dist/chat/textMetrics.js +24 -0
  76. package/server/dist/chat/textMetrics.js.map +1 -0
  77. package/server/dist/chat/threadTurnsProjector.d.ts +12 -0
  78. package/server/dist/chat/threadTurnsProjector.js +292 -0
  79. package/server/dist/chat/threadTurnsProjector.js.map +1 -0
  80. package/server/dist/chat/todoPlanProjector.d.ts +8 -0
  81. package/server/dist/chat/todoPlanProjector.js +94 -0
  82. package/server/dist/chat/todoPlanProjector.js.map +1 -0
  83. package/server/dist/chat/todoPlanTypes.d.ts +21 -0
  84. package/server/dist/chat/todoPlanTypes.js +3 -0
  85. package/server/dist/chat/todoPlanTypes.js.map +1 -0
  86. package/server/dist/chat/types.d.ts +138 -0
  87. package/server/dist/chat/types.js +3 -0
  88. package/server/dist/chat/types.js.map +1 -0
  89. package/server/dist/cli/configArg.d.ts +21 -0
  90. package/server/dist/cli/configArg.js +70 -0
  91. package/server/dist/cli/configArg.js.map +1 -0
  92. package/server/dist/codex/appServerProcess.d.ts +24 -0
  93. package/server/dist/codex/appServerProcess.js +56 -0
  94. package/server/dist/codex/appServerProcess.js.map +1 -0
  95. package/server/dist/codex/cliArgs.d.ts +17 -0
  96. package/server/dist/codex/cliArgs.js +34 -0
  97. package/server/dist/codex/cliArgs.js.map +1 -0
  98. package/server/dist/codex/codexAppServer.d.ts +103 -0
  99. package/server/dist/codex/codexAppServer.js +206 -0
  100. package/server/dist/codex/codexAppServer.js.map +1 -0
  101. package/server/dist/codex/jsonl.d.ts +4 -0
  102. package/server/dist/codex/jsonl.js +23 -0
  103. package/server/dist/codex/jsonl.js.map +1 -0
  104. package/server/dist/codex/jsonrpc.d.ts +43 -0
  105. package/server/dist/codex/jsonrpc.js +96 -0
  106. package/server/dist/codex/jsonrpc.js.map +1 -0
  107. package/server/dist/config/serverConfig.d.ts +150 -0
  108. package/server/dist/config/serverConfig.js +64 -0
  109. package/server/dist/config/serverConfig.js.map +1 -0
  110. package/server/dist/env.d.ts +101 -0
  111. package/server/dist/env.js +523 -0
  112. package/server/dist/env.js.map +1 -0
  113. package/server/dist/history/http/historyRoutes.d.ts +18 -0
  114. package/server/dist/history/http/historyRoutes.js +67 -0
  115. package/server/dist/history/http/historyRoutes.js.map +1 -0
  116. package/server/dist/history/index.d.ts +24 -0
  117. package/server/dist/history/index.js +30 -0
  118. package/server/dist/history/index.js.map +1 -0
  119. package/server/dist/history/ingest/historyIngestService.d.ts +15 -0
  120. package/server/dist/history/ingest/historyIngestService.js +42 -0
  121. package/server/dist/history/ingest/historyIngestService.js.map +1 -0
  122. package/server/dist/history/projector/extractIds.d.ts +36 -0
  123. package/server/dist/history/projector/extractIds.js +111 -0
  124. package/server/dist/history/projector/extractIds.js.map +1 -0
  125. package/server/dist/history/projector/projectCodexEvent.d.ts +27 -0
  126. package/server/dist/history/projector/projectCodexEvent.js +845 -0
  127. package/server/dist/history/projector/projectCodexEvent.js.map +1 -0
  128. package/server/dist/history/query/historyQueryService.d.ts +34 -0
  129. package/server/dist/history/query/historyQueryService.js +170 -0
  130. package/server/dist/history/query/historyQueryService.js.map +1 -0
  131. package/server/dist/history/sqlite/schema.d.ts +11 -0
  132. package/server/dist/history/sqlite/schema.js +34 -0
  133. package/server/dist/history/sqlite/schema.js.map +1 -0
  134. package/server/dist/history/sqlite/sqliteHistoryStore.d.ts +69 -0
  135. package/server/dist/history/sqlite/sqliteHistoryStore.js +206 -0
  136. package/server/dist/history/sqlite/sqliteHistoryStore.js.map +1 -0
  137. package/server/dist/history/types.d.ts +29 -0
  138. package/server/dist/history/types.js +3 -0
  139. package/server/dist/history/types.js.map +1 -0
  140. package/server/dist/index.d.ts +1 -0
  141. package/server/dist/index.js +166 -0
  142. package/server/dist/index.js.map +1 -0
  143. package/server/dist/security/executionPolicy.d.ts +33 -0
  144. package/server/dist/security/executionPolicy.js +72 -0
  145. package/server/dist/security/executionPolicy.js.map +1 -0
  146. package/server/dist/security/origin.d.ts +11 -0
  147. package/server/dist/security/origin.js +40 -0
  148. package/server/dist/security/origin.js.map +1 -0
  149. package/server/dist/settings/sqliteUserSettingsStore.d.ts +12 -0
  150. package/server/dist/settings/sqliteUserSettingsStore.js +62 -0
  151. package/server/dist/settings/sqliteUserSettingsStore.js.map +1 -0
  152. package/server/dist/settings/userSettingsRoutes.d.ts +8 -0
  153. package/server/dist/settings/userSettingsRoutes.js +55 -0
  154. package/server/dist/settings/userSettingsRoutes.js.map +1 -0
  155. package/server/dist/settings/userSettingsStore.d.ts +19 -0
  156. package/server/dist/settings/userSettingsStore.js +26 -0
  157. package/server/dist/settings/userSettingsStore.js.map +1 -0
  158. package/server/dist/settings/userSettingsTypes.d.ts +70 -0
  159. package/server/dist/settings/userSettingsTypes.js +196 -0
  160. package/server/dist/settings/userSettingsTypes.js.map +1 -0
  161. package/server/dist/status/codexTaskTracker.d.ts +21 -0
  162. package/server/dist/status/codexTaskTracker.js +123 -0
  163. package/server/dist/status/codexTaskTracker.js.map +1 -0
  164. package/server/dist/status/threadContextUsage.d.ts +19 -0
  165. package/server/dist/status/threadContextUsage.js +229 -0
  166. package/server/dist/status/threadContextUsage.js.map +1 -0
  167. package/server/dist/threadList/threadListServerCache.d.ts +10 -0
  168. package/server/dist/threadList/threadListServerCache.js +42 -0
  169. package/server/dist/threadList/threadListServerCache.js.map +1 -0
  170. package/server/dist/tools/cwdSuggest.d.ts +11 -0
  171. package/server/dist/tools/cwdSuggest.js +128 -0
  172. package/server/dist/tools/cwdSuggest.js.map +1 -0
  173. package/server/dist/workspace/accessControl.d.ts +16 -0
  174. package/server/dist/workspace/accessControl.js +82 -0
  175. package/server/dist/workspace/accessControl.js.map +1 -0
  176. package/server/dist/workspace/sqliteUserWorkspaceStore.d.ts +12 -0
  177. package/server/dist/workspace/sqliteUserWorkspaceStore.js +82 -0
  178. package/server/dist/workspace/sqliteUserWorkspaceStore.js.map +1 -0
  179. package/server/dist/workspace/threadAccess.d.ts +19 -0
  180. package/server/dist/workspace/threadAccess.js +22 -0
  181. package/server/dist/workspace/threadAccess.js.map +1 -0
  182. package/server/dist/workspace/threadListVisibility.d.ts +25 -0
  183. package/server/dist/workspace/threadListVisibility.js +104 -0
  184. package/server/dist/workspace/threadListVisibility.js.map +1 -0
  185. package/server/dist/workspace/userWorkspaceRoutes.d.ts +7 -0
  186. package/server/dist/workspace/userWorkspaceRoutes.js +124 -0
  187. package/server/dist/workspace/userWorkspaceRoutes.js.map +1 -0
  188. package/server/dist/workspace/userWorkspaceStore.d.ts +12 -0
  189. package/server/dist/workspace/userWorkspaceStore.js +23 -0
  190. package/server/dist/workspace/userWorkspaceStore.js.map +1 -0
  191. package/server/dist/ws/socketIoBridge.d.ts +32 -0
  192. package/server/dist/ws/socketIoBridge.js +194 -0
  193. package/server/dist/ws/socketIoBridge.js.map +1 -0
  194. package/server/dist/ws/types.d.ts +113 -0
  195. package/server/dist/ws/types.js +3 -0
  196. package/server/dist/ws/types.js.map +1 -0
  197. package/server/dist/ws/wsHub.d.ts +119 -0
  198. package/server/dist/ws/wsHub.js +1259 -0
  199. package/server/dist/ws/wsHub.js.map +1 -0
  200. package/web/dist/assets/index-CY6cnwQz.js +174 -0
  201. package/web/dist/assets/index-DI7kJHr2.css +32 -0
  202. package/web/dist/favicon-mask.svg +9 -0
  203. package/web/dist/favicon.svg +26 -0
  204. package/web/dist/index.html +75 -0
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_USER_SETTINGS = void 0;
4
+ exports.normalizeUserSettings = normalizeUserSettings;
5
+ /**
6
+ * 默认用户配置(每次读取时应复制,避免引用污染)。
7
+ */
8
+ exports.DEFAULT_USER_SETTINGS = {
9
+ locale: "zh-CN",
10
+ theme: "light",
11
+ accentColor: null,
12
+ backgroundColor: null,
13
+ sidebarCollapsed: true,
14
+ compactView: true,
15
+ threadNameOverrides: {},
16
+ threadModelOverrides: {},
17
+ webModelDefaults: {},
18
+ customModels: [],
19
+ threadPermissionsOverrides: {},
20
+ threadCollaborationOverrides: {},
21
+ defaultWorkspace: null,
22
+ };
23
+ /**
24
+ * 判断输入是否为 plain object。
25
+ */
26
+ function isRecord(input) {
27
+ return typeof input === "object" && input !== null && !Array.isArray(input);
28
+ }
29
+ /**
30
+ * 规范化字符串;空串回退为 null。
31
+ */
32
+ function normalizeOptionalString(input) {
33
+ const normalized = typeof input === "string" ? input.trim() : "";
34
+ return normalized ? normalized : null;
35
+ }
36
+ /**
37
+ * 规范化字符串;空串回退为 undefined。
38
+ */
39
+ function normalizeOptionalStringAsUndefined(input) {
40
+ const normalized = typeof input === "string" ? input.trim() : "";
41
+ return normalized ? normalized : undefined;
42
+ }
43
+ /**
44
+ * 规范化语言配置;非法值统一回退到 `zh-CN`。
45
+ */
46
+ function normalizeLocale(input) {
47
+ const normalized = String(input ?? "").trim();
48
+ if (normalized === "en-US")
49
+ return "en-US";
50
+ return "zh-CN";
51
+ }
52
+ /**
53
+ * 去重并保序地规范化字符串数组。
54
+ */
55
+ function normalizeStringArray(input) {
56
+ if (!Array.isArray(input))
57
+ return [];
58
+ const seen = new Set();
59
+ const normalized = [];
60
+ for (const item of input) {
61
+ const value = String(item ?? "").trim();
62
+ if (!value)
63
+ continue;
64
+ if (seen.has(value))
65
+ continue;
66
+ seen.add(value);
67
+ normalized.push(value);
68
+ }
69
+ return normalized;
70
+ }
71
+ /**
72
+ * 规范化线程标题覆盖映射。
73
+ */
74
+ function normalizeThreadNameOverrides(input) {
75
+ if (!isRecord(input))
76
+ return {};
77
+ const out = {};
78
+ for (const [threadId, rawTitle] of Object.entries(input)) {
79
+ const normalizedThreadId = String(threadId ?? "").trim();
80
+ if (!normalizedThreadId)
81
+ continue;
82
+ const title = String(rawTitle ?? "").trim();
83
+ if (!title)
84
+ continue;
85
+ out[normalizedThreadId] = title;
86
+ }
87
+ return out;
88
+ }
89
+ /**
90
+ * 规范化线程模型覆盖映射。
91
+ */
92
+ function normalizeThreadModelOverrides(input) {
93
+ if (!isRecord(input))
94
+ return {};
95
+ const out = {};
96
+ for (const [threadId, rawOverride] of Object.entries(input)) {
97
+ const normalizedThreadId = String(threadId ?? "").trim();
98
+ if (!normalizedThreadId || !isRecord(rawOverride))
99
+ continue;
100
+ const model = normalizeOptionalStringAsUndefined(rawOverride.model);
101
+ const reasoningEffort = normalizeOptionalStringAsUndefined(rawOverride.reasoningEffort);
102
+ if (!model && !reasoningEffort)
103
+ continue;
104
+ out[normalizedThreadId] = { model, reasoningEffort };
105
+ }
106
+ return out;
107
+ }
108
+ /**
109
+ * 规范化 Web 默认模型配置。
110
+ */
111
+ function normalizeWebModelDefaults(input) {
112
+ if (!isRecord(input))
113
+ return {};
114
+ const model = normalizeOptionalStringAsUndefined(input.model);
115
+ const reasoningEffort = normalizeOptionalStringAsUndefined(input.reasoningEffort);
116
+ if (!model && !reasoningEffort)
117
+ return {};
118
+ return { model, reasoningEffort };
119
+ }
120
+ /**
121
+ * 规范化线程权限覆盖映射。
122
+ */
123
+ function normalizeThreadPermissionsOverrides(input) {
124
+ if (!isRecord(input))
125
+ return {};
126
+ const out = {};
127
+ for (const [threadId, rawOverride] of Object.entries(input)) {
128
+ const normalizedThreadId = String(threadId ?? "").trim();
129
+ if (!normalizedThreadId || !isRecord(rawOverride))
130
+ continue;
131
+ const approvalPolicyRaw = rawOverride.approvalPolicy;
132
+ const approvalPolicy = approvalPolicyRaw === "untrusted" ||
133
+ approvalPolicyRaw === "on-failure" ||
134
+ approvalPolicyRaw === "on-request" ||
135
+ approvalPolicyRaw === "never"
136
+ ? approvalPolicyRaw
137
+ : undefined;
138
+ const sandboxRaw = rawOverride.sandbox;
139
+ const sandbox = sandboxRaw === "read-only" || sandboxRaw === "workspace-write" || sandboxRaw === "danger-full-access" ? sandboxRaw : undefined;
140
+ if (!approvalPolicy && !sandbox)
141
+ continue;
142
+ out[normalizedThreadId] = { approvalPolicy, sandbox };
143
+ }
144
+ return out;
145
+ }
146
+ /**
147
+ * 规范化线程协作模式覆盖映射。
148
+ */
149
+ function normalizeThreadCollaborationOverrides(input) {
150
+ if (!isRecord(input))
151
+ return {};
152
+ const out = {};
153
+ for (const [threadId, rawOverride] of Object.entries(input)) {
154
+ const normalizedThreadId = String(threadId ?? "").trim();
155
+ if (!normalizedThreadId || !isRecord(rawOverride))
156
+ continue;
157
+ const mode = rawOverride.mode === "plan" || rawOverride.mode === "default" ? rawOverride.mode : null;
158
+ const rawSettings = isRecord(rawOverride.settings) ? rawOverride.settings : null;
159
+ const model = normalizeOptionalString(rawSettings?.model);
160
+ if (!mode || !model || !rawSettings)
161
+ continue;
162
+ const developerInstructions = typeof rawSettings.developer_instructions === "string" ? rawSettings.developer_instructions : null;
163
+ const reasoningEffort = mode === "plan" ? null : typeof rawSettings.reasoning_effort === "string" ? rawSettings.reasoning_effort : null;
164
+ out[normalizedThreadId] = {
165
+ mode,
166
+ settings: {
167
+ model,
168
+ developer_instructions: developerInstructions,
169
+ reasoning_effort: reasoningEffort,
170
+ },
171
+ };
172
+ }
173
+ return out;
174
+ }
175
+ /**
176
+ * 规范化用户配置输入,确保可安全入库与返回。
177
+ */
178
+ function normalizeUserSettings(input) {
179
+ const record = isRecord(input) ? input : {};
180
+ return {
181
+ locale: normalizeLocale(record.locale),
182
+ theme: record.theme === "dark" ? "dark" : "light",
183
+ accentColor: normalizeOptionalString(record.accentColor),
184
+ backgroundColor: normalizeOptionalString(record.backgroundColor),
185
+ sidebarCollapsed: typeof record.sidebarCollapsed === "boolean" ? record.sidebarCollapsed : true,
186
+ compactView: typeof record.compactView === "boolean" ? record.compactView : true,
187
+ threadNameOverrides: normalizeThreadNameOverrides(record.threadNameOverrides),
188
+ threadModelOverrides: normalizeThreadModelOverrides(record.threadModelOverrides),
189
+ webModelDefaults: normalizeWebModelDefaults(record.webModelDefaults),
190
+ customModels: normalizeStringArray(record.customModels),
191
+ threadPermissionsOverrides: normalizeThreadPermissionsOverrides(record.threadPermissionsOverrides),
192
+ threadCollaborationOverrides: normalizeThreadCollaborationOverrides(record.threadCollaborationOverrides),
193
+ defaultWorkspace: normalizeOptionalString(record.defaultWorkspace),
194
+ };
195
+ }
196
+ //# sourceMappingURL=userSettingsTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userSettingsTypes.js","sourceRoot":"","sources":["../../src/settings/userSettingsTypes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export type CodexNotification = {
2
+ method: string;
3
+ params: unknown;
4
+ };
5
+ export type CodexTaskSnapshot = {
6
+ busy: boolean;
7
+ activeTurnCount: number;
8
+ activeThreads: string[];
9
+ activeByThread: Record<string, number>;
10
+ lastEventAtMs: number | null;
11
+ };
12
+ export declare class CodexTaskTracker {
13
+ private readonly activeByThread;
14
+ private lastEventAtMs;
15
+ onNotification(n: CodexNotification): void;
16
+ getSnapshot(): CodexTaskSnapshot;
17
+ getActiveTurnIds(threadId: string): string[];
18
+ reset(): void;
19
+ private markActive;
20
+ private markComplete;
21
+ }
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CodexTaskTracker = void 0;
4
+ class CodexTaskTracker {
5
+ activeByThread = new Map();
6
+ lastEventAtMs = null;
7
+ onNotification(n) {
8
+ this.lastEventAtMs = Date.now();
9
+ const params = n.params;
10
+ const threadId = extractThreadId(params);
11
+ if (!threadId)
12
+ return;
13
+ // Codex app-server v2 emits `error` notifications with per-turn ids.
14
+ // If the server will not retry the turn, we can treat it as completion.
15
+ if (n.method === "error") {
16
+ const turnId = extractTurnId(params);
17
+ const willRetry = Boolean(params?.willRetry);
18
+ if (turnId && !willRetry)
19
+ this.markComplete(threadId, turnId);
20
+ return;
21
+ }
22
+ if (n.method === "item/started" || n.method === "turn/started") {
23
+ const turnId = extractTurnId(params);
24
+ if (!turnId)
25
+ return;
26
+ this.markActive(threadId, turnId);
27
+ return;
28
+ }
29
+ if (n.method === "turn/completed" ||
30
+ n.method === "turn/failed" ||
31
+ n.method === "turn/cancelled" ||
32
+ n.method === "turn/interrupted") {
33
+ const turnId = extractTurnId(params);
34
+ if (turnId) {
35
+ this.markComplete(threadId, turnId);
36
+ }
37
+ else {
38
+ this.activeByThread.delete(threadId);
39
+ }
40
+ return;
41
+ }
42
+ }
43
+ getSnapshot() {
44
+ const activeThreads = Array.from(this.activeByThread.keys()).sort();
45
+ const activeByThread = {};
46
+ let activeTurnCount = 0;
47
+ for (const [threadId, turns] of this.activeByThread.entries()) {
48
+ activeByThread[threadId] = turns.size;
49
+ activeTurnCount += turns.size;
50
+ }
51
+ return {
52
+ busy: activeTurnCount > 0,
53
+ activeTurnCount,
54
+ activeThreads,
55
+ activeByThread,
56
+ lastEventAtMs: this.lastEventAtMs,
57
+ };
58
+ }
59
+ getActiveTurnIds(threadId) {
60
+ const set = this.activeByThread.get(threadId);
61
+ if (!set)
62
+ return [];
63
+ return Array.from(set);
64
+ }
65
+ reset() {
66
+ this.activeByThread.clear();
67
+ this.lastEventAtMs = null;
68
+ }
69
+ markActive(threadId, turnId) {
70
+ const set = this.activeByThread.get(threadId) ?? new Set();
71
+ set.add(turnId);
72
+ this.activeByThread.set(threadId, set);
73
+ }
74
+ markComplete(threadId, turnId) {
75
+ const set = this.activeByThread.get(threadId);
76
+ if (!set)
77
+ return;
78
+ set.delete(turnId);
79
+ if (set.size === 0)
80
+ this.activeByThread.delete(threadId);
81
+ }
82
+ }
83
+ exports.CodexTaskTracker = CodexTaskTracker;
84
+ function extractThreadId(params) {
85
+ const p = params;
86
+ if (p && typeof p.threadId === "string")
87
+ return p.threadId;
88
+ if (p && typeof p.conversationId === "string")
89
+ return p.conversationId;
90
+ // Be liberal in what we accept: official app-server payloads sometimes use snake_case.
91
+ if (p && typeof p.thread_id === "string")
92
+ return p.thread_id;
93
+ if (p && typeof p.conversation_id === "string")
94
+ return p.conversation_id;
95
+ if (p && typeof p.thread?.id === "string")
96
+ return p.thread.id;
97
+ if (p && typeof p.conversation?.id === "string")
98
+ return p.conversation.id;
99
+ return null;
100
+ }
101
+ function extractTurnId(params) {
102
+ const p = params;
103
+ const candidates = [
104
+ p?.turnId,
105
+ p?.turn_id,
106
+ p?.turn?.id,
107
+ p?.turn,
108
+ p?.id,
109
+ p?.item?.turnId,
110
+ p?.item?.turn_id,
111
+ p?.item?.turn?.id,
112
+ ];
113
+ // Upstream event payloads are not fully stable; accept several known shapes.
114
+ for (const candidate of candidates) {
115
+ if (candidate === null || candidate === undefined)
116
+ continue;
117
+ const trimmed = String(candidate).trim();
118
+ if (trimmed)
119
+ return trimmed;
120
+ }
121
+ return null;
122
+ }
123
+ //# sourceMappingURL=codexTaskTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexTaskTracker.js","sourceRoot":"","sources":["../../src/status/codexTaskTracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 根据 thread 的 session 文件路径读取 context usage 百分比(带缓存)。
3
+ */
4
+ export declare function readThreadContextUsagePercentFromSessionPath(sessionPath: unknown): Promise<number | null>;
5
+ /**
6
+ * 线程上下文使用率读取器:
7
+ * - 读取 thread 对应 session 文件中的最新 token_count;
8
+ * - 输出与 CLI 一致口径的 `context usage` 百分比。
9
+ */
10
+ export declare class ThreadContextUsageReader {
11
+ /**
12
+ * 从 session 文件路径读取上下文使用率(百分比)。
13
+ */
14
+ readUsagePercent(sessionPath: unknown): Promise<number | null>;
15
+ }
16
+ /**
17
+ * 测试专用:清空缓存,避免 case 间互相污染。
18
+ */
19
+ export declare function clearThreadContextUsageCacheForTest(): void;
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ThreadContextUsageReader = void 0;
7
+ exports.readThreadContextUsagePercentFromSessionPath = readThreadContextUsagePercentFromSessionPath;
8
+ exports.clearThreadContextUsageCacheForTest = clearThreadContextUsageCacheForTest;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ // 基于 `path + mtime + size` 的轻量缓存,避免频繁 open_thread 时重复扫描大文件。
12
+ const threadContextUsageCacheByPath = new Map();
13
+ const SESSION_TAIL_SCAN_CHUNK_SIZE = 64 * 1024;
14
+ /**
15
+ * 判断值是否为可索引对象,避免误把 `null` / 数组当成对象读取。
16
+ */
17
+ function isRecord(value) {
18
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
19
+ }
20
+ /**
21
+ * 从对象中按 key 读取嵌套记录;任一层缺失则返回 `null`。
22
+ */
23
+ function readNestedRecord(root, keys) {
24
+ if (!isRecord(root))
25
+ return null;
26
+ let currentValue = root;
27
+ for (const key of keys) {
28
+ const nestedValue = currentValue[key];
29
+ if (!isRecord(nestedValue))
30
+ return null;
31
+ currentValue = nestedValue;
32
+ }
33
+ return currentValue;
34
+ }
35
+ /**
36
+ * 读取对象上的 number 字段(支持 camelCase / snake_case);读取失败返回 `null`。
37
+ */
38
+ function pickNumber(input, candidateKeys) {
39
+ if (!isRecord(input))
40
+ return null;
41
+ for (const key of candidateKeys) {
42
+ const rawValue = input[key];
43
+ if (typeof rawValue !== "number")
44
+ continue;
45
+ if (!Number.isFinite(rawValue))
46
+ continue;
47
+ return rawValue;
48
+ }
49
+ return null;
50
+ }
51
+ /**
52
+ * 将百分比值归一化到 `0..100` 并保留 1 位小数。
53
+ */
54
+ function normalizePercent(rawPercent) {
55
+ if (!Number.isFinite(rawPercent))
56
+ return null;
57
+ if (rawPercent < 0)
58
+ return null;
59
+ const clampedPercent = Math.max(0, Math.min(100, rawPercent));
60
+ return Math.round(clampedPercent * 10) / 10;
61
+ }
62
+ /**
63
+ * 从单条 session jsonl 记录中提取 context usage 百分比。
64
+ *
65
+ * 支持两类 token_count 结构:
66
+ * 1) event_msg: `{ payload: { type: "token_count", info: ... } }`
67
+ * 2) ws event : `{ payload: { method: "codex/event/token_count", params: { msg: { info: ... } } } }`
68
+ */
69
+ function extractContextUsagePercentFromSessionLine(lineData) {
70
+ if (!isRecord(lineData))
71
+ return null;
72
+ const payload = lineData.payload;
73
+ if (!isRecord(payload))
74
+ return null;
75
+ // 结构 1:session 事件落盘格式。
76
+ const directInfo = payload.type === "token_count" && isRecord(payload.info) ? payload.info : null;
77
+ if (directInfo) {
78
+ const directPercent = extractPercentFromTokenCountInfo(directInfo);
79
+ if (directPercent !== null)
80
+ return directPercent;
81
+ }
82
+ // 结构 2:ws/raw event 包装格式。
83
+ const method = typeof payload.method === "string" ? payload.method : "";
84
+ if (method !== "codex/event/token_count")
85
+ return null;
86
+ const wrappedInfo = readNestedRecord(payload, ["params", "msg", "info"]) ?? readNestedRecord(payload, ["params", "info"]);
87
+ if (!wrappedInfo)
88
+ return null;
89
+ return extractPercentFromTokenCountInfo(wrappedInfo);
90
+ }
91
+ /**
92
+ * 从 token_count.info 结构中提取百分比:`last_token_usage.input_tokens / model_context_window`。
93
+ *
94
+ * 兼容说明:
95
+ * - 优先 `last_token_usage`(更接近 CLI 实时“上下文占用”口径);
96
+ * - 若缺失,再回退 `total_token_usage` 兼容旧结构。
97
+ */
98
+ function extractPercentFromTokenCountInfo(tokenCountInfo) {
99
+ if (!isRecord(tokenCountInfo))
100
+ return null;
101
+ const lastTokenUsageRecord = readNestedRecord(tokenCountInfo, ["last_token_usage"]) ??
102
+ readNestedRecord(tokenCountInfo, ["lastTokenUsage"]);
103
+ const totalTokenUsageRecord = readNestedRecord(tokenCountInfo, ["total_token_usage"]) ??
104
+ readNestedRecord(tokenCountInfo, ["totalTokenUsage"]);
105
+ const preferredTokenUsageRecord = lastTokenUsageRecord ?? totalTokenUsageRecord;
106
+ if (!preferredTokenUsageRecord)
107
+ return null;
108
+ const inputTokens = pickNumber(preferredTokenUsageRecord, ["input_tokens", "inputTokens"]);
109
+ const modelContextWindow = pickNumber(tokenCountInfo, ["model_context_window", "modelContextWindow"]);
110
+ if (inputTokens === null || modelContextWindow === null)
111
+ return null;
112
+ if (inputTokens < 0 || modelContextWindow <= 0)
113
+ return null;
114
+ // input_tokens 理论上不应大于 context window;超出时判为无效,避免误报 100%。
115
+ if (inputTokens > modelContextWindow)
116
+ return null;
117
+ return normalizePercent((inputTokens / modelContextWindow) * 100);
118
+ }
119
+ /**
120
+ * 尝试从单行 jsonl 文本中提取 context usage 百分比。
121
+ */
122
+ function readContextUsagePercentFromLineText(lineText) {
123
+ const normalizedLineText = lineText.trim();
124
+ if (!normalizedLineText)
125
+ return null;
126
+ let parsedLineData;
127
+ try {
128
+ parsedLineData = JSON.parse(normalizedLineText);
129
+ }
130
+ catch {
131
+ return null;
132
+ }
133
+ return extractContextUsagePercentFromSessionLine(parsedLineData);
134
+ }
135
+ /**
136
+ * 从 session jsonl 尾部反向分块扫描,返回“最后一条可解析 token_count 记录”的 context usage 百分比。
137
+ */
138
+ async function readLatestContextUsagePercentFromSessionFile(sessionPath, fileSizeHint) {
139
+ let sessionFileHandle = null;
140
+ try {
141
+ sessionFileHandle = await fs_1.default.promises.open(sessionPath, "r");
142
+ // 优先复用外层 stat 的 size,避免重复 stat 系统调用。
143
+ const hintedSize = typeof fileSizeHint === "number" && Number.isFinite(fileSizeHint) ? Math.max(0, Math.floor(fileSizeHint)) : -1;
144
+ let readEnd = hintedSize >= 0 ? hintedSize : (await sessionFileHandle.stat()).size;
145
+ if (readEnd <= 0)
146
+ return null;
147
+ let carryPrefix = "";
148
+ while (readEnd > 0) {
149
+ const readStart = Math.max(0, readEnd - SESSION_TAIL_SCAN_CHUNK_SIZE);
150
+ const readLength = readEnd - readStart;
151
+ const readBuffer = Buffer.allocUnsafe(readLength);
152
+ const { bytesRead } = await sessionFileHandle.read(readBuffer, 0, readLength, readStart);
153
+ if (bytesRead <= 0)
154
+ break;
155
+ const chunkText = readBuffer.subarray(0, bytesRead).toString("utf8");
156
+ const combinedText = chunkText + carryPrefix;
157
+ const chunkLines = combinedText.split(/\r?\n/);
158
+ carryPrefix = readStart > 0 ? (chunkLines.shift() ?? "") : "";
159
+ for (let lineIndex = chunkLines.length - 1; lineIndex >= 0; lineIndex -= 1) {
160
+ const parsedPercent = readContextUsagePercentFromLineText(chunkLines[lineIndex] ?? "");
161
+ if (parsedPercent !== null)
162
+ return parsedPercent;
163
+ }
164
+ readEnd = readStart;
165
+ }
166
+ // 最前面的残余文本(文件开头行)也尝试解析一次。
167
+ return readContextUsagePercentFromLineText(carryPrefix);
168
+ }
169
+ finally {
170
+ await sessionFileHandle?.close().catch(() => undefined);
171
+ }
172
+ }
173
+ /**
174
+ * 根据 thread 的 session 文件路径读取 context usage 百分比(带缓存)。
175
+ */
176
+ async function readThreadContextUsagePercentFromSessionPath(sessionPath) {
177
+ if (typeof sessionPath !== "string")
178
+ return null;
179
+ const normalizedSessionPath = path_1.default.resolve(sessionPath.trim());
180
+ if (!normalizedSessionPath)
181
+ return null;
182
+ let sessionStat;
183
+ try {
184
+ sessionStat = await fs_1.default.promises.stat(normalizedSessionPath);
185
+ }
186
+ catch {
187
+ return null;
188
+ }
189
+ if (!sessionStat.isFile())
190
+ return null;
191
+ const cachedEntry = threadContextUsageCacheByPath.get(normalizedSessionPath);
192
+ if (cachedEntry && cachedEntry.mtimeMs === sessionStat.mtimeMs && cachedEntry.size === sessionStat.size) {
193
+ return cachedEntry.percent;
194
+ }
195
+ let parsedPercent = null;
196
+ try {
197
+ parsedPercent = await readLatestContextUsagePercentFromSessionFile(normalizedSessionPath, sessionStat.size);
198
+ }
199
+ catch {
200
+ parsedPercent = null;
201
+ }
202
+ threadContextUsageCacheByPath.set(normalizedSessionPath, {
203
+ mtimeMs: sessionStat.mtimeMs,
204
+ size: sessionStat.size,
205
+ percent: parsedPercent,
206
+ });
207
+ return parsedPercent;
208
+ }
209
+ /**
210
+ * 线程上下文使用率读取器:
211
+ * - 读取 thread 对应 session 文件中的最新 token_count;
212
+ * - 输出与 CLI 一致口径的 `context usage` 百分比。
213
+ */
214
+ class ThreadContextUsageReader {
215
+ /**
216
+ * 从 session 文件路径读取上下文使用率(百分比)。
217
+ */
218
+ async readUsagePercent(sessionPath) {
219
+ return readThreadContextUsagePercentFromSessionPath(sessionPath);
220
+ }
221
+ }
222
+ exports.ThreadContextUsageReader = ThreadContextUsageReader;
223
+ /**
224
+ * 测试专用:清空缓存,避免 case 间互相污染。
225
+ */
226
+ function clearThreadContextUsageCacheForTest() {
227
+ threadContextUsageCacheByPath.clear();
228
+ }
229
+ //# sourceMappingURL=threadContextUsage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threadContextUsage.js","sourceRoot":"","sources":["../../src/status/threadContextUsage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export type ThreadListServerCacheOptions = {
2
+ ttlMs?: number;
3
+ nowMs?: () => number;
4
+ };
5
+ export type ThreadListServerCache<T> = {
6
+ get: () => T[] | null;
7
+ set: (threads: T[]) => void;
8
+ clear: () => void;
9
+ };
10
+ export declare function createThreadListServerCache<T>(options?: ThreadListServerCacheOptions): ThreadListServerCache<T>;