cursedbelt 4.6.0 → 5.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 (144) hide show
  1. package/README.md +36 -0
  2. package/dist/react/chat/index.d.ts +1 -0
  3. package/dist/react/chat/index.d.ts.map +1 -1
  4. package/dist/react/chat/index.js +1 -0
  5. package/dist/react/chat/index.js.map +1 -1
  6. package/dist/react/chat/usePresence.d.ts +75 -0
  7. package/dist/react/chat/usePresence.d.ts.map +1 -0
  8. package/dist/react/chat/usePresence.js +109 -0
  9. package/dist/react/chat/usePresence.js.map +1 -0
  10. package/dist/react/components/SecretInput.d.ts +7 -2
  11. package/dist/react/components/SecretInput.d.ts.map +1 -1
  12. package/dist/react/components/SecretInput.js +5 -2
  13. package/dist/react/components/SecretInput.js.map +1 -1
  14. package/dist/react/components/TooltipImpl.d.ts.map +1 -1
  15. package/dist/react/components/TooltipImpl.js +52 -3
  16. package/dist/react/components/TooltipImpl.js.map +1 -1
  17. package/dist/react/file-tree/FileTree.d.ts.map +1 -1
  18. package/dist/react/file-tree/FileTree.js +19 -1
  19. package/dist/react/file-tree/FileTree.js.map +1 -1
  20. package/dist/react/index.d.ts +1 -0
  21. package/dist/react/index.d.ts.map +1 -1
  22. package/dist/react/index.js +1 -0
  23. package/dist/react/index.js.map +1 -1
  24. package/dist/react/master-lock/MasterLockDialog.d.ts.map +1 -1
  25. package/dist/react/master-lock/MasterLockDialog.js +2 -1
  26. package/dist/react/master-lock/MasterLockDialog.js.map +1 -1
  27. package/dist/react/master-lock/MasterLockProvider.d.ts +12 -18
  28. package/dist/react/master-lock/MasterLockProvider.d.ts.map +1 -1
  29. package/dist/react/master-lock/MasterLockProvider.js +14 -20
  30. package/dist/react/master-lock/MasterLockProvider.js.map +1 -1
  31. package/dist/react/media/MediaUploadControl.d.ts +3 -7
  32. package/dist/react/media/MediaUploadControl.d.ts.map +1 -1
  33. package/dist/react/media/MediaUploadControl.js +4 -13
  34. package/dist/react/media/MediaUploadControl.js.map +1 -1
  35. package/dist/react/media/fileUploadClient.d.ts +0 -8
  36. package/dist/react/media/fileUploadClient.d.ts.map +1 -1
  37. package/dist/react/media/fileUploadClient.js +0 -8
  38. package/dist/react/media/fileUploadClient.js.map +1 -1
  39. package/dist/react/media/hlsSource.d.ts.map +1 -1
  40. package/dist/react/media/hlsSource.js +4 -2
  41. package/dist/react/media/hlsSource.js.map +1 -1
  42. package/dist/react/media/index.d.ts +0 -4
  43. package/dist/react/media/index.d.ts.map +1 -1
  44. package/dist/react/media/index.js +0 -4
  45. package/dist/react/media/index.js.map +1 -1
  46. package/dist/react/sessionAuth.d.ts +1 -2
  47. package/dist/react/sessionAuth.d.ts.map +1 -1
  48. package/dist/react/sessionAuth.js +2 -3
  49. package/dist/react/sessionAuth.js.map +1 -1
  50. package/dist/scripts/guardrailsEnforce.d.ts.map +1 -1
  51. package/dist/styles-areas/activity-bar.css +1 -1
  52. package/dist/styles-areas/auth.css +1 -1
  53. package/dist/styles-areas/charts.css +1 -1
  54. package/dist/styles-areas/chat.css +1 -1
  55. package/dist/styles-areas/core.css +1 -1
  56. package/dist/styles-areas/data-table.css +1 -1
  57. package/dist/styles-areas/disk-usage.css +1 -1
  58. package/dist/styles-areas/fields.css +1 -1
  59. package/dist/styles-areas/file-tree.css +1 -1
  60. package/dist/styles-areas/master-detail.css +1 -1
  61. package/dist/styles-areas/master-lock.css +108 -2
  62. package/dist/styles-areas/media-gallery.css +1 -1
  63. package/dist/styles-areas/media.css +1 -17
  64. package/dist/styles-areas/nav.css +1 -1
  65. package/dist/styles-areas/notifications.css +1 -1
  66. package/dist/styles-areas/spreadsheet.css +1 -1
  67. package/dist/styles-areas/stats.css +1 -1
  68. package/dist/styles-areas/wizard.css +1 -1
  69. package/dist/styles-areas/workbook-viewer.css +1 -1
  70. package/dist/styles-utilities.css +0 -16
  71. package/dist/testing/_noBun.d.ts +2 -0
  72. package/dist/testing/_noBun.d.ts.map +1 -0
  73. package/dist/testing/_noBun.js +10 -0
  74. package/dist/testing/_noBun.js.map +1 -0
  75. package/package.json +42 -19
  76. package/scripts/checkAreaStyles.spec.ts +71 -0
  77. package/scripts/checkAreaStyles.ts +150 -0
  78. package/scripts/guardrailsEnforce.spec.ts +43 -0
  79. package/scripts/guardrailsEnforce.ts +46 -1
  80. package/scripts/styleAreas.ts +1 -2
  81. package/src/barrelsReachNoOptionalPeer.spec.ts +6 -3
  82. package/src/bundlerOnlyEntries.spec.ts +101 -0
  83. package/src/declaredImports.spec.ts +4 -0
  84. package/src/optionalPeersTable.spec.ts +127 -0
  85. package/src/react/chat/index.ts +8 -0
  86. package/src/react/chat/usePresence.spec.tsx +138 -0
  87. package/src/react/chat/usePresence.ts +185 -0
  88. package/src/react/components/SecretInput.tsx +12 -1
  89. package/src/react/components/TooltipImpl.tsx +54 -5
  90. package/src/react/file-tree/FileTree.tsx +19 -1
  91. package/src/react/file-tree/fileTreeThumbs.spec.tsx +90 -0
  92. package/src/react/index.ts +8 -0
  93. package/src/react/master-lock/MasterLockDialog.tsx +13 -9
  94. package/src/react/master-lock/MasterLockProvider.spec.tsx +17 -0
  95. package/src/react/master-lock/MasterLockProvider.tsx +16 -19
  96. package/src/react/media/MediaUploadControl.tsx +8 -29
  97. package/src/react/media/fileUploadClient.ts +7 -17
  98. package/src/react/media/hlsSource.ts +4 -1
  99. package/src/react/media/index.ts +0 -16
  100. package/src/react/sessionAuth.ts +2 -3
  101. package/src/scriptsResolve.spec.ts +66 -0
  102. package/src/styles-areas/activity-bar.css +1 -1
  103. package/src/styles-areas/auth.css +1 -1
  104. package/src/styles-areas/charts.css +1 -1
  105. package/src/styles-areas/chat.css +1 -1
  106. package/src/styles-areas/core.css +1 -1
  107. package/src/styles-areas/data-table.css +1 -1
  108. package/src/styles-areas/disk-usage.css +1 -1
  109. package/src/styles-areas/fields.css +1 -1
  110. package/src/styles-areas/file-tree.css +1 -1
  111. package/src/styles-areas/master-detail.css +1 -1
  112. package/src/styles-areas/master-lock.css +108 -2
  113. package/src/styles-areas/media-gallery.css +1 -1
  114. package/src/styles-areas/media.css +1 -17
  115. package/src/styles-areas/nav.css +1 -1
  116. package/src/styles-areas/notifications.css +1 -1
  117. package/src/styles-areas/spreadsheet.css +1 -1
  118. package/src/styles-areas/stats.css +1 -1
  119. package/src/styles-areas/wizard.css +1 -1
  120. package/src/styles-areas/workbook-viewer.css +1 -1
  121. package/src/styles-utilities.css +0 -16
  122. package/src/testing/_noBun.ts +12 -0
  123. package/src/verifyGraph.spec.ts +11 -0
  124. package/dist/react/media/PrivateIndexView.d.ts +0 -6
  125. package/dist/react/media/PrivateIndexView.d.ts.map +0 -1
  126. package/dist/react/media/PrivateIndexView.js +0 -44
  127. package/dist/react/media/PrivateIndexView.js.map +0 -1
  128. package/dist/react/media/PrivateModeBadge.d.ts +0 -17
  129. package/dist/react/media/PrivateModeBadge.d.ts.map +0 -1
  130. package/dist/react/media/PrivateModeBadge.js +0 -24
  131. package/dist/react/media/PrivateModeBadge.js.map +0 -1
  132. package/dist/react/media/privateClient.d.ts +0 -34
  133. package/dist/react/media/privateClient.d.ts.map +0 -1
  134. package/dist/react/media/privateClient.js +0 -36
  135. package/dist/react/media/privateClient.js.map +0 -1
  136. package/dist/react/media/usePrivateUnlock.d.ts +0 -25
  137. package/dist/react/media/usePrivateUnlock.d.ts.map +0 -1
  138. package/dist/react/media/usePrivateUnlock.js +0 -68
  139. package/dist/react/media/usePrivateUnlock.js.map +0 -1
  140. package/src/react/media/PrivateIndexView.tsx +0 -113
  141. package/src/react/media/PrivateModeBadge.tsx +0 -50
  142. package/src/react/media/privateClient.spec.ts +0 -113
  143. package/src/react/media/privateClient.ts +0 -82
  144. package/src/react/media/usePrivateUnlock.ts +0 -132
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Every `bun run <x>` a script calls, and every command the app manifest names, is a script
3
+ * that EXISTS in this `package.json`.
4
+ *
5
+ * 🔴 Task 102, 2026-09-18: `done:serial` was `typecheck && lint && test && build`, and there was
6
+ * no `lint` script — so it had never once reached `test` or `build`, and the 31 lint errors a
7
+ * `lint` would have shown sat unseen. `format` was named in `cursed.app.extraCommands` too.
8
+ * Neither was in the gate, which is exactly why nobody noticed; this spec is in the gate.
9
+ */
10
+ import { describe, expect, it } from 'bun:test';
11
+ import pkg from '../package.json';
12
+
13
+ const scripts = (pkg as { scripts: Record<string, string> }).scripts;
14
+
15
+ /** The script names a command line invokes through `bun run` / `npm run`. */
16
+ export function calledScripts(command: string): string[] {
17
+ const out: string[] = [];
18
+ for (const m of command.matchAll(/\b(?:bun|npm|pnpm|yarn) run\s+([A-Za-z0-9:_./-]+)/g)) {
19
+ // A path (`bun run scripts/x.ts`) is a file, not a script name.
20
+ if (m[1] && !m[1].includes('/') && !/\.[cm]?[jt]sx?$/.test(m[1])) out.push(m[1]);
21
+ }
22
+ return out;
23
+ }
24
+
25
+ describe('package.json scripts resolve', () => {
26
+ it('reads `bun run <name>` and skips `bun run <file>`', () => {
27
+ expect(calledScripts('bun run typecheck && bun run lint && bun run scripts/gate.ts')).toEqual([
28
+ 'typecheck',
29
+ 'lint',
30
+ ]);
31
+ });
32
+
33
+ it('🔴 fails on a script that calls one that is not there — the task-102 shape', () => {
34
+ const fake = { 'done:serial': 'bun run typecheck && bun run lint', typecheck: 'tsc' };
35
+ const dangling = Object.values(fake)
36
+ .flatMap(calledScripts)
37
+ .filter((name) => !(name in fake));
38
+ expect(dangling).toEqual(['lint']);
39
+ });
40
+
41
+ it('every `bun run <script>` inside a script names a script that exists', () => {
42
+ const dangling: string[] = [];
43
+ for (const [name, command] of Object.entries(scripts)) {
44
+ for (const called of calledScripts(command)) {
45
+ if (!(called in scripts)) dangling.push(`${name} → ${called}`);
46
+ }
47
+ }
48
+ expect(dangling).toEqual([]);
49
+ });
50
+
51
+ it('every command the `cursed.app` manifest names is a script', () => {
52
+ const app = (pkg as { cursed?: { app?: Record<string, unknown> } }).cursed?.app ?? {};
53
+ const named: string[] = [];
54
+ for (const key of ['commands', 'extraCommands']) {
55
+ const block = app[key] as Record<string, string> | undefined;
56
+ if (block) named.push(...Object.values(block));
57
+ }
58
+ expect(named.length).toBeGreaterThan(0);
59
+ expect(named.filter((n) => !(n in scripts))).toEqual([]);
60
+ });
61
+
62
+ it('every gate stage is a script', () => {
63
+ const stages = (pkg as { gate?: { stages?: { script: string }[] } }).gate?.stages ?? [];
64
+ expect(stages.map((s) => s.script).filter((n) => !(n in scripts))).toEqual([]);
65
+ });
66
+ });
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 72 candidate(s) scanned.
18
+ * when this file is stale. 71 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 300 candidate(s) scanned.
18
+ * when this file is stale. 303 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 463 candidate(s) scanned.
18
+ * when this file is stale. 462 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 348 candidate(s) scanned.
18
+ * when this file is stale. 388 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -13,7 +13,7 @@
13
13
  *
