artshelf 0.6.0 → 0.7.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.js ADDED
@@ -0,0 +1,397 @@
1
+ /* Artshelf docs — chrome rendered from one manifest. */
2
+ (function () {
3
+ "use strict";
4
+
5
+ var NAV = [
6
+ {
7
+ title: "Start",
8
+ items: [
9
+ { n: "01", t: "Overview", h: "index.html" },
10
+ { n: "02", t: "Install", h: "install.html" },
11
+ { n: "03", t: "Quickstart", h: "quickstart.html" }
12
+ ]
13
+ },
14
+ {
15
+ title: "Agents",
16
+ items: [
17
+ {
18
+ n: "04", t: "Agent usage", h: "agent-usage.html",
19
+ children: [
20
+ { n: "4.1", t: "Create", h: "agent-create.html" },
21
+ { n: "4.2", t: "Monitor", h: "agent-monitor.html" },
22
+ { n: "4.3", t: "Review", h: "agent-review.html" },
23
+ { n: "4.4", t: "Clean", h: "agent-clean.html" }
24
+ ]
25
+ },
26
+ { t: "Agent skill", h: "https://github.com/calvinnwq/artshelf/tree/main/skills/artshelf", ext: true }
27
+ ]
28
+ },
29
+ {
30
+ title: "Reference",
31
+ items: [
32
+ { n: "05", t: "CLI reference", h: "reference.html" },
33
+ { t: "GitHub", h: "https://github.com/calvinnwq/artshelf", ext: true }
34
+ ]
35
+ }
36
+ ];
37
+
38
+ var ORDER = [];
39
+ NAV.forEach(function (g) {
40
+ g.items.forEach(function (i) {
41
+ if (!i.ext) {
42
+ ORDER.push(i);
43
+ (i.children || []).forEach(function (c) { ORDER.push(c); });
44
+ }
45
+ });
46
+ });
47
+
48
+ var page = document.body.dataset.page || "index.html";
49
+
50
+ /* ---------- theme ---------- */
51
+
52
+ var THEME_KEY = "artshelf-docs-theme";
53
+ var INDEX_KEY = "artshelf-docs-index-v1";
54
+
55
+ function getStorageItem(storageName, key) {
56
+ try {
57
+ return window[storageName].getItem(key);
58
+ } catch (_) {
59
+ return null;
60
+ }
61
+ }
62
+
63
+ function setStorageItem(storageName, key, value) {
64
+ try {
65
+ window[storageName].setItem(key, value);
66
+ } catch (_) {}
67
+ }
68
+
69
+ function getStoredTheme() {
70
+ return getStorageItem("localStorage", THEME_KEY);
71
+ }
72
+ function setStoredTheme(t) {
73
+ setStorageItem("localStorage", THEME_KEY, t);
74
+ }
75
+ function preferredTheme() {
76
+ return getStoredTheme() ||
77
+ (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
78
+ }
79
+ function applyTheme(t) {
80
+ document.documentElement.dataset.theme = t;
81
+ document.querySelectorAll("[data-theme-toggle]").forEach(function (b) {
82
+ b.setAttribute("aria-pressed", t === "dark" ? "true" : "false");
83
+ });
84
+ }
85
+ document.addEventListener("click", function (e) {
86
+ if (!e.target.closest("[data-theme-toggle]")) return;
87
+ var next = document.documentElement.dataset.theme === "dark" ? "light" : "dark";
88
+ setStoredTheme(next);
89
+ applyTheme(next);
90
+ });
91
+
92
+ /* ---------- sidebar ---------- */
93
+
94
+ function navLink(item, child) {
95
+ var a = document.createElement("a");
96
+ a.href = item.h;
97
+ if (item.ext) { a.className = "ext"; a.rel = "noopener"; }
98
+ if (item.h === page) a.setAttribute("aria-current", "page");
99
+ if (item.n) {
100
+ var n = document.createElement("span");
101
+ n.className = "n";
102
+ n.textContent = item.n;
103
+ a.appendChild(n);
104
+ }
105
+ a.appendChild(document.createTextNode(item.t));
106
+ return a;
107
+ }
108
+
109
+ function renderSidebar() {
110
+ var nav = document.getElementById("sidebar");
111
+ if (!nav) return;
112
+ NAV.forEach(function (group) {
113
+ var box = document.createElement("div");
114
+ box.className = "nav-group";
115
+ var h = document.createElement("p");
116
+ h.className = "nav-group-title";
117
+ h.textContent = group.title;
118
+ box.appendChild(h);
119
+ group.items.forEach(function (item) {
120
+ box.appendChild(navLink(item));
121
+ if (item.children) {
122
+ var kids = document.createElement("div");
123
+ kids.className = "children";
124
+ kids.setAttribute("aria-label", item.t + " workflow pages");
125
+ item.children.forEach(function (c) { kids.appendChild(navLink(c, true)); });
126
+ box.appendChild(kids);
127
+ }
128
+ });
129
+ nav.appendChild(box);
130
+ });
131
+ }
132
+
133
+ /* ---------- pager ---------- */
134
+
135
+ function renderPager() {
136
+ var el = document.getElementById("pager");
137
+ if (!el) return;
138
+ var idx = ORDER.findIndex(function (i) { return i.h === page; });
139
+ if (idx < 0) return;
140
+ var prev = ORDER[idx - 1];
141
+ var next = ORDER[idx + 1];
142
+ el.innerHTML = "";
143
+ [["prev", prev, "← Previous"], ["next", next, "Next →"]].forEach(function (def) {
144
+ if (!def[1]) { el.appendChild(document.createElement("span")); return; }
145
+ var a = document.createElement("a");
146
+ a.className = def[0];
147
+ a.href = def[1].h;
148
+ a.innerHTML = '<span class="dir">' + def[2] + '</span><span class="t">' + def[1].t + "</span>";
149
+ el.appendChild(a);
150
+ });
151
+ }
152
+
153
+ /* ---------- headings: ids, anchors, toc ---------- */
154
+
155
+ function slug(text) {
156
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
157
+ }
158
+
159
+ function renderToc() {
160
+ var toc = document.getElementById("toc");
161
+ var heads = document.querySelectorAll("article h2, article h3");
162
+ var links = [];
163
+ heads.forEach(function (h) {
164
+ if (!h.id) h.id = slug(h.textContent);
165
+ var a = document.createElement("a");
166
+ a.href = "#" + h.id;
167
+ a.textContent = "#";
168
+ a.className = "anchor";
169
+ a.setAttribute("aria-label", "Link to " + h.textContent);
170
+ h.appendChild(a);
171
+ if (toc) {
172
+ var t = document.createElement("a");
173
+ t.href = "#" + h.id;
174
+ t.textContent = h.childNodes[0].textContent.trim();
175
+ if (h.tagName === "H3") t.className = "sub";
176
+ toc.appendChild(t);
177
+ links.push({ head: h, link: t });
178
+ }
179
+ });
180
+ if (!links.length) return;
181
+ /* getBoundingClientRect, not offsetTop: the entrance animation transforms
182
+ sections, which makes them offsetParents and breaks offsetTop math. */
183
+ function spy() {
184
+ var current = links[0];
185
+ links.forEach(function (l) {
186
+ if (l.head.getBoundingClientRect().top <= 120) current = l;
187
+ });
188
+ if (window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 4) {
189
+ current = links[links.length - 1];
190
+ }
191
+ links.forEach(function (l) { l.link.classList.toggle("active", l === current); });
192
+ }
193
+ window.addEventListener("scroll", spy, { passive: true });
194
+ window.addEventListener("resize", spy, { passive: true });
195
+ spy();
196
+ }
197
+
198
+ /* ---------- copy buttons ---------- */
199
+
200
+ function renderCopy() {
201
+ document.querySelectorAll("article pre").forEach(function (pre) {
202
+ var wrap = document.createElement("div");
203
+ wrap.className = "snippet";
204
+ pre.parentNode.insertBefore(wrap, pre);
205
+ wrap.appendChild(pre);
206
+ var btn = document.createElement("button");
207
+ btn.className = "copy-btn";
208
+ btn.type = "button";
209
+ btn.textContent = "copy";
210
+ btn.addEventListener("click", function () {
211
+ navigator.clipboard.writeText(pre.textContent.trim()).then(function () {
212
+ btn.textContent = "copied";
213
+ btn.classList.add("done");
214
+ setTimeout(function () {
215
+ btn.textContent = "copy";
216
+ btn.classList.remove("done");
217
+ }, 1400);
218
+ });
219
+ });
220
+ wrap.appendChild(btn);
221
+ });
222
+ }
223
+
224
+ /* ---------- mobile drawer ---------- */
225
+
226
+ document.addEventListener("click", function (e) {
227
+ var btn = e.target.closest("[data-menu]");
228
+ if (btn) {
229
+ var open = document.body.classList.toggle("nav-open");
230
+ btn.setAttribute("aria-expanded", open ? "true" : "false");
231
+ return;
232
+ }
233
+ if (document.body.classList.contains("nav-open") && e.target.closest("#sidebar a")) {
234
+ document.body.classList.remove("nav-open");
235
+ }
236
+ });
237
+
238
+ /* ---------- search palette ---------- */
239
+
240
+ var INDEX = null;
241
+ var INDEX_PROMISE = null;
242
+
243
+ function isSearchEntry(entry) {
244
+ return entry &&
245
+ typeof entry.t === "string" &&
246
+ typeof entry.h === "string" &&
247
+ typeof entry.where === "string";
248
+ }
249
+
250
+ function isSearchIndex(value) {
251
+ return Array.isArray(value) && value.every(isSearchEntry);
252
+ }
253
+
254
+ function buildIndex() {
255
+ if (INDEX) return Promise.resolve(INDEX);
256
+ if (INDEX_PROMISE) return INDEX_PROMISE;
257
+ var cached = getStorageItem("sessionStorage", INDEX_KEY);
258
+ if (cached) {
259
+ try {
260
+ var parsed = JSON.parse(cached);
261
+ if (isSearchIndex(parsed)) {
262
+ INDEX = parsed;
263
+ return Promise.resolve(INDEX);
264
+ }
265
+ } catch (_) {}
266
+ }
267
+ var parser = new DOMParser();
268
+ INDEX_PROMISE = Promise.all(ORDER.map(function (p) {
269
+ return fetch(p.h).then(function (r) { return r.text(); }).then(function (html) {
270
+ var doc = parser.parseFromString(html, "text/html");
271
+ var entries = [{ t: p.t, h: p.h, where: p.t }];
272
+ doc.querySelectorAll("article h2, article h3").forEach(function (head) {
273
+ var text = head.textContent.trim();
274
+ entries.push({ t: text, h: p.h + "#" + slug(text), where: p.t });
275
+ });
276
+ return entries;
277
+ }).catch(function () { return [{ t: p.t, h: p.h, where: p.t }]; });
278
+ })).then(function (lists) {
279
+ INDEX = lists.flat();
280
+ setStorageItem("sessionStorage", INDEX_KEY, JSON.stringify(INDEX));
281
+ return INDEX;
282
+ }).finally(function () {
283
+ INDEX_PROMISE = null;
284
+ });
285
+ return INDEX_PROMISE;
286
+ }
287
+
288
+ var palette, paletteInput, paletteResults, backdrop, selIdx = 0;
289
+
290
+ function openPalette() {
291
+ if (!palette) buildPalette();
292
+ backdrop.hidden = false;
293
+ palette.hidden = false;
294
+ paletteInput.value = "";
295
+ renderResults("");
296
+ paletteInput.focus();
297
+ buildIndex();
298
+ }
299
+
300
+ function closePalette() {
301
+ if (!palette) return;
302
+ backdrop.hidden = true;
303
+ palette.hidden = true;
304
+ }
305
+
306
+ function buildPalette() {
307
+ backdrop = document.createElement("div");
308
+ backdrop.className = "palette-backdrop";
309
+ backdrop.hidden = true;
310
+ backdrop.addEventListener("click", closePalette);
311
+
312
+ palette = document.createElement("div");
313
+ palette.className = "palette";
314
+ palette.hidden = true;
315
+ palette.setAttribute("role", "dialog");
316
+ palette.setAttribute("aria-label", "Search documentation");
317
+
318
+ paletteInput = document.createElement("input");
319
+ paletteInput.type = "search";
320
+ paletteInput.placeholder = "Search pages, sections, commands…";
321
+ paletteInput.addEventListener("input", function () { renderResults(paletteInput.value); });
322
+ paletteInput.addEventListener("keydown", function (e) {
323
+ var items = paletteResults.querySelectorAll("a");
324
+ if (e.key === "ArrowDown") { e.preventDefault(); selIdx = Math.min(selIdx + 1, items.length - 1); paint(items); }
325
+ else if (e.key === "ArrowUp") { e.preventDefault(); selIdx = Math.max(selIdx - 1, 0); paint(items); }
326
+ else if (e.key === "Enter" && items[selIdx]) { items[selIdx].click(); }
327
+ });
328
+
329
+ paletteResults = document.createElement("div");
330
+ paletteResults.className = "palette-results";
331
+
332
+ palette.appendChild(paletteInput);
333
+ palette.appendChild(paletteResults);
334
+ document.body.appendChild(backdrop);
335
+ document.body.appendChild(palette);
336
+ }
337
+
338
+ function paint(items) {
339
+ items.forEach(function (a, i) { a.classList.toggle("sel", i === selIdx); });
340
+ if (items[selIdx]) items[selIdx].scrollIntoView({ block: "nearest" });
341
+ }
342
+
343
+ function renderResults(q) {
344
+ var capturedQuery = q;
345
+ selIdx = 0;
346
+ buildIndex().then(function (index) {
347
+ if (paletteInput && paletteInput.value !== capturedQuery) return;
348
+ var query = capturedQuery.trim().toLowerCase();
349
+ var hits = !query
350
+ ? index.filter(function (e) { return !e.h.includes("#"); })
351
+ : index.filter(function (e) { return e.t.toLowerCase().includes(query); }).slice(0, 12);
352
+ paletteResults.innerHTML = "";
353
+ if (!hits.length) {
354
+ var empty = document.createElement("p");
355
+ empty.className = "empty";
356
+ empty.textContent = "No matches — try a command name or stage.";
357
+ paletteResults.appendChild(empty);
358
+ return;
359
+ }
360
+ hits.forEach(function (hit, i) {
361
+ var a = document.createElement("a");
362
+ a.href = hit.h;
363
+ if (i === 0) a.className = "sel";
364
+ var label = document.createElement("span");
365
+ label.textContent = hit.t;
366
+ var where = document.createElement("span");
367
+ where.className = "where";
368
+ where.textContent = hit.where;
369
+ a.appendChild(label);
370
+ a.appendChild(where);
371
+ paletteResults.appendChild(a);
372
+ });
373
+ });
374
+ }
375
+
376
+ document.addEventListener("click", function (e) {
377
+ if (e.target.closest("[data-search-open]")) openPalette();
378
+ });
379
+
380
+ document.addEventListener("keydown", function (e) {
381
+ if (e.key === "/" && !e.target.closest("input, textarea") && (!palette || palette.hidden)) {
382
+ e.preventDefault();
383
+ openPalette();
384
+ } else if (e.key === "Escape") {
385
+ closePalette();
386
+ document.body.classList.remove("nav-open");
387
+ }
388
+ });
389
+
390
+ /* ---------- boot ---------- */
391
+
392
+ applyTheme(preferredTheme());
393
+ renderSidebar();
394
+ renderPager();
395
+ renderToc();
396
+ renderCopy();
397
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artshelf",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Tiny CLI for accountable temporary artifact retention.",
5
5
  "type": "module",
6
6
  "author": "Calvin",