minecodex 1.2.2 → 2.0.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.
Files changed (87) hide show
  1. package/README.md +9 -3
  2. package/features/images/README.md +16 -98
  3. package/features/images/codex-feature.json +6 -23
  4. package/features/images/src/library-prompt-page.mjs +239 -0
  5. package/features/model-slider/THIRD_PARTY_NOTICES.md +1 -1
  6. package/features/notes/DESIGN.md +66 -0
  7. package/features/notes/README.md +18 -99
  8. package/features/notes/assets/icons/book-open-nav.svg +15 -0
  9. package/features/notes/assets/icons/book-open.svg +16 -0
  10. package/features/notes/assets/native-emojis.json +1 -0
  11. package/features/notes/assets/native-prompt-icons.json +28 -0
  12. package/features/notes/codex-feature.json +12 -70
  13. package/features/notes/src/main.mjs +2 -2
  14. package/features/notes/src/product.mjs +287 -613
  15. package/features/notes/src/prompt-schema.mjs +117 -0
  16. package/features/notes/src/quick-prompts-page.mjs +1559 -0
  17. package/features/notes/src/quick-prompts-server.mjs +167 -0
  18. package/features/session-status/DESIGN.md +10 -2
  19. package/features/session-status/README.md +8 -4
  20. package/features/session-status/src/session-status.mjs +268 -24
  21. package/features/sidebar-focus/DESIGN.md +16 -0
  22. package/features/sidebar-focus/codex-feature.json +20 -0
  23. package/features/sidebar-focus/src/sidebar-focus.mjs +134 -0
  24. package/features/sidebar-focus/vendor/lucide-LICENSE +43 -0
  25. package/features/unread-inbox/DESIGN.md +28 -0
  26. package/features/unread-inbox/codex-feature.json +20 -0
  27. package/features/unread-inbox/src/unread-inbox.mjs +360 -0
  28. package/features/usage-meter/DESIGN.md +49 -0
  29. package/features/usage-meter/README.md +18 -0
  30. package/features/usage-meter/codex-feature.json +13 -0
  31. package/features/usage-meter/src/usage-meter.mjs +200 -0
  32. package/package.json +17 -5
  33. package/packages/cli/src/config.mjs +4 -1
  34. package/packages/cli/src/control-server.mjs +2 -2
  35. package/packages/runtime-host/src/codex-injection.mjs +38 -3
  36. package/packages/runtime-host/src/codex-runtime.mjs +41 -20
  37. package/packages/runtime-host/src/feature-registry.mjs +1 -0
  38. package/packages/runtime-host/src/session-status-reader.mjs +40 -16
  39. package/features/notes/assets/icons/circle.svg +0 -15
  40. package/features/notes/assets/icons/ellipsis.svg +0 -17
  41. package/features/notes/assets/icons/external-link.svg +0 -17
  42. package/features/notes/assets/icons/list-todo.svg +0 -19
  43. package/features/notes/assets/icons/message-square-quote.svg +0 -17
  44. package/features/notes/assets/icons/paperclip.svg +0 -15
  45. package/features/notes/assets/icons/star-off.svg +0 -17
  46. package/features/notes/assets/icons/star.svg +0 -15
  47. package/features/notes/assets/icons/sticky-note.svg +0 -16
  48. package/features/notes/assets/icons/trash-2.svg +0 -19
  49. package/features/notes/src/http-server.mjs +0 -580
  50. package/features/notes/web/app.js +0 -1202
  51. package/features/notes/web/codex-artifact-document.svg +0 -1
  52. package/features/notes/web/codex-attachment.svg +0 -1
  53. package/features/notes/web/codex-build.svg +0 -1
  54. package/features/notes/web/codex-code.svg +0 -1
  55. package/features/notes/web/codex-cplusplus.svg +0 -1
  56. package/features/notes/web/codex-css.svg +0 -1
  57. package/features/notes/web/codex-document.svg +0 -1
  58. package/features/notes/web/codex-file.svg +0 -1
  59. package/features/notes/web/codex-folder.svg +0 -1
  60. package/features/notes/web/codex-hashes.svg +0 -1
  61. package/features/notes/web/codex-html.svg +0 -1
  62. package/features/notes/web/codex-image.svg +0 -1
  63. package/features/notes/web/codex-java.svg +0 -1
  64. package/features/notes/web/codex-javascript.svg +0 -1
  65. package/features/notes/web/codex-json.svg +0 -1
  66. package/features/notes/web/codex-notebook.svg +0 -1
  67. package/features/notes/web/codex-pdf.svg +0 -1
  68. package/features/notes/web/codex-pencil.svg +0 -3
  69. package/features/notes/web/codex-php.svg +0 -1
  70. package/features/notes/web/codex-plus.svg +0 -3
  71. package/features/notes/web/codex-presentation.svg +0 -1
  72. package/features/notes/web/codex-python.svg +0 -1
  73. package/features/notes/web/codex-react.svg +0 -1
  74. package/features/notes/web/codex-rust.svg +0 -1
  75. package/features/notes/web/codex-shell.svg +0 -1
  76. package/features/notes/web/codex-skill.svg +0 -1
  77. package/features/notes/web/codex-spreadsheet.svg +0 -1
  78. package/features/notes/web/codex-task.svg +0 -3
  79. package/features/notes/web/codex-terminal.svg +0 -1
  80. package/features/notes/web/codex-toml.svg +0 -1
  81. package/features/notes/web/codex-typescript.svg +0 -1
  82. package/features/notes/web/codex-view-all.svg +0 -3
  83. package/features/notes/web/file-icons.mjs +0 -68
  84. package/features/notes/web/i18n.mjs +0 -237
  85. package/features/notes/web/index.html +0 -15
  86. package/features/notes/web/styles.css +0 -1155
  87. package/features/notes/web/todo-drag.mjs +0 -18