14
14
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
15
15
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
16
- * when this file is stale. 5187 candidate(s) scanned.
16
+ * when this file is stale. 5197 candidate(s) scanned.
17
17
  *
18
18
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
19
19
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 1349 candidate(s) scanned.
18
+ * when this file is stale. 1350 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 290 candidate(s) scanned.
18
+ * when this file is stale. 289 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 613 candidate(s) scanned.
18
+ * when this file is stale. 616 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 535 candidate(s) scanned.
18
+ * when this file is stale. 574 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 195 candidate(s) scanned.
18
+ * when this file is stale. 198 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,12 +15,118 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 147 candidate(s) scanned.
18
+ * when this file is stale. 189 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
22
22
  * import closures rather than a hand-written list, is scripts/styleAreas.ts.
23
23
  */
24
24
  /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
25
+ @layer properties;
25
26
  @layer theme, base, components, utilities;
26
- @layer utilities;
27
+ @layer utilities {
28
+ .self-stretch {
29
+ align-self: stretch;
30
+ }
31
+ .focus-within\:border-field-ring:focus-within {
32
+ border-color: var(--field-ring);
33
+ }
34
+ .focus-within\:ring-2:focus-within {
35
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
36
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
37
+ }
38
+ .focus-within\:ring-field-ring\/30:focus-within {
39
+ --tw-ring-color: var(--field-ring);
40
+ @supports (color: color-mix(in lab, red, red)) {
41
+ --tw-ring-color: color-mix(in oklab, var(--field-ring) 30%, transparent);
42
+ }
43
+ }
44
+ .has-\[\[aria-invalid\=true\]\]\:border-field-error:has(:is([aria-invalid=true])) {
45
+ border-color: var(--field-error);
46
+ }
47
+ }
48
+ @property --tw-shadow {
49
+ syntax: "*";
50
+ inherits: false;
51
+ initial-value: 0 0 #0000;
52
+ }
53
+ @property --tw-shadow-color {
54
+ syntax: "*";
55
+ inherits: false;
56
+ }
57
+ @property --tw-shadow-alpha {
58
+ syntax: "<percentage>";
59
+ inherits: false;
60
+ initial-value: 100%;
61
+ }
62
+ @property --tw-inset-shadow {
63
+ syntax: "*";
64
+ inherits: false;
65
+ initial-value: 0 0 #0000;
66
+ }
67
+ @property --tw-inset-shadow-color {
68
+ syntax: "*";
69
+ inherits: false;
70
+ }
71
+ @property --tw-inset-shadow-alpha {
72
+ syntax: "<percentage>";
73
+ inherits: false;
74
+ initial-value: 100%;
75
+ }
76
+ @property --tw-ring-color {
77
+ syntax: "*";
78
+ inherits: false;
79
+ }
80
+ @property --tw-ring-shadow {
81
+ syntax: "*";
82
+ inherits: false;
83
+ initial-value: 0 0 #0000;
84
+ }
85
+ @property --tw-inset-ring-color {
86
+ syntax: "*";
87
+ inherits: false;
88
+ }
89
+ @property --tw-inset-ring-shadow {
90
+ syntax: "*";
91
+ inherits: false;
92
+ initial-value: 0 0 #0000;
93
+ }
94
+ @property --tw-ring-inset {
95
+ syntax: "*";
96
+ inherits: false;
97
+ }
98
+ @property --tw-ring-offset-width {
99
+ syntax: "<length>";
100
+ inherits: false;
101
+ initial-value: 0px;
102
+ }
103
+ @property --tw-ring-offset-color {
104
+ syntax: "*";
105
+ inherits: false;
106
+ initial-value: #fff;
107
+ }
108
+ @property --tw-ring-offset-shadow {
109
+ syntax: "*";
110
+ inherits: false;
111
+ initial-value: 0 0 #0000;
112
+ }
113
+ @layer properties {
114
+ @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
115
+ *, ::before, ::after, ::backdrop {
116
+ --tw-shadow: 0 0 #0000;
117
+ --tw-shadow-color: initial;
118
+ --tw-shadow-alpha: 100%;
119
+ --tw-inset-shadow: 0 0 #0000;
120
+ --tw-inset-shadow-color: initial;
121
+ --tw-inset-shadow-alpha: 100%;
122
+ --tw-ring-color: initial;
123
+ --tw-ring-shadow: 0 0 #0000;
124
+ --tw-inset-ring-color: initial;
125
+ --tw-inset-ring-shadow: 0 0 #0000;
126
+ --tw-ring-inset: initial;
127
+ --tw-ring-offset-width: 0px;
128
+ --tw-ring-offset-color: #fff;
129
+ --tw-ring-offset-shadow: 0 0 #0000;
130
+ }
131
+ }
132
+ }
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 2162 candidate(s) scanned.
18
+ * when this file is stale. 2159 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 2849 candidate(s) scanned.
18
+ * when this file is stale. 2777 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -156,9 +156,6 @@
156
156
  border-block-style: var(--tw-border-style);
