artshelf 0.3.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.
package/docs/site.css ADDED
@@ -0,0 +1,639 @@
1
+ :root {
2
+ color-scheme: light;
3
+ --bg: #f6f7f4;
4
+ --panel: #ffffff;
5
+ --panel-strong: #eef4ef;
6
+ --nav-bg: #fbfcf8;
7
+ --ink: #141713;
8
+ --body-ink: #30382f;
9
+ --muted: #667064;
10
+ --line: #d9dfd5;
11
+ --line-soft: #eef1eb;
12
+ --code-bg: #eef1eb;
13
+ --code-ink: #182018;
14
+ --pre-bg: #0d1420;
15
+ --pre-ink: #edf7ea;
16
+ --pre-border: #1e293b;
17
+ --accent: #1d7b5b;
18
+ --accent-strong: #105d43;
19
+ --blue: #2364aa;
20
+ --amber: #9a5b11;
21
+ --red: #9e3b3b;
22
+ --warn: #fff8df;
23
+ --shadow: 0 18px 48px rgba(20, 23, 19, 0.08);
24
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
25
+ }
26
+
27
+ html[data-theme="dark"] {
28
+ color-scheme: dark;
29
+ --bg: #090b09;
30
+ --panel: #111610;
31
+ --panel-strong: #172117;
32
+ --nav-bg: #0d100c;
33
+ --ink: #f4f7ef;
34
+ --body-ink: #d7dfd0;
35
+ --muted: #9da795;
36
+ --line: #293323;
37
+ --line-soft: #1d261a;
38
+ --code-bg: #1c2519;
39
+ --code-ink: #e9f2e2;
40
+ --pre-bg: #050812;
41
+ --pre-ink: #edf7ea;
42
+ --pre-border: #20283a;
43
+ --accent: #62d7a3;
44
+ --accent-strong: #95efbf;
45
+ --blue: #8ebcff;
46
+ --amber: #efc66f;
47
+ --red: #f28b8b;
48
+ --warn: #2b2412;
49
+ --shadow: 0 18px 50px rgba(0, 0, 0, 0.3);
50
+ }
51
+
52
+ * {
53
+ box-sizing: border-box;
54
+ }
55
+
56
+ body {
57
+ margin: 0;
58
+ background: var(--bg);
59
+ color: var(--ink);
60
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
61
+ font-feature-settings: "cv02", "cv03", "cv04", "cv11";
62
+ line-height: 1.65;
63
+ -webkit-font-smoothing: antialiased;
64
+ overflow-x: hidden;
65
+ }
66
+
67
+ a {
68
+ color: var(--accent-strong);
69
+ font-weight: 650;
70
+ text-decoration-thickness: 1px;
71
+ text-underline-offset: 0.2em;
72
+ }
73
+
74
+ code,
75
+ pre {
76
+ font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
77
+ }
78
+
79
+ code {
80
+ border: 1px solid var(--line);
81
+ border-radius: 5px;
82
+ background: var(--code-bg);
83
+ color: var(--code-ink);
84
+ padding: 0.08em 0.35em;
85
+ font-size: 0.88em;
86
+ }
87
+
88
+ pre {
89
+ width: 100%;
90
+ max-width: 100%;
91
+ min-width: 0;
92
+ overflow: auto;
93
+ border: 1px solid var(--pre-border);
94
+ border-radius: 8px;
95
+ background: var(--pre-bg);
96
+ color: var(--pre-ink);
97
+ padding: 14px 18px;
98
+ font-size: 0.9rem;
99
+ font-weight: 520;
100
+ line-height: 1.6;
101
+ scrollbar-color: #334155 transparent;
102
+ scrollbar-width: thin;
103
+ }
104
+
105
+ pre code {
106
+ display: block;
107
+ width: max-content;
108
+ min-width: 100%;
109
+ border: 0;
110
+ background: transparent;
111
+ color: inherit;
112
+ padding: 0;
113
+ font-size: 1em;
114
+ white-space: pre;
115
+ }
116
+
117
+ .docs-shell {
118
+ display: grid;
119
+ grid-template-columns: 248px minmax(0, 1fr);
120
+ min-height: 100vh;
121
+ }
122
+
123
+ .global-nav {
124
+ position: sticky;
125
+ top: 0;
126
+ display: grid;
127
+ grid-template-columns: minmax(0, 1fr) auto;
128
+ align-content: start;
129
+ column-gap: 10px;
130
+ height: 100vh;
131
+ overflow: auto;
132
+ border-right: 1px solid var(--line);
133
+ background: var(--nav-bg);
134
+ padding: 24px 22px;
135
+ scrollbar-color: var(--line) transparent;
136
+ scrollbar-width: thin;
137
+ }
138
+
139
+ .site-mark {
140
+ display: grid;
141
+ gap: 4px;
142
+ min-width: 0;
143
+ margin-bottom: 18px;
144
+ border-bottom: 1px solid var(--line);
145
+ padding: 0 0 18px;
146
+ text-decoration: none;
147
+ }
148
+
149
+ .site-mark strong {
150
+ color: var(--ink);
151
+ font-size: 1.08rem;
152
+ font-weight: 700;
153
+ line-height: 1.1;
154
+ }
155
+
156
+ .site-mark span,
157
+ .nav-section-title,
158
+ .breadcrumbs {
159
+ color: var(--muted);
160
+ font-size: 0.74rem;
161
+ }
162
+
163
+ .nav-section {
164
+ display: grid;
165
+ grid-column: 1 / -1;
166
+ gap: 7px;
167
+ margin-bottom: 18px;
168
+ }
169
+
170
+ .nav-scroll {
171
+ display: contents;
172
+ }
173
+
174
+ .nav-section-title {
175
+ margin: 0;
176
+ font-weight: 700;
177
+ letter-spacing: 0;
178
+ text-transform: uppercase;
179
+ }
180
+
181
+ .global-nav a:not(.site-mark) {
182
+ display: block;
183
+ border-radius: 6px;
184
+ padding: 6px 10px;
185
+ color: var(--body-ink);
186
+ font-size: 0.9rem;
187
+ line-height: 1.4;
188
+ text-decoration: none;
189
+ }
190
+
191
+ .global-nav a:not(.site-mark):hover,
192
+ .global-nav a[aria-current="page"] {
193
+ background: var(--panel-strong);
194
+ color: var(--accent-strong);
195
+ }
196
+
197
+ .theme-toggle {
198
+ display: inline-flex;
199
+ width: 34px;
200
+ height: 34px;
201
+ flex: 0 0 auto;
202
+ align-items: center;
203
+ justify-content: center;
204
+ border: 1px solid var(--line);
205
+ border-radius: 8px;
206
+ background: var(--panel);
207
+ color: var(--muted);
208
+ cursor: pointer;
209
+ padding: 0;
210
+ }
211
+
212
+ .theme-toggle:hover {
213
+ border-color: var(--ink);
214
+ color: var(--ink);
215
+ }
216
+
217
+ .theme-toggle svg {
218
+ display: block;
219
+ width: 16px;
220
+ height: 16px;
221
+ }
222
+
223
+ .theme-toggle .theme-icon-sun,
224
+ html[data-theme="dark"] .theme-toggle .theme-icon-moon {
225
+ display: none;
226
+ }
227
+
228
+ html[data-theme="dark"] .theme-toggle .theme-icon-sun {
229
+ display: block;
230
+ }
231
+
232
+ .docs-content {
233
+ min-width: 0;
234
+ max-width: 100vw;
235
+ overflow-x: clip;
236
+ }
237
+
238
+ .page-top {
239
+ border-bottom: 1px solid var(--line);
240
+ background: var(--nav-bg);
241
+ }
242
+
243
+ .wrap {
244
+ width: min(1120px, calc(100% - 36px));
245
+ min-width: 0;
246
+ margin-right: auto;
247
+ margin-left: auto;
248
+ }
249
+
250
+ .breadcrumbs {
251
+ display: flex;
252
+ flex-wrap: wrap;
253
+ gap: 8px;
254
+ align-items: center;
255
+ padding-top: 20px;
256
+ font-weight: 750;
257
+ }
258
+
259
+ .breadcrumbs a {
260
+ color: var(--muted);
261
+ text-decoration: none;
262
+ }
263
+
264
+ .hero {
265
+ display: grid;
266
+ grid-template-columns: minmax(0, 1.08fr) minmax(320px, 0.92fr);
267
+ gap: 28px;
268
+ align-items: center;
269
+ padding: 34px 0 30px;
270
+ }
271
+
272
+ .hero > *,
273
+ .terminal,
274
+ .card,
275
+ .doc-card,
276
+ .stat,
277
+ .command-row {
278
+ min-width: 0;
279
+ }
280
+
281
+ .eyebrow {
282
+ margin: 0 0 10px;
283
+ color: var(--muted);
284
+ font-size: 0.72rem;
285
+ font-weight: 700;
286
+ letter-spacing: 0;
287
+ text-transform: uppercase;
288
+ }
289
+
290
+ h1 {
291
+ margin: 0;
292
+ max-width: 820px;
293
+ color: var(--ink);
294
+ font-size: 3.25rem;
295
+ font-weight: 760;
296
+ letter-spacing: 0;
297
+ line-height: 1.06;
298
+ overflow-wrap: anywhere;
299
+ }
300
+
301
+ h2 {
302
+ margin: 0 0 12px;
303
+ color: var(--ink);
304
+ font-size: 1.55rem;
305
+ font-weight: 700;
306
+ letter-spacing: 0;
307
+ line-height: 1.2;
308
+ }
309
+
310
+ h3 {
311
+ margin: 0 0 8px;
312
+ color: var(--ink);
313
+ font-size: 1.08rem;
314
+ font-weight: 700;
315
+ }
316
+
317
+ p,
318
+ li {
319
+ color: var(--body-ink);
320
+ font-size: 1rem;
321
+ line-height: 1.68;
322
+ }
323
+
324
+ .lede {
325
+ max-width: 790px;
326
+ margin: 18px 0 0;
327
+ color: var(--muted);
328
+ font-size: 1.08rem;
329
+ line-height: 1.6;
330
+ }
331
+
332
+ .actions,
333
+ .tag-row {
334
+ display: flex;
335
+ flex-wrap: wrap;
336
+ gap: 10px;
337
+ }
338
+
339
+ .actions {
340
+ margin-top: 22px;
341
+ }
342
+
343
+ .button,
344
+ .pill {
345
+ display: inline-flex;
346
+ min-height: 38px;
347
+ align-items: center;
348
+ justify-content: center;
349
+ border: 1px solid var(--line);
350
+ border-radius: 6px;
351
+ background: var(--panel);
352
+ padding: 0 14px;
353
+ color: var(--ink);
354
+ text-decoration: none;
355
+ }
356
+
357
+ .button.primary {
358
+ border-color: var(--accent);
359
+ background: var(--accent);
360
+ color: #ffffff;
361
+ }
362
+
363
+ .terminal {
364
+ border: 1px solid var(--pre-border);
365
+ border-radius: 8px;
366
+ overflow: hidden;
367
+ background: var(--pre-bg);
368
+ box-shadow: var(--shadow);
369
+ }
370
+
371
+ .terminal-head {
372
+ display: flex;
373
+ gap: 6px;
374
+ align-items: center;
375
+ border-bottom: 1px solid var(--pre-border);
376
+ padding: 10px 14px;
377
+ color: #94a3b8;
378
+ font-size: 0.78rem;
379
+ }
380
+
381
+ .dot {
382
+ width: 10px;
383
+ height: 10px;
384
+ border-radius: 999px;
385
+ background: #ef4444;
386
+ }
387
+
388
+ .dot:nth-child(2) {
389
+ background: #f59e0b;
390
+ }
391
+
392
+ .dot:nth-child(3) {
393
+ background: #22c55e;
394
+ }
395
+
396
+ .terminal pre {
397
+ margin: 0;
398
+ border: 0;
399
+ border-radius: 0;
400
+ box-shadow: none;
401
+ }
402
+
403
+ main {
404
+ min-width: 0;
405
+ padding: 30px 0 56px;
406
+ }
407
+
408
+ article {
409
+ display: grid;
410
+ min-width: 0;
411
+ gap: 28px;
412
+ }
413
+
414
+ article > section {
415
+ min-width: 0;
416
+ max-width: 100%;
417
+ border-top: 1px solid var(--line);
418
+ padding-top: 28px;
419
+ }
420
+
421
+ article > section:first-child {
422
+ border-top: 0;
423
+ padding-top: 0;
424
+ }
425
+
426
+ .grid,
427
+ .summary-grid {
428
+ display: grid;
429
+ grid-template-columns: repeat(3, minmax(0, 1fr));
430
+ gap: 12px;
431
+ }
432
+
433
+ .summary-grid {
434
+ grid-template-columns: repeat(4, minmax(0, 1fr));
435
+ }
436
+
437
+ .card,
438
+ .doc-card,
439
+ .stat,
440
+ .note {
441
+ border: 1px solid var(--line);
442
+ border-radius: 8px;
443
+ background: var(--panel);
444
+ padding: 16px;
445
+ }
446
+
447
+ .doc-card {
448
+ display: grid;
449
+ gap: 8px;
450
+ min-height: 148px;
451
+ align-content: start;
452
+ text-decoration: none;
453
+ }
454
+
455
+ .doc-card strong,
456
+ .stat strong {
457
+ color: var(--ink);
458
+ font-size: 1.08rem;
459
+ }
460
+
461
+ .doc-card span,
462
+ .stat span,
463
+ .card p {
464
+ margin: 0;
465
+ color: var(--muted);
466
+ font-size: 0.94rem;
467
+ line-height: 1.46;
468
+ }
469
+
470
+ .stat strong {
471
+ display: block;
472
+ font-size: 1.9rem;
473
+ line-height: 1;
474
+ }
475
+
476
+ .note {
477
+ border-color: #e0c36d;
478
+ background: var(--warn);
479
+ }
480
+
481
+ .command-list {
482
+ display: grid;
483
+ gap: 10px;
484
+ }
485
+
486
+ .command-row {
487
+ display: grid;
488
+ grid-template-columns: minmax(170px, 0.42fr) minmax(0, 1fr);
489
+ gap: 12px;
490
+ align-items: start;
491
+ border: 1px solid var(--line);
492
+ border-radius: 8px;
493
+ background: var(--panel);
494
+ padding: 12px;
495
+ }
496
+
497
+ .command-row p {
498
+ margin: 0;
499
+ color: var(--muted);
500
+ }
501
+
502
+ .site-footer {
503
+ border-top: 1px solid var(--line);
504
+ background: var(--panel);
505
+ color: var(--muted);
506
+ padding: 20px 0;
507
+ }
508
+
509
+ html[data-theme="dark"] .card,
510
+ html[data-theme="dark"] .doc-card,
511
+ html[data-theme="dark"] .stat,
512
+ html[data-theme="dark"] .command-row,
513
+ html[data-theme="dark"] .theme-toggle {
514
+ border-color: var(--line);
515
+ background: var(--panel);
516
+ }
517
+
518
+ html[data-theme="dark"] .note {
519
+ border-color: #6a5321;
520
+ background: var(--warn);
521
+ }
522
+
523
+ @media (max-width: 960px) {
524
+ .docs-shell {
525
+ display: block;
526
+ }
527
+
528
+ .global-nav {
529
+ position: sticky;
530
+ z-index: 10;
531
+ grid-template-columns: minmax(0, 1fr) auto;
532
+ height: auto;
533
+ max-height: none;
534
+ align-items: center;
535
+ border-right: 0;
536
+ border-bottom: 1px solid var(--line);
537
+ padding: 16px 20px 12px;
538
+ overflow: hidden;
539
+ box-shadow: 0 8px 26px rgba(20, 23, 19, 0.06);
540
+ }
541
+
542
+ html[data-theme="dark"] .global-nav {
543
+ box-shadow: 0 8px 26px rgba(0, 0, 0, 0.24);
544
+ }
545
+
546
+ .site-mark {
547
+ margin-bottom: 4px;
548
+ border-bottom: 0;
549
+ padding-bottom: 0;
550
+ }
551
+
552
+ .nav-scroll {
553
+ display: flex;
554
+ grid-column: 1 / -1;
555
+ gap: 8px;
556
+ margin: 2px -20px 0;
557
+ overflow-x: auto;
558
+ padding: 8px 20px 4px;
559
+ scrollbar-color: var(--line) transparent;
560
+ scrollbar-width: thin;
561
+ }
562
+
563
+ .nav-section {
564
+ display: flex;
565
+ flex: 0 0 auto;
566
+ gap: 8px;
567
+ margin: 0;
568
+ }
569
+
570
+ .nav-section-title {
571
+ display: none;
572
+ }
573
+
574
+ .global-nav a:not(.site-mark) {
575
+ flex: 0 0 auto;
576
+ border: 1px solid var(--line);
577
+ background: var(--panel);
578
+ padding: 8px 11px;
579
+ white-space: nowrap;
580
+ }
581
+
582
+ .hero,
583
+ .grid,
584
+ .summary-grid,
585
+ .command-row {
586
+ grid-template-columns: 1fr;
587
+ }
588
+
589
+ h1 {
590
+ font-size: 2.35rem;
591
+ }
592
+
593
+ h2 {
594
+ font-size: 1.38rem;
595
+ }
596
+ }
597
+
598
+ @media (max-width: 560px) {
599
+ .wrap {
600
+ width: calc(100vw - 32px);
601
+ max-width: calc(100vw - 32px);
602
+ }
603
+
604
+ .global-nav {
605
+ padding-right: 16px;
606
+ padding-left: 16px;
607
+ }
608
+
609
+ .nav-scroll {
610
+ margin-right: -16px;
611
+ margin-left: -16px;
612
+ padding-right: 16px;
613
+ padding-left: 16px;
614
+ }
615
+
616
+ .site-mark span {
617
+ display: none;
618
+ }
619
+
620
+ .actions {
621
+ display: grid;
622
+ grid-template-columns: 1fr;
623
+ }
624
+
625
+ .button,
626
+ .pill {
627
+ width: 100%;
628
+ }
629
+
630
+ pre {
631
+ padding: 12px 14px;
632
+ font-size: 0.82rem;
633
+ }
634
+
635
+ h1 {
636
+ font-size: 1.82rem;
637
+ line-height: 1.12;
638
+ }
639
+ }
package/docs/theme.js ADDED
@@ -0,0 +1,42 @@
1
+ (function () {
2
+ const storageKey = "artshelf-docs-theme";
3
+ const root = document.documentElement;
4
+ const systemDark = window.matchMedia("(prefers-color-scheme: dark)");
5
+ const toggleIcon = `
6
+ <svg class="theme-icon-moon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.6 12.1A6.5 6.5 0 0 1 7.4 2.7a6.5 6.5 0 1 0 7.2 9.4z" fill="currentColor"></path></svg>
7
+ <svg class="theme-icon-sun" viewBox="0 0 20 20" aria-hidden="true"><circle cx="10" cy="10" r="3.4" fill="currentColor"></circle><g stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><line x1="10" y1="2" x2="10" y2="4"></line><line x1="10" y1="16" x2="10" y2="18"></line><line x1="2" y1="10" x2="4" y2="10"></line><line x1="16" y1="10" x2="18" y2="10"></line><line x1="4.2" y1="4.2" x2="5.6" y2="5.6"></line><line x1="14.4" y1="14.4" x2="15.8" y2="15.8"></line><line x1="4.2" y1="15.8" x2="5.6" y2="14.4"></line><line x1="14.4" y1="5.6" x2="15.8" y2="4.2"></line></g></svg>
8
+ `;
9
+
10
+ function preferredTheme() {
11
+ const saved = window.localStorage.getItem(storageKey);
12
+ if (saved === "light" || saved === "dark") return saved;
13
+ return systemDark.matches ? "dark" : "light";
14
+ }
15
+
16
+ function applyTheme(theme) {
17
+ root.dataset.theme = theme;
18
+ root.style.colorScheme = theme;
19
+ document.querySelectorAll("[data-theme-toggle]").forEach((button) => {
20
+ button.setAttribute("aria-pressed", theme === "dark" ? "true" : "false");
21
+ button.setAttribute("title", theme === "dark" ? "Switch to light mode" : "Switch to dark mode");
22
+ if (button.innerHTML !== toggleIcon) button.innerHTML = toggleIcon;
23
+ });
24
+ }
25
+
26
+ applyTheme(preferredTheme());
27
+
28
+ window.addEventListener("DOMContentLoaded", () => {
29
+ applyTheme(preferredTheme());
30
+ document.querySelectorAll("[data-theme-toggle]").forEach((button) => {
31
+ button.addEventListener("click", () => {
32
+ const nextTheme = root.dataset.theme === "dark" ? "light" : "dark";
33
+ window.localStorage.setItem(storageKey, nextTheme);
34
+ applyTheme(nextTheme);
35
+ });
36
+ });
37
+ });
38
+
39
+ systemDark.addEventListener("change", () => {
40
+ if (!window.localStorage.getItem(storageKey)) applyTheme(preferredTheme());
41
+ });
42
+ })();
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "artshelf",
3
+ "version": "0.3.0",
4
+ "description": "Tiny CLI for accountable temporary artifact retention.",
5
+ "type": "module",
6
+ "author": "Calvin",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/calvinnwq/artshelf.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/calvinnwq/artshelf/issues"
13
+ },
14
+ "homepage": "https://calvinnwq.github.io/artshelf/",
15
+ "keywords": [
16
+ "artifact-retention",
17
+ "cleanup",
18
+ "cli",
19
+ "jsonl",
20
+ "tmp"
21
+ ],
22
+ "bin": {
23
+ "artshelf": "dist/src/cli.js",
24
+ "shelf": "dist/src/cli.js"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "files": [
30
+ "dist/src",
31
+ "docs",
32
+ "skills",
33
+ "CHANGELOG.md",
34
+ "LICENSE",
35
+ "README.md",
36
+ "SPEC.md"
37
+ ],
38
+ "scripts": {
39
+ "build": "tsc -p tsconfig.json",
40
+ "typecheck": "tsc -p tsconfig.json --noEmit",
41
+ "lint": "pnpm run typecheck",
42
+ "format:check": "git diff --check",
43
+ "test": "node --test dist/tests/*.test.js",
44
+ "check": "pnpm run build && pnpm run test",
45
+ "docs:serve": "python3 -m http.server 8080 --bind 127.0.0.1 --directory docs",
46
+ "start": "node dist/src/cli.js"
47
+ },
48
+ "devDependencies": {
49
+ "typescript": "^5.9.3"
50
+ },
51
+ "engines": {
52
+ "node": ">=22"
53
+ },
54
+ "packageManager": "pnpm@10.33.3",
55
+ "license": "MIT"
56
+ }