@aryacode/dsh-aryacode-polish 0.20.0 → 0.21.2
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/client/workspace.js +54 -9
- package/docs/better-workspace.md +18 -0
- package/lib/client.js +55 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.21.2] - 2026-10-28
|
|
4
|
+
|
|
5
|
+
Fixed: the folders-only density showed a zero count because it read the hidden session list instead of the real one.
|
|
6
|
+
|
|
7
|
+
- 2026-10-28
|
|
8
|
+
|
|
9
|
+
Added: a folders-only density that hides session rows, and [ / ] to hop between workspaces.
|
|
10
|
+
|
|
3
11
|
## [0.20.0] - 2026-10-28
|
|
4
12
|
|
|
5
13
|
Added: session flags and notes, shown on the row and on hover; the whole tree can be copied as indented text from the header.
|
package/client/workspace.js
CHANGED
|
@@ -371,6 +371,23 @@ export function flattenRows(rows, expanded, query) {
|
|
|
371
371
|
return flat
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
/** Where the cursor lands when hopping to the next or previous workspace head. */
|
|
375
|
+
export function jumpWorkspace(list, cursor, step) {
|
|
376
|
+
const flat = Array.isArray(list) ? list : []
|
|
377
|
+
const heads = []
|
|
378
|
+
flat.forEach((item, index) => {
|
|
379
|
+
if (item && item.kind === 'workspace') heads.push(index)
|
|
380
|
+
})
|
|
381
|
+
if (heads.length === 0) return -1
|
|
382
|
+
if (cursor === undefined || cursor < 0) return step > 0 ? heads[0] : heads[heads.length - 1]
|
|
383
|
+
if (step > 0) {
|
|
384
|
+
const after = heads.find(index => index > cursor)
|
|
385
|
+
return after === undefined ? heads[0] : after
|
|
386
|
+
}
|
|
387
|
+
const before = heads.filter(index => index < cursor)
|
|
388
|
+
return before.length === 0 ? heads[heads.length - 1] : before[before.length - 1]
|
|
389
|
+
}
|
|
390
|
+
|
|
374
391
|
export function moveBefore(list, movingId, beforeId) {
|
|
375
392
|
const from = list.findIndex(item => item.id === movingId)
|
|
376
393
|
const to = list.findIndex(item => item.id === beforeId)
|
|
@@ -522,16 +539,34 @@ export function folderNamesOf(rows, declared) {
|
|
|
522
539
|
return seen
|
|
523
540
|
}
|
|
524
541
|
|
|
525
|
-
export const DENSITIES = ['comfortable', 'compact']
|
|
542
|
+
export const DENSITIES = ['comfortable', 'compact', 'folders']
|
|
526
543
|
|
|
527
544
|
/** Row height per density: the tree fits more rows without shrinking the text. */
|
|
528
545
|
export const DENSITY_METRICS = {
|
|
529
|
-
comfortable: { row: '28px' },
|
|
530
|
-
compact: { row: '22px' },
|
|
546
|
+
comfortable: { row: '28px', sessions: true },
|
|
547
|
+
compact: { row: '22px', sessions: true },
|
|
548
|
+
folders: { row: '24px', sessions: false },
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export const DENSITY_TITLES = {
|
|
552
|
+
comfortable: 'Use compact rows',
|
|
553
|
+
compact: 'Show folders only',
|
|
554
|
+
folders: 'Use comfortable rows',
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
export const DENSITY_GLYPHS = {
|
|
558
|
+
comfortable: '\u2263',
|
|
559
|
+
compact: '\u2261',
|
|
560
|
+
folders: '\u25a4',
|
|
531
561
|
}
|
|
532
562
|
|
|
533
563
|
export function densityOf(value) {
|
|
534
|
-
return value
|
|
564
|
+
return DENSITIES.indexOf(value) >= 0 ? value : 'comfortable'
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export function nextDensity(value) {
|
|
568
|
+
const list = DENSITIES
|
|
569
|
+
return list[(list.indexOf(densityOf(value)) + 1) % list.length]
|
|
535
570
|
}
|
|
536
571
|
|
|
537
572
|
export function readDensity(storage) {
|
|
@@ -1193,7 +1228,17 @@ export function BetterWorkspace(props) {
|
|
|
1193
1228
|
if (item.kind === 'workspace') toggleWorkspace(item.workspaceId)
|
|
1194
1229
|
else services.openSession(item.id)
|
|
1195
1230
|
}
|
|
1231
|
+
/** [ and ] hop between workspace heads: the fast way through a long tree. */
|
|
1232
|
+
const hopWorkspace = (step) => {
|
|
1233
|
+
const next = jumpWorkspace(walk, cursor, step)
|
|
1234
|
+
if (next >= 0) setCursor(next)
|
|
1235
|
+
}
|
|
1196
1236
|
const onKeyDown = (event) => {
|
|
1237
|
+
if (event.key === '[' || event.key === ']') {
|
|
1238
|
+
event.preventDefault()
|
|
1239
|
+
hopWorkspace(event.key === ']' ? 1 : -1)
|
|
1240
|
+
return
|
|
1241
|
+
}
|
|
1197
1242
|
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
1198
1243
|
if (walk.length === 0) return
|
|
1199
1244
|
event.preventDefault()
|
|
@@ -1667,15 +1712,15 @@ export function BetterWorkspace(props) {
|
|
|
1667
1712
|
key: 'density',
|
|
1668
1713
|
type: 'button',
|
|
1669
1714
|
'data-polish-ws-density': densityOf(density),
|
|
1670
|
-
title: densityOf(density)
|
|
1671
|
-
'aria-label': densityOf(density)
|
|
1715
|
+
title: DENSITY_TITLES[densityOf(density)],
|
|
1716
|
+
'aria-label': DENSITY_TITLES[densityOf(density)],
|
|
1672
1717
|
style: WS_ADD,
|
|
1673
1718
|
onClick: () => {
|
|
1674
|
-
const next =
|
|
1719
|
+
const next = nextDensity(density)
|
|
1675
1720
|
setDensity(next)
|
|
1676
1721
|
writeDensity(next)
|
|
1677
1722
|
},
|
|
1678
|
-
}, densityOf(density)
|
|
1723
|
+
}, DENSITY_GLYPHS[densityOf(density)]),
|
|
1679
1724
|
React.createElement('button', {
|
|
1680
1725
|
key: 'add',
|
|
1681
1726
|
type: 'button',
|
|
@@ -1936,7 +1981,7 @@ export function BetterWorkspace(props) {
|
|
|
1936
1981
|
: null)))
|
|
1937
1982
|
|
|
1938
1983
|
if (open) {
|
|
1939
|
-
sessions.forEach((row) => {
|
|
1984
|
+
(metrics.sessions ? sessions : []).forEach((row) => {
|
|
1940
1985
|
index += 1
|
|
1941
1986
|
children.push(sessionRow(workspace, row, index))
|
|
1942
1987
|
})
|
package/docs/better-workspace.md
CHANGED
|
@@ -239,3 +239,21 @@ session that no longer exists is simply never drawn.
|
|
|
239
239
|
The header's `⧉` copies the whole tree as indented text — folders, workspaces, sessions, with
|
|
240
240
|
`⚑` before a flagged session — through `navigator.clipboard.writeText`. It is meant for pasting
|
|
241
241
|
into a prompt or an issue: "here is what I am looking at", without screenshots.
|
|
242
|
+
|
|
243
|
+
## Folders only
|
|
244
|
+
|
|
245
|
+
The density button walks three states, not two: comfortable, compact, and **folders only**. The
|
|
246
|
+
last one keeps every folder and workspace row (with its real session count) and drops the session
|
|
247
|
+
rows entirely — useful when you are navigating the shape of your work rather than a specific
|
|
248
|
+
session. Nothing is lost: one more click returns to comfortable, and the mode is remembered in
|
|
249
|
+
`aryacode-polish:density.v1`.
|
|
250
|
+
|
|
251
|
+
One trap it exposed: the workspace count must come from the unfiltered session list. Reading the
|
|
252
|
+
list the tree was about to draw made every workspace read `0` in this mode, which looked like the
|
|
253
|
+
feature had eaten the sessions.
|
|
254
|
+
|
|
255
|
+
## Hopping between workspaces
|
|
256
|
+
|
|
257
|
+
With the tree focused, `[` and `]` move the keyboard cursor to the previous / next workspace head
|
|
258
|
+
and wrap at the ends. It is a second gear next to ArrowUp/ArrowDown: arrows walk rows, brackets
|
|
259
|
+
walk groups, so a long flat list of sessions stops being a scroll-and-squint exercise.
|
package/lib/client.js
CHANGED
|
@@ -53,7 +53,7 @@ window.__ModuleLoader__.load({
|
|
|
53
53
|
]
|
|
54
54
|
const ROW_ID = "polish"
|
|
55
55
|
const ROW_KEY = "@aryacode/dsh-aryacode-polish" + '#' + ROW_ID
|
|
56
|
-
const CLIENT_VERSION = "0.
|
|
56
|
+
const CLIENT_VERSION = "0.21.2"
|
|
57
57
|
|
|
58
58
|
/* html2canvas 1.4.1 — MIT, vendored from vendor/html2canvas.min.js.
|
|
59
59
|
* A UMD build, so it assigns itself to globalThis; face.js reads it lazily. */
|
|
@@ -572,6 +572,23 @@ window.__ModuleLoader__.load({
|
|
|
572
572
|
return flat
|
|
573
573
|
}
|
|
574
574
|
|
|
575
|
+
/** Where the cursor lands when hopping to the next or previous workspace head. */
|
|
576
|
+
function jumpWorkspace(list, cursor, step) {
|
|
577
|
+
const flat = Array.isArray(list) ? list : []
|
|
578
|
+
const heads = []
|
|
579
|
+
flat.forEach((item, index) => {
|
|
580
|
+
if (item && item.kind === 'workspace') heads.push(index)
|
|
581
|
+
})
|
|
582
|
+
if (heads.length === 0) return -1
|
|
583
|
+
if (cursor === undefined || cursor < 0) return step > 0 ? heads[0] : heads[heads.length - 1]
|
|
584
|
+
if (step > 0) {
|
|
585
|
+
const after = heads.find(index => index > cursor)
|
|
586
|
+
return after === undefined ? heads[0] : after
|
|
587
|
+
}
|
|
588
|
+
const before = heads.filter(index => index < cursor)
|
|
589
|
+
return before.length === 0 ? heads[heads.length - 1] : before[before.length - 1]
|
|
590
|
+
}
|
|
591
|
+
|
|
575
592
|
function moveBefore(list, movingId, beforeId) {
|
|
576
593
|
const from = list.findIndex(item => item.id === movingId)
|
|
577
594
|
const to = list.findIndex(item => item.id === beforeId)
|
|
@@ -723,16 +740,34 @@ window.__ModuleLoader__.load({
|
|
|
723
740
|
return seen
|
|
724
741
|
}
|
|
725
742
|
|
|
726
|
-
const DENSITIES = ['comfortable', 'compact']
|
|
743
|
+
const DENSITIES = ['comfortable', 'compact', 'folders']
|
|
727
744
|
|
|
728
745
|
/** Row height per density: the tree fits more rows without shrinking the text. */
|
|
729
746
|
const DENSITY_METRICS = {
|
|
730
|
-
comfortable: { row: '28px' },
|
|
731
|
-
compact: { row: '22px' },
|
|
747
|
+
comfortable: { row: '28px', sessions: true },
|
|
748
|
+
compact: { row: '22px', sessions: true },
|
|
749
|
+
folders: { row: '24px', sessions: false },
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
const DENSITY_TITLES = {
|
|
753
|
+
comfortable: 'Use compact rows',
|
|
754
|
+
compact: 'Show folders only',
|
|
755
|
+
folders: 'Use comfortable rows',
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
const DENSITY_GLYPHS = {
|
|
759
|
+
comfortable: '\u2263',
|
|
760
|
+
compact: '\u2261',
|
|
761
|
+
folders: '\u25a4',
|
|
732
762
|
}
|
|
733
763
|
|
|
734
764
|
function densityOf(value) {
|
|
735
|
-
return value
|
|
765
|
+
return DENSITIES.indexOf(value) >= 0 ? value : 'comfortable'
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
function nextDensity(value) {
|
|
769
|
+
const list = DENSITIES
|
|
770
|
+
return list[(list.indexOf(densityOf(value)) + 1) % list.length]
|
|
736
771
|
}
|
|
737
772
|
|
|
738
773
|
function readDensity(storage) {
|
|
@@ -1394,7 +1429,17 @@ window.__ModuleLoader__.load({
|
|
|
1394
1429
|
if (item.kind === 'workspace') toggleWorkspace(item.workspaceId)
|
|
1395
1430
|
else services.openSession(item.id)
|
|
1396
1431
|
}
|
|
1432
|
+
/** [ and ] hop between workspace heads: the fast way through a long tree. */
|
|
1433
|
+
const hopWorkspace = (step) => {
|
|
1434
|
+
const next = jumpWorkspace(walk, cursor, step)
|
|
1435
|
+
if (next >= 0) setCursor(next)
|
|
1436
|
+
}
|
|
1397
1437
|
const onKeyDown = (event) => {
|
|
1438
|
+
if (event.key === '[' || event.key === ']') {
|
|
1439
|
+
event.preventDefault()
|
|
1440
|
+
hopWorkspace(event.key === ']' ? 1 : -1)
|
|
1441
|
+
return
|
|
1442
|
+
}
|
|
1398
1443
|
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
1399
1444
|
if (walk.length === 0) return
|
|
1400
1445
|
event.preventDefault()
|
|
@@ -1868,15 +1913,15 @@ window.__ModuleLoader__.load({
|
|
|
1868
1913
|
key: 'density',
|
|
1869
1914
|
type: 'button',
|
|
1870
1915
|
'data-polish-ws-density': densityOf(density),
|
|
1871
|
-
title: densityOf(density)
|
|
1872
|
-
'aria-label': densityOf(density)
|
|
1916
|
+
title: DENSITY_TITLES[densityOf(density)],
|
|
1917
|
+
'aria-label': DENSITY_TITLES[densityOf(density)],
|
|
1873
1918
|
style: WS_ADD,
|
|
1874
1919
|
onClick: () => {
|
|
1875
|
-
const next =
|
|
1920
|
+
const next = nextDensity(density)
|
|
1876
1921
|
setDensity(next)
|
|
1877
1922
|
writeDensity(next)
|
|
1878
1923
|
},
|
|
1879
|
-
}, densityOf(density)
|
|
1924
|
+
}, DENSITY_GLYPHS[densityOf(density)]),
|
|
1880
1925
|
React.createElement('button', {
|
|
1881
1926
|
key: 'add',
|
|
1882
1927
|
type: 'button',
|
|
@@ -2137,7 +2182,7 @@ window.__ModuleLoader__.load({
|
|
|
2137
2182
|
: null)))
|
|
2138
2183
|
|
|
2139
2184
|
if (open) {
|
|
2140
|
-
sessions.forEach((row) => {
|
|
2185
|
+
(metrics.sessions ? sessions : []).forEach((row) => {
|
|
2141
2186
|
index += 1
|
|
2142
2187
|
children.push(sessionRow(workspace, row, index))
|
|
2143
2188
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aryacode/dsh-aryacode-polish",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.2",
|
|
4
4
|
"description": "AryaCode Polish: one install for the small things that make AryaCode feel finished. One Plugins row, one switch per quality-of-life feature.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|