157
157
  border-block-width: 2px;
158
158
  }
159
- .border-\[color\:var\(--border-strong\)\] {
160
- border-color: var(--border-strong);
161
- }
162
159
  .border-accent {
163
160
  border-color: var(--accent);
164
161
  }
@@ -171,12 +168,6 @@
171
168
  border-color: color-mix(in oklab, var(--color-white) 90%, transparent);
172
169
  }
173
170
  }
174
- .bg-\[color\:color-mix\(in_srgb\,var\(--accent-solid\)_8\%\,transparent\)\] {
175
- background-color: var(--accent-solid);
176
- @supports (color: color-mix(in lab, red, red)) {
177
- background-color: color-mix(in srgb,var(--accent-solid) 8%,transparent);
178
- }
179
- }
180
171
  .bg-accent\/15 {
181
172
  background-color: var(--accent);
182
173
  @supports (color: color-mix(in lab, red, red)) {
@@ -283,9 +274,6 @@
283
274
  .text-\[color\:var\(--accent\)\] {
284
275
  color: var(--accent);
285
276
  }
286
- .text-\[color\:var\(--muted-foreground\)\] {
287
- color: var(--muted-foreground);
288
- }
289
277
  .accent-white {
290
278
  accent-color: var(--color-white);
291
279
  }
@@ -322,10 +310,6 @@
322
310
  .group-focus-within\:opacity-100:is(:where(.group):focus-within *) {
323
311
  opacity: 100%;
324
312
  }
325
- .last\:border-b-0:last-child {
326
- border-bottom-style: var(--tw-border-style);
327
- border-bottom-width: 0px;
328
- }
329
313
  .focus-within\:opacity-100:focus-within {
330
314
  opacity: 100%;
331
315
  }
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 800 candidate(s) scanned.
18
+ * when this file is stale. 799 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 232 candidate(s) scanned.
18
+ * when this file is stale. 231 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 166 candidate(s) scanned.
18
+ * when this file is stale. 165 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 361 candidate(s) scanned.
18
+ * when this file is stale. 360 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 389 candidate(s) scanned.
18
+ * when this file is stale. 392 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -15,7 +15,7 @@
15
15
  *
16
16
  * An app that imports every area gets exactly what `cursedbelt/styles-utilities.css`
17
17
  * emits — proved rule by rule in src/stylesAreas.spec.ts, which is also what fails
18
- * when this file is stale. 247 candidate(s) scanned.
18
+ * when this file is stale. 246 candidate(s) scanned.
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -1591,9 +1591,6 @@
1591
1591
  --tw-border-style: solid;
1592
1592
  border-style: solid;
1593
1593
  }
1594
- .border-\[color\:var\(--border-strong\)\] {
1595
- border-color: var(--border-strong);
1596
- }
1597
1594
  .border-\[var\(--border\)\] {
1598
1595
  border-color: var(--border);
1599
1596
  }
@@ -1741,12 +1738,6 @@
1741
1738
  .border-l-warning {
1742
1739
  border-left-color: var(--warning);
1743
1740
  }
1744
- .bg-\[color\:color-mix\(in_srgb\,var\(--accent-solid\)_8\%\,transparent\)\] {
1745
- background-color: var(--accent-solid);
1746
- @supports (color: color-mix(in lab, red, red)) {
1747
- background-color: color-mix(in srgb,var(--accent-solid) 8%,transparent);
1748
- }
1749
- }
1750
1741
  .bg-\[var\(--accent\)\]\/12 {
1751
1742
  background-color: var(--accent);
1752
1743
  @supports (color: color-mix(in lab, red, red)) {
@@ -2626,9 +2617,6 @@
2626
2617
  .text-\[color\:var\(--accent\)\] {
2627
2618
  color: var(--accent);
2628
2619
  }
2629
- .text-\[color\:var\(--muted-foreground\)\] {
2630
- color: var(--muted-foreground);
2631
- }
2632
2620
  .text-\[var\(--danger\)\] {
2633
2621
  color: var(--danger);
2634
2622
  }
@@ -3299,10 +3287,6 @@
3299
3287
  border-right-style: var(--tw-border-style);
3300
3288
  border-right-width: 0px;
3301
3289
  }
3302
- .last\:border-b-0:last-child {
3303
- border-bottom-style: var(--tw-border-style);
3304
- border-bottom-width: 0px;
3305
- }
3306
3290
  .last\:pr-1:last-child {
3307
3291
  padding-right: var(--spacing);
3308
3292
  }
@@ -0,0 +1,12 @@
1
+ // Loaded only on non-Bun runtimes (task 2087). The `cursedbelt/testing` export map routes the
2
+ // real module to Bun (the `bun` condition) and everything else here, so importing these helpers
3
+ // from Node fails with a sentence instead of `Named export 'waitFor' not found` — which is what
4
+ // Node said about `@testing-library/react`, a CommonJS module its ESM loader cannot name-import.
5
+ // Same shape as `cwip/testing`'s `_noBun`, and `tools/proveInstall.ts` excuses exactly this: a
6
+ // `bun` condition plus a plain `Error` of the package's own making.
7
+ throw new Error(
8
+ 'cursedbelt/testing requires the Bun runtime — it drives @testing-library/react under bun:test + happy-dom. ' +
9
+ 'Import it only from specs run with `bun test`.',
10
+ );
11
+
12
+ export {};
@@ -67,6 +67,17 @@ const MUST_RUN = [
67
67
  // added, removing it argues with this list.
68
68
  'typecheck:scripts',
69
69
  'demo:check',
70
+ // 🔴 Added 2026-09-23 (task 102). `biome lint` was in no command at all — `done:serial`
71
+ // called a `lint` script that did not exist, so the 31 errors it would have shown sat
72
+ // unseen. They were cleared in the same landing (29 were in Tailwind's generated output,
73
+ // now excluded in `biome.jsonc`), so the stage landed green.
74
+ 'lint',
75
+ // 🔴 Added 2026-09-23 with `no-raw-password` (task 077). This repo's own guardrails scan was
76
+ // in no command a gate ran, and it had been RED since task 269 gave every relative specifier
77
+ // its `.js`: `no-native-dialog` stopped recognising DeleteButton's `'../confirm.js'` import
78
+ // as the belt's own `confirm`. The rules this package ships to five apps were not being
79
+ // applied to the package itself.
80
+ 'guardrails:report',
70
81
  'styles',
71
82
  'build',
72
83
  'test',
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- import type { PrivateUnlock } from './usePrivateUnlock.js';
3
- export declare function PrivateIndexView({ unlock }: {
4
- unlock: PrivateUnlock;
5
- }): React.JSX.Element;
6
- //# sourceMappingURL=PrivateIndexView.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PrivateIndexView.d.ts","sourceRoot":"","sources":["../../../src/react/media/PrivateIndexView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAS5E,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,qBAmGrE"}
@@ -1,44 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { formatBytes as fmtBytes } from 'cwip/format';
3
- import React from 'react';
4
- import { Button } from '../components/Button.js';
5
- import { Input } from '../components/Input.js';
6
- // The locked-index cleanup view: every private item's SIZE + created-date (never its title,
7
- // thumbnail, or notes), so a user can prune media whose password they've lost. A password field
8
- // runs "try-a-password" — items it decrypts light up with their revealed title; the rest stay
9
- // opaque. Themed off cursedbelt tokens (with fallbacks so it renders anywhere).
10
- const fmtDate = (ts) => new Date(ts).toISOString().slice(0, 10);
11
- export function PrivateIndexView({ unlock }) {
12
- const [rows, setRows] = React.useState([]);
13
- const [revealed, setRevealed] = React.useState(new Map());
14
- const [password, setPassword] = React.useState('');
15
- const [trying, setTrying] = React.useState(false);
16
- React.useEffect(() => {
17
- unlock.loadIndex().then(setRows);
18
- }, [unlock]);
19
- async function tryPassword() {
20
- if (!password)
21
- return;
22
- setTrying(true);
23
- try {
24
- const items = await unlock.reveal(password);
25
- setRevealed(new Map(items.map((i) => [i.id, i.meta])));
26
- }
27
- finally {
28
- setTrying(false);
29
- }
30
- }
31
- const totalBytes = rows.reduce((s, r) => s + r.sizeBytes, 0);
32
- const matchCount = revealed.size;
33
- return (_jsxs("div", { className: 'flex flex-col gap-3 text-sm', children: [_jsxs("div", { className: 'flex items-center justify-between gap-3', children: [_jsxs("div", { className: 'text-[color:var(--muted-foreground)]', children: [rows.length, " locked ", rows.length === 1 ? 'file' : 'files', " \u00B7 ", fmtBytes(totalBytes)] }), _jsxs("div", { className: 'flex items-center gap-2', children: [_jsx(Input, { type: 'password', value: password, onChange: (e) => setPassword(e.target.value), onEnter: () => tryPassword(), placeholder: 'Try a password\u2026', "aria-label": 'Try a password', className: 'h-auto w-auto bg-transparent px-2 py-1' }), _jsx(Button, { size: 'sm', onClick: tryPassword, disabled: trying || !password, loading: trying, tooltip: 'Try this password against every locked file', children: trying ? 'Trying…' : 'Reveal' })] })] }), matchCount > 0 ? (_jsxs("div", { className: 'text-[color:var(--accent)]', children: ["This password unlocks ", matchCount, " ", matchCount === 1 ? 'file' : 'files', "."] })) : null, _jsxs("div", { className: 'overflow-hidden rounded-lg border border-[color:var(--border-strong)]', children: [rows.map((r) => {
34
- const meta = revealed.get(r.id);
35
- const title = typeof meta?.title === 'string' ? meta.title : null;
36
- return (_jsxs("div", { className: `flex items-center justify-between gap-3 border-b border-[color:var(--border-strong)] px-3 py-2 last:border-b-0 ${
37
- // `--card-overlay` (white/navy per theme.css) isn't the tint this row wants —
38
- // the original rgba(16,185,129,0.08) fallback was an emerald-accent highlight,
39
- // not the neutral card-overlay token, so build the same tint from the real
40
- // accent token via color-mix instead of a literal fallback color.
41
- title ? 'bg-[color:color-mix(in_srgb,var(--accent-solid)_8%,transparent)]' : ''}`, children: [_jsx("div", { className: 'min-w-0 flex-1 truncate', children: title ? (_jsx("span", { className: 'font-medium text-[color:var(--accent)]', children: title })) : (_jsxs("span", { className: 'font-mono text-[color:var(--muted-foreground)]', children: ["\uD83D\uDD12 ", r.id.slice(0, 8), "\u2026"] })) }), _jsx("div", { className: 'shrink-0 tabular-nums text-[color:var(--muted-foreground)]', children: fmtBytes(r.sizeBytes) }), _jsx("div", { className: 'shrink-0 tabular-nums text-[color:var(--muted-foreground)]', children: fmtDate(r.createdAt) })] }, r.id));
42
- }), rows.length === 0 ? (_jsx("div", { className: 'px-3 py-6 text-center text-[color:var(--muted-foreground)]', children: "No private files." })) : null] })] }));
43
- }
44
- //# sourceMappingURL=PrivateIndexView.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PrivateIndexView.js","sourceRoot":"","sources":["../../../src/react/media/PrivateIndexView.tsx"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- export interface PrivateModeBadgeProps {
2
- /** How many items are private (shown in the label). */
3
- hiddenCount: number;
4
- /** Whether the feed is currently filtered to private-only. */
5
- active: boolean;
6
- /** Toggle the private-only filter. */
7
- onToggle: () => void;
8
- className?: string;
9
- }
10
- /**
11
- * The "🔓 N private" toggle pill shown in a media gallery's header once private
12
- * mode is unlocked — click filters the feed to private-only items. One shared
13
- * implementation for every gallery (video/photo/media); it was previously
14
- * copy-pasted per plugin with per-plugin CSS classes.
15
- */
16
- export declare function PrivateModeBadge({ hiddenCount, active, onToggle, className }: PrivateModeBadgeProps): import("react").JSX.Element;
17
- //# sourceMappingURL=PrivateModeBadge.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PrivateModeBadge.d.ts","sourceRoot":"","sources":["../../../src/react/media/PrivateModeBadge.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,qBAAqB,+BA8BnG"}
@@ -1,24 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '../lib/cn.js';
3
- import { Tooltip } from '../components/Tooltip.js';
4
- /**
5
- * The "🔓 N private" toggle pill shown in a media gallery's header once private
6
- * mode is unlocked — click filters the feed to private-only items. One shared
7
- * implementation for every gallery (video/photo/media); it was previously
8
- * copy-pasted per plugin with per-plugin CSS classes.
9
- */
10
- export function PrivateModeBadge({ hiddenCount, active, onToggle, className }) {
11
- return (_jsx(Tooltip, { content: 'Private mode unlocked \u2014 click to show only private items', children: _jsxs("button", {
12
- // guardrails-ignore no-raw-action-button: compact header pill with pressed
13
- // state — Button's control-height/variant chrome doesn't fit a badge-sized
14
- // toggle; this keeps the exact badge geometry the galleries share.
15
- type: 'button', "data-cb-private-badge": '', "aria-pressed": active, onClick: onToggle, className: cn('inline-flex shrink-0 cursor-pointer items-center gap-1 rounded-full border border-border bg-surface px-2.5 py-0.5 text-xs font-medium text-muted-foreground transition-colors', 'hover:border-accent hover:text-foreground', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
16
- // `text-accent-strong`, not plain `text-accent` — the /15 tint only clears
17
- // 4.43:1 with the base accent hue, under AA (cbux-101). (Previously
18
- // `text-accent-foreground`, a token this library never defines — an
19
- // undefined Tailwind color utility compiles to no rule at all, so the
20
- // pill silently fell back to inherited text color instead of an
21
- // intentional one.)
22
- active && 'border-accent bg-accent/15 text-accent-strong', className), children: [_jsx("span", { "aria-hidden": true, children: "\uD83D\uDD13" }), hiddenCount, " private"] }) }));
23
- }
24
- //# sourceMappingURL=PrivateModeBadge.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PrivateModeBadge.js","sourceRoot":"","sources":["../../../src/react/media/PrivateModeBadge.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAYnD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAyB;IAClG,OAAO,CACL,KAAC,OAAO,IAAC,OAAO,EAAC,+DAA0D,YACzE;YACE,2EAA2E;YAC3E,2EAA2E;YAC3E,mEAAmE;YACnE,IAAI,EAAC,QAAQ,2BACS,EAAE,kBACV,MAAM,EACpB,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,EAAE,CACX,+KAA+K,EAC/K,2CAA2C,EAC3C,yEAAyE;YACzE,2EAA2E;YAC3E,oEAAoE;YACpE,oEAAoE;YACpE,sEAAsE;YACtE,gEAAgE;YAChE,oBAAoB;YACpB,MAAM,IAAI,+CAA+C,EACzD,SAAS,CACV,aAED,+DAA2B,EAC1B,WAAW,gBACL,GACD,CACX,CAAC;AACJ,CAAC"}
@@ -1,34 +0,0 @@
1
- /** A clear index row — non-sensitive facts only (matches the server's PrivateIndexRow). */
2
- export type PrivateIndexRow = {
3
- id: string;
4
- sizeBytes: number;
5
- createdAt: number;
6
- status: 'pending' | 'processing' | 'ready' | 'failed';
7
- };
8
- export type RevealedItem = {
9
- id: string;
10
- meta: Record<string, unknown>;
11
- };
12
- export interface PrivateClientConfig {
13
- /** Origin+prefix for the private routes. '' = same-origin; an absolute API origin for a
14
- * split-origin deploy. */
15
- apiBase?: string;
16
- /** Route mount prefix (must match mountPrivateRoutes basePath). Default '/_private'. */
17
- basePath?: string;
18
- /** Extra headers for the GUARDED calls (unlock/index/reveal) — e.g. the app's Bearer. The
19
- * token-embedded byte/key URLs need no header. */
20
- authHeaders?: () => Record<string, string>;
21
- }
22
- export declare const privateBaseUrl: (cfg: PrivateClientConfig) => string;
23
- /** Try `password` against every item; returns the ones it decrypts (with their metadata). */
24
- export declare const revealPrivateWithPassword: (cfg: PrivateClientConfig, password: string) => Promise<RevealedItem[]>;
25
- /** Reveal the items an UNLOCK TOKEN opens — no password re-entry. The token must belong to the
26
- * session caller (the server enforces it). */
27
- export declare const revealPrivateWithToken: (cfg: PrivateClientConfig, token: string) => Promise<RevealedItem[]>;
28
- /** The token-embedded HLS master URL for a private video — same shape usePrivateUnlock.hlsUrl
29
- * builds. Needs no auth header (the token IS the authorization). */
30
- export declare const privateHlsUrlWithToken: (cfg: PrivateClientConfig, token: string, sourceId: string, videoId: string) => string;
31
- /** The token-embedded URL for a private NON-video file (photo/doc) stored as an encrypted
32
- * blob — served decrypted by the gated blob route. Needs no auth header. */
33
- export declare const privateFileUrlWithToken: (cfg: PrivateClientConfig, token: string, fileId: string) => string;
34
- //# sourceMappingURL=privateClient.d.ts.map