@aryacode/dsh-aryacode-polish 0.6.0 → 0.6.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 +23 -0
- package/client/face.js +43 -10
- package/docs/github-workspaces.md +9 -6
- package/lib/client.js +44 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.2] - 2026-10-28
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **The "+" menu and the GitHub dialog are opaque again in the desktop app.**
|
|
8
|
+
Both are portaled to `document.body`, which puts them outside the themed tree,
|
|
9
|
+
and they painted themselves with the harness menu fill `--dsw-specific-menu`
|
|
10
|
+
(`#f8f9fa94`, 58% alpha) relying on `backdrop-filter` to make that read solid.
|
|
11
|
+
The AryaCode desktop build does not composite that blur, so the page showed
|
|
12
|
+
through the panel. Every portaled surface now lays that fill over an opaque
|
|
13
|
+
`Canvas` base and keeps the blur only where the platform honours it.
|
|
14
|
+
|
|
15
|
+
## [0.6.1] - 2026-10-28
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **"On this PC" opens the real Windows folder dialog in the desktop app again.**
|
|
20
|
+
The desktop preload exposes the OS chooser as `__DSH_DIRECTORY_PICKER__.pick()`
|
|
21
|
+
— the same bridge the shipped native picker uses — and the flow now calls it
|
|
22
|
+
directly, so picking a folder behaves exactly like the picker it stands in for.
|
|
23
|
+
The in-app folder list is now only the browser fallback, where no such bridge
|
|
24
|
+
exists and the composed picker's `pick` would wait on a dialog that cannot open.
|
|
25
|
+
|
|
3
26
|
## [0.6.0] - 2026-10-28
|
|
4
27
|
|
|
5
28
|
### Changed
|
package/client/face.js
CHANGED
|
@@ -252,6 +252,24 @@ const PILL_STYLE = {
|
|
|
252
252
|
/** The label half of the pill, cut with an ellipsis rather than wrapped. */
|
|
253
253
|
const PILL_LABEL_STYLE = { minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }
|
|
254
254
|
|
|
255
|
+
/**
|
|
256
|
+
* The menu skin of the harness, made opaque on purpose.
|
|
257
|
+
*
|
|
258
|
+
* `--dsw-specific-menu` is a translucent fill (`#f8f9fa94`) that only reads as a
|
|
259
|
+
* solid surface because the harness pairs it with `backdrop-filter`. A plugin
|
|
260
|
+
* face has to portal its panels to `document.body`, and in the AryaCode desktop
|
|
261
|
+
* build that blur does not composite: the panel then showed the page behind it
|
|
262
|
+
* through a 58% fill. So the token stays as a tint over an opaque backdrop
|
|
263
|
+
* colour, and the blur is kept only where the platform actually honours it.
|
|
264
|
+
*/
|
|
265
|
+
const PANEL_SURFACE = {
|
|
266
|
+
backgroundColor: 'Canvas',
|
|
267
|
+
backgroundImage:
|
|
268
|
+
'linear-gradient(var(--dsw-specific-menu, rgba(248, 249, 250, 0.94)), var(--dsw-specific-menu, rgba(248, 249, 250, 0.94)))',
|
|
269
|
+
backdropFilter: 'var(--dsw-menu-backdrop-filter, none)',
|
|
270
|
+
border: '0.5px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.12))',
|
|
271
|
+
}
|
|
272
|
+
|
|
255
273
|
/** The dialog surface, copied from the harness `stat-dialog.module.css` skin. */
|
|
256
274
|
const PANEL_STYLE = {
|
|
257
275
|
position: 'fixed',
|
|
@@ -261,10 +279,8 @@ const PANEL_STYLE = {
|
|
|
261
279
|
minWidth: 'min(300px, calc(100vw - 24px))',
|
|
262
280
|
maxWidth: 'min(440px, calc(100vw - 24px))',
|
|
263
281
|
padding: '16px',
|
|
264
|
-
border: 0,
|
|
265
282
|
borderRadius: 'var(--dsw-radius-lg, 12px)',
|
|
266
|
-
|
|
267
|
-
backdropFilter: 'var(--dsw-menu-backdrop-filter, none)',
|
|
283
|
+
...PANEL_SURFACE,
|
|
268
284
|
boxShadow: 'var(--dsw-elevation-prominent, 0 10px 30px rgba(0, 0, 0, 0.18))',
|
|
269
285
|
fontSize: '12px',
|
|
270
286
|
lineHeight: '18px',
|
|
@@ -1064,16 +1080,33 @@ function WorkspaceSourceFlow(props) {
|
|
|
1064
1080
|
}
|
|
1065
1081
|
|
|
1066
1082
|
/**
|
|
1067
|
-
*
|
|
1083
|
+
* Hand folder choice to the Host.
|
|
1068
1084
|
*
|
|
1069
|
-
*
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1085
|
+
* In the desktop app the preload exposes the real OS chooser as
|
|
1086
|
+
* `__DSH_DIRECTORY_PICKER__.pick()` — the same bridge the shipped native
|
|
1087
|
+
* picker uses — so the flow opens the Windows folder dialog and behaves like
|
|
1088
|
+
* the stock picker it stands in for. In a browser there is no such bridge, and
|
|
1089
|
+
* the composed picker's `pick` waits on a dialog that cannot open, so the flow
|
|
1090
|
+
* lists folders itself instead of hanging.
|
|
1074
1091
|
*/
|
|
1075
1092
|
const chooseOnPc = () => {
|
|
1076
1093
|
if (busy) return
|
|
1094
|
+
const bridge = typeof globalThis === 'undefined' ? undefined : globalThis.__DSH_DIRECTORY_PICKER__
|
|
1095
|
+
if (bridge !== undefined && typeof bridge.pick === 'function') {
|
|
1096
|
+
setBusy(true)
|
|
1097
|
+
setError('')
|
|
1098
|
+
Promise.resolve()
|
|
1099
|
+
.then(() => bridge.pick())
|
|
1100
|
+
.then(path => {
|
|
1101
|
+
if (typeof path === 'string' && path !== '') {
|
|
1102
|
+
land(path)
|
|
1103
|
+
return
|
|
1104
|
+
}
|
|
1105
|
+
setBusy(false)
|
|
1106
|
+
})
|
|
1107
|
+
.catch(reason => fail(messageOf(reason)))
|
|
1108
|
+
return
|
|
1109
|
+
}
|
|
1077
1110
|
setBusy(true)
|
|
1078
1111
|
setError('')
|
|
1079
1112
|
Promise.resolve()
|
|
@@ -1189,7 +1222,7 @@ function WorkspaceSourceFlow(props) {
|
|
|
1189
1222
|
padding: '6px',
|
|
1190
1223
|
overflowY: 'auto',
|
|
1191
1224
|
borderRadius: 'var(--dsw-radius-lg, 12px)',
|
|
1192
|
-
|
|
1225
|
+
...PANEL_SURFACE,
|
|
1193
1226
|
boxShadow: 'var(--dsw-elevation-prominent, 0 8px 24px rgba(0,0,0,0.18))',
|
|
1194
1227
|
fontSize: '12px',
|
|
1195
1228
|
lineHeight: '18px',
|
|
@@ -38,7 +38,11 @@ The "+" menu's **Add workspace…** entry only appears when something occupies
|
|
|
38
38
|
takes it stands in for the folder picker. This bundle takes it and offers the
|
|
39
39
|
two sources the owner asked for:
|
|
40
40
|
|
|
41
|
-
- **On this PC** —
|
|
41
|
+
- **On this PC** — the OS folder dialog. The desktop preload exposes it as
|
|
42
|
+
`window.__DSH_DIRECTORY_PICKER__.pick()`, the same bridge the shipped native
|
|
43
|
+
picker uses, so the flow calls it directly and behaves exactly like the picker
|
|
44
|
+
it stands in for. Where that bridge is absent (the web build) the flow falls
|
|
45
|
+
back to a folder browser driven by this bundle's own route
|
|
42
46
|
(`api/polish.folders`, actions `roots` and `ls`): roots, a `..` row for going
|
|
43
47
|
back, directories only, hidden and system entries filtered out, and **Use this
|
|
44
48
|
folder** hands the current path to the flow's `onPicked`.
|
|
@@ -46,15 +50,14 @@ two sources the owner asked for:
|
|
|
46
50
|
flow, so a finished clone hands its path back through the flow's `onPicked`,
|
|
47
51
|
and the Shell creates the workspace exactly as it does for a picked folder.
|
|
48
52
|
|
|
49
|
-
### Why the
|
|
53
|
+
### Why the fallback exists at all
|
|
50
54
|
|
|
51
55
|
A composed directory picker serves exactly one capability: `browse` answers
|
|
52
56
|
`list` and `createDirectory`, `native` answers `pick`. The web profile composes
|
|
53
57
|
the picker whose chooser cannot open there, so `directoryPicker.pick()` waits on
|
|
54
|
-
a dialog that never appears —
|
|
55
|
-
the row spun forever.
|
|
56
|
-
|
|
57
|
-
a different picker.
|
|
58
|
+
a dialog that never appears — an earlier build of this flow did exactly that and
|
|
59
|
+
the row spun forever. The preload bridge is the reliable door in the app; the
|
|
60
|
+
listing is what a browser gets instead of a spinner.
|
|
58
61
|
|
|
59
62
|
The tray of the foot keeps the sign-in state (`GitHub · <login>`, or
|
|
60
63
|
`GitHub · signed out`) next to the balance, so the account is visible without
|
package/lib/client.js
CHANGED
|
@@ -41,7 +41,7 @@ window.__ModuleLoader__.load({
|
|
|
41
41
|
]
|
|
42
42
|
const ROW_ID = "polish"
|
|
43
43
|
const ROW_KEY = "@aryacode/dsh-aryacode-polish" + '#' + ROW_ID
|
|
44
|
-
const CLIENT_VERSION = "0.6.
|
|
44
|
+
const CLIENT_VERSION = "0.6.2"
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* The two pure decisions behind the balance line: which wallet to show, and how
|
|
@@ -419,6 +419,24 @@ window.__ModuleLoader__.load({
|
|
|
419
419
|
/** The label half of the pill, cut with an ellipsis rather than wrapped. */
|
|
420
420
|
const PILL_LABEL_STYLE = { minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }
|
|
421
421
|
|
|
422
|
+
/**
|
|
423
|
+
* The menu skin of the harness, made opaque on purpose.
|
|
424
|
+
*
|
|
425
|
+
* `--dsw-specific-menu` is a translucent fill (`#f8f9fa94`) that only reads as a
|
|
426
|
+
* solid surface because the harness pairs it with `backdrop-filter`. A plugin
|
|
427
|
+
* face has to portal its panels to `document.body`, and in the AryaCode desktop
|
|
428
|
+
* build that blur does not composite: the panel then showed the page behind it
|
|
429
|
+
* through a 58% fill. So the token stays as a tint over an opaque backdrop
|
|
430
|
+
* colour, and the blur is kept only where the platform actually honours it.
|
|
431
|
+
*/
|
|
432
|
+
const PANEL_SURFACE = {
|
|
433
|
+
backgroundColor: 'Canvas',
|
|
434
|
+
backgroundImage:
|
|
435
|
+
'linear-gradient(var(--dsw-specific-menu, rgba(248, 249, 250, 0.94)), var(--dsw-specific-menu, rgba(248, 249, 250, 0.94)))',
|
|
436
|
+
backdropFilter: 'var(--dsw-menu-backdrop-filter, none)',
|
|
437
|
+
border: '0.5px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.12))',
|
|
438
|
+
}
|
|
439
|
+
|
|
422
440
|
/** The dialog surface, copied from the harness `stat-dialog.module.css` skin. */
|
|
423
441
|
const PANEL_STYLE = {
|
|
424
442
|
position: 'fixed',
|
|
@@ -428,10 +446,8 @@ window.__ModuleLoader__.load({
|
|
|
428
446
|
minWidth: 'min(300px, calc(100vw - 24px))',
|
|
429
447
|
maxWidth: 'min(440px, calc(100vw - 24px))',
|
|
430
448
|
padding: '16px',
|
|
431
|
-
border: 0,
|
|
432
449
|
borderRadius: 'var(--dsw-radius-lg, 12px)',
|
|
433
|
-
|
|
434
|
-
backdropFilter: 'var(--dsw-menu-backdrop-filter, none)',
|
|
450
|
+
...PANEL_SURFACE,
|
|
435
451
|
boxShadow: 'var(--dsw-elevation-prominent, 0 10px 30px rgba(0, 0, 0, 0.18))',
|
|
436
452
|
fontSize: '12px',
|
|
437
453
|
lineHeight: '18px',
|
|
@@ -1231,16 +1247,33 @@ window.__ModuleLoader__.load({
|
|
|
1231
1247
|
}
|
|
1232
1248
|
|
|
1233
1249
|
/**
|
|
1234
|
-
*
|
|
1250
|
+
* Hand folder choice to the Host.
|
|
1235
1251
|
*
|
|
1236
|
-
*
|
|
1237
|
-
*
|
|
1238
|
-
*
|
|
1239
|
-
*
|
|
1240
|
-
*
|
|
1252
|
+
* In the desktop app the preload exposes the real OS chooser as
|
|
1253
|
+
* `__DSH_DIRECTORY_PICKER__.pick()` — the same bridge the shipped native
|
|
1254
|
+
* picker uses — so the flow opens the Windows folder dialog and behaves like
|
|
1255
|
+
* the stock picker it stands in for. In a browser there is no such bridge, and
|
|
1256
|
+
* the composed picker's `pick` waits on a dialog that cannot open, so the flow
|
|
1257
|
+
* lists folders itself instead of hanging.
|
|
1241
1258
|
*/
|
|
1242
1259
|
const chooseOnPc = () => {
|
|
1243
1260
|
if (busy) return
|
|
1261
|
+
const bridge = typeof globalThis === 'undefined' ? undefined : globalThis.__DSH_DIRECTORY_PICKER__
|
|
1262
|
+
if (bridge !== undefined && typeof bridge.pick === 'function') {
|
|
1263
|
+
setBusy(true)
|
|
1264
|
+
setError('')
|
|
1265
|
+
Promise.resolve()
|
|
1266
|
+
.then(() => bridge.pick())
|
|
1267
|
+
.then(path => {
|
|
1268
|
+
if (typeof path === 'string' && path !== '') {
|
|
1269
|
+
land(path)
|
|
1270
|
+
return
|
|
1271
|
+
}
|
|
1272
|
+
setBusy(false)
|
|
1273
|
+
})
|
|
1274
|
+
.catch(reason => fail(messageOf(reason)))
|
|
1275
|
+
return
|
|
1276
|
+
}
|
|
1244
1277
|
setBusy(true)
|
|
1245
1278
|
setError('')
|
|
1246
1279
|
Promise.resolve()
|
|
@@ -1356,7 +1389,7 @@ window.__ModuleLoader__.load({
|
|
|
1356
1389
|
padding: '6px',
|
|
1357
1390
|
overflowY: 'auto',
|
|
1358
1391
|
borderRadius: 'var(--dsw-radius-lg, 12px)',
|
|
1359
|
-
|
|
1392
|
+
...PANEL_SURFACE,
|
|
1360
1393
|
boxShadow: 'var(--dsw-elevation-prominent, 0 8px 24px rgba(0,0,0,0.18))',
|
|
1361
1394
|
fontSize: '12px',
|
|
1362
1395
|
lineHeight: '18px',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aryacode/dsh-aryacode-polish",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.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",
|