@gotcos/glasses-server 6.36.2 → 6.36.4
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/CHANGELOG.md
CHANGED
|
@@ -2219,6 +2219,51 @@ unsaved capture, and makes batch status stop lying about finished work.
|
|
|
2219
2219
|
|
|
2220
2220
|
# Changelog
|
|
2221
2221
|
|
|
2222
|
+
## [6.36.4] - 2026-08-17
|
|
2223
|
+
|
|
2224
|
+
### A cloned Codex conversation gets its own identity
|
|
2225
|
+
|
|
2226
|
+
Miles forked "Markt POS 2.0 build" into "POS Nation 3.0 build" and the fork never
|
|
2227
|
+
appeared in the sessions list. It had not failed to index -- it was indexed AS ITS
|
|
2228
|
+
PARENT. The list showed one `Markt POS 2.0 build` row whose modified time was the
|
|
2229
|
+
fork's activity: two conversations, one identity, and the newer one invisible.
|
|
2230
|
+
|
|
2231
|
+
Cloning copies the parent's `session_meta` record wholesale, so the new rollout carries
|
|
2232
|
+
the PARENT's id under its own filename. `listCodexSessions` keyed on `meta.id` and
|
|
2233
|
+
folded them together.
|
|
2234
|
+
|
|
2235
|
+
The filename is unique per rollout by construction; the meta record is content and can
|
|
2236
|
+
be a copy. **When they disagree, the filename now wins.** An ordinary session, where
|
|
2237
|
+
they agree, is untouched.
|
|
2238
|
+
|
|
2239
|
+
Verified against the real machine before and after: the fork's `session_meta.id` reads
|
|
2240
|
+
`019e0943…` (the parent) while its filename reads `01a0119c…`.
|
|
2241
|
+
|
|
2242
|
+
### Also worth recording, not fixed here
|
|
2243
|
+
|
|
2244
|
+
That fork's rollout is **771,177,205 bytes** -- 735 MB, against other rollouts small
|
|
2245
|
+
enough not to register. The clone duplicated the entire parent transcript and Codex
|
|
2246
|
+
rewrites the whole file, which is past Node's 512 MB string limit; COS survives only
|
|
2247
|
+
because it reads bounded windows. Giving the fork its own identity does not shrink it,
|
|
2248
|
+
and a clone of a clone doubles again.
|
|
2249
|
+
|
|
2250
|
+
## [6.36.3] - 2026-08-17
|
|
2251
|
+
|
|
2252
|
+
### The seeded query was being crowded out by the steps
|
|
2253
|
+
|
|
2254
|
+
Caught by probing the live stream after shipping 6.36.2, before Miles tested it: a
|
|
2255
|
+
real session seeded 8 events -- 6 tool calls, one prose, one status -- and **no
|
|
2256
|
+
prompt**. The seed took "the last 7 events of any kind", and in a busy run the
|
|
2257
|
+
user's question is twenty or thirty steps back, so the activity you opened the page
|
|
2258
|
+
to watch is exactly what pushed the query off it. The one case the feature exists
|
|
2259
|
+
for was the one case it failed.
|
|
2260
|
+
|
|
2261
|
+
The newest prompt in the read window is now emitted FIRST and unconditionally,
|
|
2262
|
+
outside the step budget. Measured on this Mac's largest transcript (87.2 MB): the
|
|
2263
|
+
last 256 KiB holds 133 records including 3 user turns, so the window reaches a query
|
|
2264
|
+
comfortably. The client pins rather than lists it, so it costs nothing in the
|
|
2265
|
+
scrolling window.
|
|
2266
|
+
|
|
2222
2267
|
## [6.36.2] - 2026-08-17
|
|
2223
2268
|
|
|
2224
2269
|
### The live view stops being a blank slate
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gotcos/glasses-server",
|
|
3
|
-
"version": "6.36.
|
|
3
|
+
"version": "6.36.4",
|
|
4
4
|
"description": "COS Glasses \u2014 self-hosted AI heads-up-display server for Even G2 smart glasses, powered by Claude Code, Codex, or Cursor Agent CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -899,7 +899,26 @@ export async function listCodexSessions(
|
|
|
899
899
|
if (rows.length >= Math.max(0, limit)) break
|
|
900
900
|
const meta = await peekCodexMeta(candidate.file)
|
|
901
901
|
if (!meta || meta.subagent) continue
|
|
902
|
-
|
|
902
|
+
// THE FILENAME WINS WHEN THEY DISAGREE.
|
|
903
|
+
//
|
|
904
|
+
// A rollout's `session_meta.id` is normally its own id, and normally the filename
|
|
905
|
+
// agrees. A CLONED conversation breaks that: the clone copies the parent's
|
|
906
|
+
// `session_meta` record wholesale, so the new rollout carries the PARENT's id
|
|
907
|
+
// while its filename carries its own.
|
|
908
|
+
//
|
|
909
|
+
// Miles forked "Markt POS 2.0 build" into "POS Nation 3.0 build" and the fork
|
|
910
|
+
// never appeared in the session list. It had not failed to index -- it was indexed
|
|
911
|
+
// AS its parent, so the list showed one `Markt POS 2.0 build` row whose modified
|
|
912
|
+
// time was the fork's activity. Two conversations, one identity, and the newer one
|
|
913
|
+
// invisible.
|
|
914
|
+
//
|
|
915
|
+
// The filename is unique per rollout by construction; the meta record is content
|
|
916
|
+
// and can be a copy. So when they disagree, trust the filename.
|
|
917
|
+
const fileId = idFromCodexFilename(candidate.name)
|
|
918
|
+
const metaId = (meta.id || '').trim().toLowerCase()
|
|
919
|
+
const native = fileId && metaId && fileId !== metaId
|
|
920
|
+
? fileId
|
|
921
|
+
: (meta.id || candidate.name.slice(0, -6))
|
|
903
922
|
const title = names.get(native) || meta.title || 'Codex session'
|
|
904
923
|
if (isKeepWarmSessionTitle(title)) continue
|
|
905
924
|
const created = meta.created || createdFromCodexFilename(candidate.name) || isoFromMtime(candidate.birthtimeMs)
|
|
@@ -264,7 +264,21 @@ agentSessionStreamRouter.get('/agent-sessions/:provider/:sessionId/stream', asyn
|
|
|
264
264
|
// Status drafts are dropped from the seed: they describe the state at some past
|
|
265
265
|
// moment and the opening status above is the CURRENT one. Replaying an old
|
|
266
266
|
// `done` after it would tell the client the live session had finished.
|
|
267
|
-
|
|
267
|
+
// THE QUERY IS SEEDED SEPARATELY, AND ALWAYS.
|
|
268
|
+
//
|
|
269
|
+
// Taking "the last 7 events" and hoping the prompt is among them does not work,
|
|
270
|
+
// and a live probe against a real session proved it: 8 seeded events, 6 tools and
|
|
271
|
+
// one prose, and NO prompt -- because in a busy run the user's question is twenty
|
|
272
|
+
// or thirty steps back and gets pushed out of the window by the very activity you
|
|
273
|
+
// opened the page to watch. That is the exact case the query exists for.
|
|
274
|
+
//
|
|
275
|
+
// So the newest prompt in the whole read window is emitted FIRST, unconditionally,
|
|
276
|
+
// and the step budget is spent entirely on steps. The client pins it rather than
|
|
277
|
+
// listing it, so it costs nothing in the scrolling window.
|
|
278
|
+
const lastPrompt = [...drafts].reverse().find(d => d.kind === 'prompt')
|
|
279
|
+
if (lastPrompt) write({ ...lastPrompt, at: Date.now() })
|
|
280
|
+
|
|
281
|
+
const steps = drafts.filter(d => d.kind === 'tool' || d.kind === 'prose')
|
|
268
282
|
for (const draft of steps.slice(-SEED_EVENTS)) {
|
|
269
283
|
// NOT tagged as seeded. A replayed step is a step that really happened, and a
|
|
270
284
|
// second rendering style for it would be a distinction without a use. The one
|