@gotcos/glasses-server 6.44.0 → 6.44.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.
- package/CHANGELOG.md +8 -0
- package/package.json +4 -2
- package/server/lib/task-store.ts +30 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 6.44.1
|
|
2
|
+
|
|
3
|
+
Board and lens titles are readable.
|
|
4
|
+
|
|
5
|
+
- `projectRow` and `projectTaskRun` sliced the raw `tasks.md` line at 44 characters, so a title kept its markdown and was cut mid-word: 119 of the 201 rows served today began with an unbalanced `**`, and one row read `**Provide data migration process docs by ind`. Both now go through `taskTitle`, which strips code spans, links and emphasis first — buying back the characters the asterisks were spending — then cuts on a word boundary and marks the cut. Verified over all 312 live task lines: none over the cap, none with a stray asterisk, none empty.
|
|
6
|
+
- Underscore emphasis is anchored, so `cos_python` and `hermit_crabs` survive; only `_emphasis_` is stripped.
|
|
7
|
+
- `TASK_TITLE_MAX` is exported so tests pin the real cap instead of a copy of it.
|
|
8
|
+
|
|
1
9
|
## 6.44.0
|
|
2
10
|
|
|
3
11
|
Task store: one COS `tasks.md` contract with a durable lock, columns, and a run ledger.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gotcos/glasses-server",
|
|
3
|
-
"version": "6.44.
|
|
3
|
+
"version": "6.44.1",
|
|
4
4
|
"description": "COS Glasses \u2014 self-hosted AI heads-up-display server for Even G2 smart glasses, powered by Claude Code, Codex, Cursor Agent CLI, or local Ollama",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
"url": "git+https://github.com/ukaoma/cos-glasses-server.git"
|
|
51
51
|
},
|
|
52
52
|
"homepage": "https://www.gotcos.com",
|
|
53
|
-
"bugs": {
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/ukaoma/cos-glasses-server/issues"
|
|
55
|
+
},
|
|
54
56
|
"publishConfig": {
|
|
55
57
|
"access": "public"
|
|
56
58
|
},
|
package/server/lib/task-store.ts
CHANGED
|
@@ -333,6 +333,34 @@ export async function loadAllRows(day: string): Promise<BridgeTaskRow[]> {
|
|
|
333
333
|
return groups.flat()
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
+
/** Board and lens titles come from a raw tasks.md line, which carries markdown
|
|
337
|
+
* emphasis and is usually far longer than a row. Slicing the raw line cut words
|
|
338
|
+
* and left unbalanced `**` on 119 of 201 live rows, so a row read
|
|
339
|
+
* "**Provide data migration process docs by ind". Strip the markup first (which
|
|
340
|
+
* buys back the four characters the asterisks were spending), then cut on a word
|
|
341
|
+
* boundary. The cap is exported so tests pin the real value rather than a copy. */
|
|
342
|
+
export const TASK_TITLE_MAX = 44
|
|
343
|
+
|
|
344
|
+
export function taskTitle(line: string): string {
|
|
345
|
+
const plain = line
|
|
346
|
+
.replace(/`([^`]*)`/g, '$1')
|
|
347
|
+
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
348
|
+
// Underscore emphasis must be anchored: a bare `_` between word characters is
|
|
349
|
+
// an identifier (cos_python, hermit_crabs), not markup, and stripping it
|
|
350
|
+
// corrupts the row. Asterisks need no such care, so one catch-all below clears
|
|
351
|
+
// them whether the pair is balanced or not — and after a slice, it often is not.
|
|
352
|
+
.replace(/(^|[\s(])_([^_]+)_(?=[\s).,;:!?]|$)/g, '$1$2')
|
|
353
|
+
.replace(/\*+/g, '')
|
|
354
|
+
.replace(/\s+/g, ' ')
|
|
355
|
+
.trim()
|
|
356
|
+
if (plain.length <= TASK_TITLE_MAX) return plain
|
|
357
|
+
const cut = plain.slice(0, TASK_TITLE_MAX - 1)
|
|
358
|
+
const space = cut.lastIndexOf(' ')
|
|
359
|
+
// Only honour a word boundary that is not so early it throws the title away.
|
|
360
|
+
const body = space > TASK_TITLE_MAX * 0.6 ? cut.slice(0, space) : cut
|
|
361
|
+
return `${body.replace(/[\s\u2014\u2013,;:.-]+$/, '')}\u2026`
|
|
362
|
+
}
|
|
363
|
+
|
|
336
364
|
export function projectRow(
|
|
337
365
|
row: BridgeTaskRow,
|
|
338
366
|
ledger: readonly TaskRun[],
|
|
@@ -350,7 +378,7 @@ export function projectRow(
|
|
|
350
378
|
id: row.id,
|
|
351
379
|
ref: row.ref,
|
|
352
380
|
domain: row.domain,
|
|
353
|
-
title: row.description
|
|
381
|
+
title: taskTitle(row.description),
|
|
354
382
|
column: col,
|
|
355
383
|
priority: row.priority,
|
|
356
384
|
...(runAt ? { runAt: new Date(taskInstant(runAt.day, runAt.minutes, tz)).toISOString() } : {}),
|
|
@@ -502,7 +530,7 @@ export function projectTaskRun(
|
|
|
502
530
|
run: TaskRun,
|
|
503
531
|
snapshot?: { status: string; completedAt?: string } | null,
|
|
504
532
|
): TaskRunView {
|
|
505
|
-
const title = run.line
|
|
533
|
+
const title = taskTitle(run.line)
|
|
506
534
|
const base = {
|
|
507
535
|
id: run.id,
|
|
508
536
|
kind: 'task' as const,
|