@@ -70,9 +70,7 @@ function emptyState(filePath) {
70
70
  contextWindow: null,
71
71
  firstOutputAt: null,
72
72
  pendingToolIntervals: [],
73
- decodeTokens: 0,
74
- decodeMs: 0,
75
- speedSamples: 0,
73
+ speedMeasurements: [],
76
74
  ttftTotalMs: 0,
77
75
  ttftSamples: 0,
78
76
  toolMs: 0,
@@ -110,6 +108,9 @@ export function applySessionStatusEvent(state, event) {
110
108
  const payload = event?.payload ?? {};
111
109
  if (event?.type === "compacted") {
112
110
  state.compactionRecords += 1;
111
+ state.last = null;
112
+ state.firstOutputAt = null;
113
+ state.pendingToolIntervals = [];
113
114
  if (Number.isSafeInteger(payload.window_number) && payload.window_number >= 0) {
114
115
  state.compactionWindow = Math.max(state.compactionWindow, payload.window_number);
115
116
  }
@@ -134,12 +135,21 @@ export function applySessionStatusEvent(state, event) {
134
135
  state.baseInstructionTokens = estimatedTextTokens(payload.base_instructions?.text);
135
136
  }
136
137
  if (event?.type === "event_msg") {
137
- if (payload.type === "context_compacted") state.compactionEvents += 1;
138
+ if (payload.type === "context_compacted") {
139
+ state.compactionEvents += 1;
140
+ state.last = null;
141
+ state.firstOutputAt = null;
142
+ state.pendingToolIntervals = [];
143
+ }
138
144
  if (payload.type === "task_started" && payload.turn_id) {
145
+ state.firstOutputAt = null;
146
+ state.pendingToolIntervals = [];
139
147
  state.turns.add(payload.turn_id);
140
148
  state.runningTurns.add(payload.turn_id);
141
149
  }
142
150
  if (["task_complete", "task_interrupted", "turn_aborted"].includes(payload.type)) {
151
+ state.firstOutputAt = null;
152
+ state.pendingToolIntervals = [];
143
153
  if (payload.turn_id) state.runningTurns.delete(payload.turn_id);
144
154
  else state.runningTurns.clear();
145
155
  }
@@ -158,13 +168,17 @@ export function applySessionStatusEvent(state, event) {
158
168
  if (TOOL_ITEMS.has(itemType) && Number.isFinite(start) && Number.isFinite(end)) {
159
169
  state.toolMs += Math.max(0, end - start);
160
170
  state.pendingToolIntervals.push([start, end]);
171
+ // 工具完成事件可能晚于用量记录落盘,补扣已记录样本中的重叠区间。
172
+ for (const sample of state.speedMeasurements) {
173
+ if (start < sample.end && end > sample.start) sample.tools.push([start, end]);
174
+ }
161
175
  }
162
176
  }
163
177
  if (payload.type === "token_count") {
164
178
  if (!state.hasResponseUsage && validUsage(payload.info?.total_token_usage)) {
165
179
  state.total = payload.info.total_token_usage;
166
180
  }
167
- if (!state.hasResponseUsage && validUsage(payload.info?.last_token_usage)) {
181
+ if (validUsage(payload.info?.last_token_usage)) {
168
182
  state.last = payload.info.last_token_usage;
169
183
  }
170
184
  if (Number.isFinite(payload.info?.model_context_window)) {
@@ -174,18 +188,18 @@ export function applySessionStatusEvent(state, event) {
174
188
  }
175
189
  if (event?.type === "token_usage_record") {
176
190
  const responseId = payload.response_id;
177
- if (responseId && !state.responses.has(responseId)) {
191
+ if (responseId && state.responses.has(responseId)) return;
192
+ if (responseId) {
178
193
  state.responses.add(responseId);
179
194
  const responseEnd = Date.parse(event.timestamp);
180
- const elapsed = state.firstOutputAt == null ? null : responseEnd - state.firstOutputAt
181
- - overlappingToolMs(state.pendingToolIntervals, state.firstOutputAt, responseEnd);
182
195
  const output = payload.usage?.output_tokens;
183
- // 会话事件只给出首个可见条目的时间,故 TPS 是观测估算。
196
+ // 起止点来自会话事件,并非模型首末 token 时间;只能提供观测约值。
184
197
  if (Number.isFinite(output) && output > 0 && state.firstOutputAt != null
185
- && Number.isFinite(elapsed) && elapsed > 0 && elapsed < 600_000) {
186
- state.decodeTokens += output;
187
- state.decodeMs += elapsed;
188
- state.speedSamples += 1;
198
+ && Number.isFinite(responseEnd) && responseEnd > state.firstOutputAt) {
199
+ state.speedMeasurements.push({
200
+ start: state.firstOutputAt, end: responseEnd, output,
201
+ tools: state.pendingToolIntervals.slice(),
202
+ });
189
203
  }
190
204
  }
191
205
  state.firstOutputAt = null;
@@ -200,6 +214,16 @@ export function applySessionStatusEvent(state, event) {
200
214
  }
201
215
 
202
216
  export function sessionStatusSnapshot(state, threadId) {
217
+ let decodeTokens = 0;
218
+ let decodeMs = 0;
219
+ let speedSamples = 0;
220
+ for (const sample of state.speedMeasurements) {
221
+ const elapsed = sample.end - sample.start - overlappingToolMs(sample.tools, sample.start, sample.end);
222
+ if (elapsed <= 0 || elapsed >= 600_000) continue;
223
+ decodeTokens += sample.output;
224
+ decodeMs += elapsed;
225
+ speedSamples += 1;
226
+ }
203
227
  const total = state.total;
204
228
  const input = total?.input_tokens ?? 0;
205
229
  const cached = total?.cached_input_tokens ?? 0;
@@ -218,9 +242,9 @@ export function sessionStatusSnapshot(state, threadId) {
218
242
  uncachedInputTokens: total ? Math.max(0, input - cached - cacheWrite) : null,
219
243
  outputTokens: total?.output_tokens ?? null,
220
244
  cacheHitPercent: input > 0 ? Math.round(cached / input * 100) : null,
221
- observedTps: state.decodeMs > 0 ? Math.round(state.decodeTokens / (state.decodeMs / 1000)) : null,
222
- speedSamples: state.speedSamples,
223
- observedModelMs: state.decodeMs,
245
+ observedTps: decodeMs > 0 ? Math.round(decodeTokens / (decodeMs / 1000)) : null,
246
+ speedSamples,
247
+ observedModelMs: decodeMs,
224
248
  toolMs: state.toolMs,
225
249
  averageFirstTokenMs: state.ttftSamples > 0 ? Math.round(state.ttftTotalMs / state.ttftSamples) : null,
226
250
  contextUsedTokens: contextUsed,
@@ -1,15 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-circle"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <circle cx="12" cy="12" r="10" />
15
- </svg>
@@ -1,17 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-ellipsis"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <circle cx="12" cy="12" r="1" />
15
- <circle cx="19" cy="12" r="1" />
16
- <circle cx="5" cy="12" r="1" />
17
- </svg>
@@ -1,17 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-external-link"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="M15 3h6v6" />
15
- <path d="M10 14 21 3" />
16
- <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
17
- </svg>
@@ -1,19 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-list-todo"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="M13 5h8" />
15
- <path d="M13 12h8" />
16
- <path d="M13 19h8" />
17
- <path d="m3 17 2 2 4-4" />
18
- <rect x="3" y="4" width="6" height="6" rx="1" />
19
- </svg>
@@ -1,17 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-message-square-quote"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="M14 14a2 2 0 0 0 2-2V8h-2" />
15
- <path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" />
16
- <path d="M8 14a2 2 0 0 0 2-2V8H8" />
17
- </svg>
@@ -1,15 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-paperclip"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551" />
15
- </svg>
@@ -1,17 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-star-off"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="m10.344 4.688 1.181-2.393a.53.53 0 0 1 .95 0l2.31 4.679a2.12 2.12 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.237 3.152" />
15
- <path d="m17.945 17.945.43 2.505a.53.53 0 0 1-.771.56l-4.618-2.428a2.12 2.12 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.12 2.12 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a8 8 0 0 0 .4-.099" />
16
- <path d="m2 2 20 20" />
17
- </svg>
@@ -1,15 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-star"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z" />
15
- </svg>
@@ -1,16 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-sticky-note"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="M21 9a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 15 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2z" />
15
- <path d="M15 3v5a1 1 0 0 0 1 1h5" />
16
- </svg>
@@ -1,19 +0,0 @@
1
- <!-- @license lucide-static v1.31.0 - ISC -->
2
- <svg
3
- class="lucide lucide-trash-2"
4
- xmlns="http://www.w3.org/2000/svg"
5
- width="24"
6
- height="24"
7
- viewBox="0 0 24 24"
8
- fill="none"
9
- stroke="currentColor"
10
- stroke-width="2"
11
- stroke-linecap="round"
12
- stroke-linejoin="round"
13
- >
14
- <path d="M10 11v6" />
15
- <path d="M14 11v6" />
16
- <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" />
17
- <path d="M3 6h18" />
18
- <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
19
- </svg>