@shardworks/spider-apparatus 0.1.273 → 0.1.275

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/README.md CHANGED
@@ -410,7 +410,9 @@ Built-in block types contributed via the Spider's support kit:
410
410
  | `scheduled-time` | 30s | `{ resumeAt: ISO-8601 }` | Blocks until a wall-clock timestamp is reached. |
411
411
  | `book-updated` | 10s | `{ book, sinceId? }` | Blocks until a book gets a new entry. |
412
412
  | `patron-input` | 10s | `{ requestId }` | Blocks until an `InputRequestDoc` is answered or rejected. |
413
- | `animator-paused` | 10s | `{ sessionId? }` | Blocks until the Animator's rate-limit back-off machine reports `state === 'running'` OR `pausedUntil` has elapsed. Entered via `tryCollect` when a session terminates with `status: 'rate-limited'`. |
413
+ | `animator-paused` | 10s | `{ sessionId? }`[^1] | Blocks until the Animator's dispatch-status doc reports dispatchable (see `isDispatchable` helper). Entered via `tryCollect` when a session terminates with `status: 'rate-limited'`. |
414
+
415
+ [^1]: Legacy holds written before this commission may carry no condition payload at all (the predicate ignores the body and just reads dispatch-status); the column shape is `{ sessionId? }` for new holds.
414
416
 
415
417
  ### Engines
416
418
 
@@ -1 +1 @@
1
- {"version":3,"file":"spider-test-fixture.d.ts","sourceRoot":"","sources":["../src/spider-test-fixture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spider-test-fixture.d.ts","sourceRoot":"","sources":["../src/spider-test-fixture.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,7 @@ import { createStacksApparatus } from '@shardworks/stacks-apparatus';
18
18
  import { MemoryBackend } from '@shardworks/stacks-apparatus/testing';
19
19
  import { createClerk } from '@shardworks/clerk-apparatus';
20
20
  import { createFabricator } from '@shardworks/fabricator-apparatus';
21
+ import { freshStatusDoc } from '@shardworks/animator-apparatus';
21
22
  import { createSpider } from "./spider.js";
22
23
  // ── Test bootstrap ────────────────────────────────────────────────────
23
24
  /**
@@ -178,6 +179,14 @@ export function buildFixture(guildConfig = {}, initialSessionOutcome = { status:
178
179
  throw new Error(`Apparatus "${name}" not found`);
179
180
  return api;
180
181
  },
182
+ tryApparatus(name) {
183
+ try {
184
+ return this.apparatus(name);
185
+ }
186
+ catch {
187
+ return null;
188
+ }
189
+ },
181
190
  config(_pluginId) { return {}; },
182
191
  writeConfig() { },
183
192
  guildConfig() { return fakeGuildConfig; },
@@ -285,7 +294,7 @@ export function buildFixture(guildConfig = {}, initialSessionOutcome = { status:
285
294
  return { id: sessionId, status: 'cancelled', startedAt: '', endedAt: '', durationMs: 0, provider: 'mock', exitCode: 1 };
286
295
  },
287
296
  async getSessionCosts() { return new Map(); },
288
- async getStatus() { return {}; },
297
+ async getStatus() { return freshStatusDoc(); },
289
298
  };
290
299
  apparatusMap.set('animator', mockAnimatorApi);
291
300
  // Start clerk. Clerk consumes `linkKinds` kit entries, so pass the full
@@ -1 +1 @@
1
- {"version":3,"file":"spider-test-fixture.js","sourceRoot":"","sources":["../src/spider-test-fixture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spider-test-fixture.js","sourceRoot":"","sources":["../src/spider-test-fixture.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shardworks/spider-apparatus",
3
- "version": "0.1.273",
3
+ "version": "0.1.275",
4
4
  "license": "ISC",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,17 +22,17 @@
22
22
  "hono": "^4.7.11",
23
23
  "yaml": "^2.0.0",
24
24
  "zod": "4.3.6",
25
- "@shardworks/fabricator-apparatus": "0.1.273",
26
- "@shardworks/stacks-apparatus": "0.1.273",
27
- "@shardworks/tools-apparatus": "0.1.273",
28
- "@shardworks/clerk-apparatus": "0.1.273",
29
- "@shardworks/animator-apparatus": "0.1.273",
30
- "@shardworks/codexes-apparatus": "0.1.273",
31
- "@shardworks/loom-apparatus": "0.1.273"
25
+ "@shardworks/fabricator-apparatus": "0.1.275",
26
+ "@shardworks/stacks-apparatus": "0.1.275",
27
+ "@shardworks/tools-apparatus": "0.1.275",
28
+ "@shardworks/animator-apparatus": "0.1.275",
29
+ "@shardworks/clerk-apparatus": "0.1.275",
30
+ "@shardworks/codexes-apparatus": "0.1.275",
31
+ "@shardworks/loom-apparatus": "0.1.275"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "25.5.0",
35
- "@shardworks/nexus-core": "0.1.273"
35
+ "@shardworks/nexus-core": "0.1.275"
36
36
  },
37
37
  "files": [
38
38
  "dist",
@@ -312,3 +312,100 @@ describe('feedback.js tag filter toolbar', () => {
312
312
  );
313
313
  });
314
314
  });
315
+
316
+ // ── Deep-link URL state (?feedback=ID) ──────────────────────────────────
317
+
318
+ describe('feedback.js — deep-link URL state', () => {
319
+ it('exposes currentUrlParams + updateUrl helpers (D9 — Ratchet pattern)', () => {
320
+ assert.match(
321
+ feedbackJs,
322
+ /function currentUrlParams\(\)\s*\{[\s\S]*?new URLSearchParams\(window\.location\.search\)/,
323
+ 'currentUrlParams reads window.location.search live',
324
+ );
325
+ assert.match(
326
+ feedbackJs,
327
+ /function updateUrl\(changes\)\s*\{[\s\S]*?window\.history\.pushState/,
328
+ 'updateUrl pushes via history.pushState',
329
+ );
330
+ });
331
+
332
+ it('showDetail pushes ?feedback=ID using the request id (stable across reorderings)', () => {
333
+ const block = feedbackJs.match(
334
+ /function showDetail\(index(?:, opts)?\)[\s\S]*?(?=\n \/\*\*|\n function )/,
335
+ );
336
+ assert.ok(block, 'should find showDetail body');
337
+ assert.match(
338
+ block[0],
339
+ /updateUrl\(\{\s*feedback:\s*currentRequest\.id\s*\}\)/,
340
+ 'showDetail pushes ?feedback=<currentRequest.id> — keyed on the id, not the index',
341
+ );
342
+ assert.match(block[0], /skipUrlPush/, 'showDetail accepts a skipUrlPush opt');
343
+ });
344
+
345
+ it('navigateToList clears ?feedback via updateUrl({feedback: null}) — never pops history (D11)', () => {
346
+ const block = feedbackJs.match(
347
+ /function navigateToList\((?:opts)?\)[\s\S]*?fetchList\(\);[\s\S]*?startPoll\(\);\s*\}/,
348
+ );
349
+ assert.ok(block, 'should find navigateToList body');
350
+ assert.match(
351
+ block[0],
352
+ /updateUrl\(\{\s*feedback:\s*null\s*\}\)/,
353
+ 'navigateToList should push a clean URL via updateUrl({feedback: null})',
354
+ );
355
+ assert.ok(
356
+ !/window\.history\.back\s*\(/.test(block[0]),
357
+ 'navigateToList should never invoke history.back',
358
+ );
359
+ });
360
+
361
+ it('a popstate listener routes browser navigation back through the page', () => {
362
+ assert.match(
363
+ feedbackJs,
364
+ /window\.addEventListener\(\s*['"]popstate['"]/,
365
+ 'feedback.js registers a popstate listener',
366
+ );
367
+ const block = feedbackJs.match(
368
+ /addEventListener\(\s*['"]popstate['"][\s\S]*?\}\)/,
369
+ );
370
+ assert.ok(block, 'should find popstate handler body');
371
+ assert.match(
372
+ block[0],
373
+ /currentUrlParams\(\)\.get\(['"]feedback['"]\)/,
374
+ 'popstate handler reads ?feedback from the new URL',
375
+ );
376
+ assert.match(
377
+ block[0],
378
+ /skipUrlPush:\s*true/,
379
+ 'popstate-driven path passes skipUrlPush to avoid double-push',
380
+ );
381
+ });
382
+
383
+ it('init reads ?feedback=ID and resolves it via showDetailById', () => {
384
+ assert.match(
385
+ feedbackJs,
386
+ /var initialFeedbackId\s*=\s*currentUrlParams\(\)\.get\(['"]feedback['"]\)/,
387
+ 'init reads ?feedback from the URL',
388
+ );
389
+ assert.match(
390
+ feedbackJs,
391
+ /showDetailById\(\s*initialFeedbackId\s*,\s*\{\s*skipUrlPush:\s*true\s*\}\)/,
392
+ 'init opens the detail via showDetailById with skipUrlPush=true',
393
+ );
394
+ });
395
+
396
+ it('renderFeedbackNotFound preserves the URL param (D16)', () => {
397
+ const block = feedbackJs.match(
398
+ /function renderFeedbackNotFound\([\s\S]*?(?=\n function )/,
399
+ );
400
+ assert.ok(block, 'should find renderFeedbackNotFound body');
401
+ assert.ok(
402
+ !/updateUrl/.test(block[0]),
403
+ 'renderFeedbackNotFound must not rewrite the URL',
404
+ );
405
+ assert.match(
406
+ block[0],
407
+ /No feedback request with id/,
408
+ 'renderFeedbackNotFound surfaces a "not found" message',
409
+ );
410
+ });
411
+ });
@@ -34,6 +34,38 @@
34
34
  var actionBar = document.getElementById('action-bar');
35
35
  var successToast = document.getElementById('success-toast');
36
36
 
37
+ // ── URL handling ───────────────────────────────────────────────────────
38
+
39
+ /**
40
+ * Read the current querystring as a `URLSearchParams`. Live snapshot.
41
+ */
42
+ function currentUrlParams() {
43
+ return new URLSearchParams(window.location.search);
44
+ }
45
+
46
+ /**
47
+ * Apply the given key/value changes to the current querystring and
48
+ * `pushState` the result. Null/undefined/empty value deletes the key.
49
+ * Mirrors Ratchet's `updateUrl` (D9). The feedback param shape is
50
+ * `?feedback=ID` (D10) — keyed on the request id (req.id), which is
51
+ * stable across the list reorderings the 12 s polling loop can
52
+ * trigger. The legacy index-based showDetail path now translates
53
+ * index → id at the click site.
54
+ */
55
+ function updateUrl(changes) {
56
+ var params = currentUrlParams();
57
+ var keys = Object.keys(changes);
58
+ for (var i = 0; i < keys.length; i++) {
59
+ var key = keys[i];
60
+ var value = changes[key];
61
+ if (value === null || value === undefined || value === '') params.delete(key);
62
+ else params.set(key, value);
63
+ }
64
+ var qs = params.toString();
65
+ var next = window.location.pathname + (qs ? '?' + qs : '');
66
+ window.history.pushState({}, '', next);
67
+ }
68
+
37
69
  // ── Helpers ────────────────────────────────────────────────────────────
38
70
 
39
71
  function esc(s) {
@@ -121,10 +153,36 @@
121
153
 
122
154
  // ── Detail view ────────────────────────────────────────────────────────
123
155
 
124
- function showDetail(index) {
156
+ /**
157
+ * Render a "not found" empty state inside the detail view for a
158
+ * deep-linked id that does not resolve. Per D16 the URL param is
159
+ * preserved.
160
+ */
161
+ function renderFeedbackNotFound(id) {
162
+ currentRequest = null;
163
+ listView.style.display = 'none';
164
+ detailView.style.display = '';
165
+ detailBanner.innerHTML = '';
166
+ detailMessage.innerHTML =
167
+ '<div class="empty-state" style="padding:1.5rem">' +
168
+ 'No feedback request with id <code>' + esc(id) + '</code> exists. ' +
169
+ 'It may have been completed, rejected, or the id may be mistyped.</div>';
170
+ questionsContainer.innerHTML = '';
171
+ actionBar.innerHTML = '';
172
+ var oldToolbar = document.getElementById('tag-filter-toolbar');
173
+ if (oldToolbar) oldToolbar.remove();
174
+ }
175
+
176
+ function showDetail(index, opts) {
177
+ var skipUrlPush = !!(opts && opts.skipUrlPush);
125
178
  currentRequest = requests[index];
126
179
  if (!currentRequest) return;
127
180
 
181
+ // Centralised URL push (D12) — keyed on the request id so the URL
182
+ // survives list reorderings between the 12 s polls. Translation
183
+ // index → id happens here, not at the click site.
184
+ if (!skipUrlPush) updateUrl({ feedback: currentRequest.id });
185
+
128
186
  // Initialize local answers from server state
129
187
  localAnswers = {};
130
188
  var keys = Object.keys(currentRequest.answers);
@@ -151,6 +209,44 @@
151
209
  renderDetail();
152
210
  }
153
211
 
212
+ /**
213
+ * Open the detail view for a request id. Looks up the local list
214
+ * first; falls back to /api/input/request-show. On miss, renders the
215
+ * not-found state without rewriting the URL (D16).
216
+ */
217
+ function showDetailById(id, opts) {
218
+ var skipUrlPush = !!(opts && opts.skipUrlPush);
219
+ var index = -1;
220
+ for (var i = 0; i < requests.length; i++) {
221
+ if (requests[i] && requests[i].id === id) { index = i; break; }
222
+ }
223
+ if (index >= 0) {
224
+ showDetail(index, { skipUrlPush: skipUrlPush });
225
+ return;
226
+ }
227
+ fetch(API.show + '?id=' + encodeURIComponent(id))
228
+ .then(function (r) {
229
+ if (!r.ok) throw new Error('HTTP ' + r.status);
230
+ return r.json();
231
+ })
232
+ .then(function (req) {
233
+ if (!req || !req.id) {
234
+ if (!skipUrlPush) updateUrl({ feedback: id });
235
+ renderFeedbackNotFound(id);
236
+ return;
237
+ }
238
+ // Splice the deep-linked request into `requests` so the
239
+ // existing index-based UI path can resolve it. Append rather
240
+ // than replace so the operator's filtered list stays intact.
241
+ requests.push(req);
242
+ showDetail(requests.length - 1, { skipUrlPush: skipUrlPush });
243
+ })
244
+ .catch(function () {
245
+ if (!skipUrlPush) updateUrl({ feedback: id });
246
+ renderFeedbackNotFound(id);
247
+ });
248
+ }
249
+
154
250
  function renderDetail() {
155
251
  var req = currentRequest;
156
252
  var isPending = req.status === 'pending';
@@ -492,7 +588,8 @@
492
588
 
493
589
  // ── Navigation ─────────────────────────────────────────────────────────
494
590
 
495
- function navigateToList() {
591
+ function navigateToList(opts) {
592
+ var skipUrlPush = !!(opts && opts.skipUrlPush);
496
593
  currentRequest = null;
497
594
  localAnswers = {};
498
595
  // Clear debounce timers
@@ -505,6 +602,10 @@
505
602
 
506
603
  detailView.style.display = 'none';
507
604
  listView.style.display = '';
605
+ // D11: push a clean URL so deep-link entries survive the Back
606
+ // button. Never pop history — the operator may have arrived
607
+ // directly at ?feedback=ID.
608
+ if (!skipUrlPush) updateUrl({ feedback: null });
508
609
  fetchList();
509
610
  startPoll();
510
611
  }
@@ -750,9 +851,34 @@
750
851
  }, 800);
751
852
  }
752
853
 
854
+ // ── Browser navigation (popstate) ──────────────────────────────────────
855
+
856
+ // Read ?feedback=ID from the new URL and either re-open the matching
857
+ // detail (skipUrlPush=true) or return to the list. Pairs with the
858
+ // central push inside showDetail (D11/D12).
859
+ window.addEventListener('popstate', function () {
860
+ var feedbackId = currentUrlParams().get('feedback');
861
+ if (feedbackId) {
862
+ showDetailById(feedbackId, { skipUrlPush: true });
863
+ } else {
864
+ navigateToList({ skipUrlPush: true });
865
+ }
866
+ });
867
+
753
868
  // ── Init ───────────────────────────────────────────────────────────────
754
869
 
755
870
  fetchList();
756
871
  startPoll();
757
872
 
873
+ // Deep-link: ?feedback=ID — open that request's detail after the
874
+ // first list fetch lands. The list-fetch is async so we wait for it
875
+ // by polling `requests.length` once via a microtask; on a miss, the
876
+ // /api/input/request-show fallback inside showDetailById handles it.
877
+ // A missing/deleted/mistyped id renders a "not found" state without
878
+ // rewriting the URL (D16).
879
+ var initialFeedbackId = currentUrlParams().get('feedback');
880
+ if (initialFeedbackId) {
881
+ showDetailById(initialFeedbackId, { skipUrlPush: true });
882
+ }
883
+
758
884
  })();
@@ -428,7 +428,7 @@ describe('spider.js rig list polling', () => {
428
428
 
429
429
  it('starts current rig polling in showRigDetail', () => {
430
430
  const showRigBlock = spiderJs.match(
431
- /function showRigDetail\(rig\)[\s\S]*?startCurrentRigPoll\(\)/,
431
+ /function showRigDetail\(rig(?:, opts)?\)[\s\S]*?startCurrentRigPoll\(\)/,
432
432
  );
433
433
  assert.ok(
434
434
  showRigBlock,
@@ -438,7 +438,7 @@ describe('spider.js rig list polling', () => {
438
438
 
439
439
  it('stops current rig poll when navigating back to list', () => {
440
440
  const backBlock = spiderJs.match(
441
- /function backToList\(\)[\s\S]*?stopCurrentRigPoll\(\)/,
441
+ /function backToList\((?:opts)?\)[\s\S]*?stopCurrentRigPoll\(\)/,
442
442
  );
443
443
  assert.ok(
444
444
  backBlock,
@@ -448,7 +448,7 @@ describe('spider.js rig list polling', () => {
448
448
 
449
449
  it('stops current rig poll when selecting a new rig', () => {
450
450
  const showRigBlock = spiderJs.match(
451
- /function showRigDetail\(rig\)[\s\S]*?stopCurrentRigPoll\(\)/,
451
+ /function showRigDetail\(rig(?:, opts)?\)[\s\S]*?stopCurrentRigPoll\(\)/,
452
452
  );
453
453
  assert.ok(
454
454
  showRigBlock,
@@ -876,7 +876,7 @@ describe('spider.js session transcript polling', () => {
876
876
  // through that helper so the textarea + spinner state is cleared
877
877
  // alongside the poll.
878
878
  const backBlock = spiderJs.match(
879
- /function backToList\(\)[\s\S]*?(?=\n function )/,
879
+ /function backToList\((?:opts)?\)[\s\S]*?(?=\n function )/,
880
880
  );
881
881
  assert.ok(backBlock, 'should find backToList');
882
882
  assert.match(
@@ -885,7 +885,7 @@ describe('spider.js session transcript polling', () => {
885
885
  'backToList should tear down transcript state via resetSessionLog',
886
886
  );
887
887
  const showRigBlock = spiderJs.match(
888
- /function showRigDetail\(rig\)[\s\S]*?(?=\n function )/,
888
+ /function showRigDetail\(rig(?:, opts)?\)[\s\S]*?(?=\n function )/,
889
889
  );
890
890
  assert.ok(showRigBlock, 'should find showRigDetail');
891
891
  assert.match(
@@ -1001,7 +1001,7 @@ describe('spider.js elapsed ticker', () => {
1001
1001
 
1002
1002
  it('navigating away stops the elapsed ticker', () => {
1003
1003
  const backBlock = spiderJs.match(
1004
- /function backToList\(\)[\s\S]*?(?=\n function )/,
1004
+ /function backToList\((?:opts)?\)[\s\S]*?(?=\n function )/,
1005
1005
  );
1006
1006
  assert.ok(backBlock, 'should find backToList');
1007
1007
  assert.match(
@@ -1010,7 +1010,7 @@ describe('spider.js elapsed ticker', () => {
1010
1010
  'backToList should stop the elapsed ticker',
1011
1011
  );
1012
1012
  const showRigBlock = spiderJs.match(
1013
- /function showRigDetail\(rig\)[\s\S]*?(?=\n function )/,
1013
+ /function showRigDetail\(rig(?:, opts)?\)[\s\S]*?(?=\n function )/,
1014
1014
  );
1015
1015
  assert.ok(showRigBlock, 'should find showRigDetail');
1016
1016
  assert.match(
@@ -1491,7 +1491,7 @@ describe('spider.js rig-meta stable-id skeleton', () => {
1491
1491
 
1492
1492
  it('showRigDetail wires up skeleton + update + rig-elapsed ticker', () => {
1493
1493
  const showRigBlock = spiderJs.match(
1494
- /function showRigDetail\(rig\)[\s\S]*?(?=\n function )/,
1494
+ /function showRigDetail\(rig(?:, opts)?\)[\s\S]*?(?=\n function )/,
1495
1495
  );
1496
1496
  assert.ok(showRigBlock, 'should find showRigDetail');
1497
1497
  assert.match(
@@ -1545,7 +1545,7 @@ describe('spider.js rig-meta stable-id skeleton', () => {
1545
1545
  'should define stopRigElapsedTimer',
1546
1546
  );
1547
1547
  const backBlock = spiderJs.match(
1548
- /function backToList\(\)[\s\S]*?(?=\n function )/,
1548
+ /function backToList\((?:opts)?\)[\s\S]*?(?=\n function )/,
1549
1549
  );
1550
1550
  assert.ok(backBlock, 'should find backToList');
1551
1551
  assert.match(
@@ -1616,7 +1616,7 @@ describe('spider.js session-log lifecycle', () => {
1616
1616
 
1617
1617
  it('showRigDetail calls resetSessionLog before any render or poll start', () => {
1618
1618
  const block = spiderJs.match(
1619
- /function showRigDetail\(rig\)[\s\S]*?(?=\n function )/,
1619
+ /function showRigDetail\(rig(?:, opts)?\)[\s\S]*?(?=\n function )/,
1620
1620
  );
1621
1621
  assert.ok(block, 'should find showRigDetail body');
1622
1622
  assert.match(
@@ -1635,7 +1635,7 @@ describe('spider.js session-log lifecycle', () => {
1635
1635
 
1636
1636
  it('backToList calls resetSessionLog', () => {
1637
1637
  const block = spiderJs.match(
1638
- /function backToList\(\)[\s\S]*?(?=\n \/\/|\n function )/,
1638
+ /function backToList\((?:opts)?\)[\s\S]*?(?=\n \/\/|\n function )/,
1639
1639
  );
1640
1640
  assert.ok(block, 'should find backToList body');
1641
1641
  assert.match(
@@ -1913,3 +1913,123 @@ describe('spider.js engine-detail attempt-history details', () => {
1913
1913
  );
1914
1914
  });
1915
1915
  });
1916
+
1917
+ // ── Deep-link URL state (?rig=ID) ──────────────────────────────────────
1918
+
1919
+ describe('spider.js — deep-link URL state', () => {
1920
+ it('exposes currentUrlParams + updateUrl helpers (D9 — Ratchet pattern)', () => {
1921
+ assert.match(
1922
+ spiderJs,
1923
+ /function currentUrlParams\(\)\s*\{[\s\S]*?new URLSearchParams\(window\.location\.search\)/,
1924
+ 'currentUrlParams reads window.location.search live',
1925
+ );
1926
+ assert.match(
1927
+ spiderJs,
1928
+ /function updateUrl\(changes\)\s*\{[\s\S]*?window\.history\.pushState/,
1929
+ 'updateUrl pushes via history.pushState',
1930
+ );
1931
+ assert.match(
1932
+ spiderJs,
1933
+ /function updateUrl\(changes\)[\s\S]*?params\.delete\(key\)/,
1934
+ 'updateUrl deletes the key when value is null/undefined/empty',
1935
+ );
1936
+ });
1937
+
1938
+ it('showRigDetail pushes ?rig=ID via the central updateUrl call (D12)', () => {
1939
+ const block = spiderJs.match(
1940
+ /function showRigDetail\(rig(?:, opts)?\)[\s\S]*?(?=\n function )/,
1941
+ );
1942
+ assert.ok(block, 'should find showRigDetail body');
1943
+ assert.match(
1944
+ block[0],
1945
+ /updateUrl\(\{\s*rig:\s*rig\.id\s*\}\)/,
1946
+ 'showRigDetail should push ?rig=<rig.id> when not skipUrlPush',
1947
+ );
1948
+ assert.match(
1949
+ block[0],
1950
+ /skipUrlPush/,
1951
+ 'showRigDetail should accept a skipUrlPush opt',
1952
+ );
1953
+ });
1954
+
1955
+ it('backToList clears ?rig via updateUrl({rig: null}) — never history.back (D11)', () => {
1956
+ const block = spiderJs.match(
1957
+ /function backToList\((?:opts)?\)[\s\S]*?(?=\n function )/,
1958
+ );
1959
+ assert.ok(block, 'should find backToList body');
1960
+ assert.match(
1961
+ block[0],
1962
+ /updateUrl\(\{\s*rig:\s*null\s*\}\)/,
1963
+ 'backToList should push a clean URL via updateUrl({rig: null})',
1964
+ );
1965
+ assert.ok(
1966
+ !/history\.back\(/.test(block[0]),
1967
+ 'backToList should never call history.back()',
1968
+ );
1969
+ });
1970
+
1971
+ it('a popstate listener routes browser navigation back through the page', () => {
1972
+ assert.match(
1973
+ spiderJs,
1974
+ /window\.addEventListener\(\s*['"]popstate['"]/,
1975
+ 'spider.js should register a popstate listener',
1976
+ );
1977
+ const block = spiderJs.match(
1978
+ /addEventListener\(\s*['"]popstate['"][\s\S]*?\}\)/,
1979
+ );
1980
+ assert.ok(block, 'should find popstate handler body');
1981
+ assert.match(
1982
+ block[0],
1983
+ /currentUrlParams\(\)\.get\(['"]rig['"]\)/,
1984
+ 'popstate handler reads ?rig from the new URL',
1985
+ );
1986
+ assert.match(
1987
+ block[0],
1988
+ /skipUrlPush:\s*true/,
1989
+ 'popstate-driven path passes skipUrlPush to avoid double-push',
1990
+ );
1991
+ });
1992
+
1993
+ it('init reads ?rig=ID and opens the matching detail after the rig list lands', () => {
1994
+ assert.match(
1995
+ spiderJs,
1996
+ /currentUrlParams\(\)\.get\(['"]rig['"]\)/,
1997
+ 'init reads ?rig from the URL',
1998
+ );
1999
+ assert.match(
2000
+ spiderJs,
2001
+ /showRigDetailById\(\s*initialRigId\s*,\s*\{\s*skipUrlPush:\s*true\s*\}\s*\)/,
2002
+ 'init opens the detail via showRigDetailById with skipUrlPush=true',
2003
+ );
2004
+ });
2005
+
2006
+ it('not-found state preserves the URL param (D16)', () => {
2007
+ const block = spiderJs.match(
2008
+ /function renderRigDetailNotFound\([\s\S]*?(?=\n function )/,
2009
+ );
2010
+ assert.ok(block, 'should find renderRigDetailNotFound body');
2011
+ // The function itself must not call updateUrl — the URL is left
2012
+ // alone so the operator can recover by editing the address bar.
2013
+ assert.ok(
2014
+ !/updateUrl/.test(block[0]),
2015
+ 'renderRigDetailNotFound must not rewrite the URL',
2016
+ );
2017
+ assert.match(
2018
+ block[0],
2019
+ /No rig with id/,
2020
+ 'renderRigDetailNotFound surfaces a "not found" message',
2021
+ );
2022
+ });
2023
+
2024
+ it('does not push a tab=… or engine=… URL param (D13/D14 explicit out-of-scope)', () => {
2025
+ assert.ok(
2026
+ !/updateUrl\(\{\s*tab:/.test(spiderJs),
2027
+ 'tab state must remain client-only (D14)',
2028
+ );
2029
+ assert.ok(
2030
+ !/updateUrl\(\{\s*engine:/.test(spiderJs),
2031
+ 'engine selection must remain client state (D13)',
2032
+ );
2033
+ });
2034
+ });
2035
+
@@ -76,6 +76,36 @@
76
76
  return '<span class="' + fullCls + '">' + esc(status) + '</span>';
77
77
  }
78
78
 
79
+ // ── URL handling ───────────────────────────────────────────────────────
80
+
81
+ /**
82
+ * Read the current querystring as a `URLSearchParams`. Live snapshot —
83
+ * read at call time, never cached, so reasoning stays local.
84
+ */
85
+ function currentUrlParams() {
86
+ return new URLSearchParams(window.location.search);
87
+ }
88
+
89
+ /**
90
+ * Apply the given key/value changes to the current querystring and
91
+ * `pushState` the result. Null/undefined/empty value deletes the key.
92
+ * Mirrors Ratchet's `updateUrl` (D9). Tab state and engine selection
93
+ * are deliberately NOT round-tripped through this helper (D13/D14).
94
+ */
95
+ function updateUrl(changes) {
96
+ var params = currentUrlParams();
97
+ var keys = Object.keys(changes);
98
+ for (var i = 0; i < keys.length; i++) {
99
+ var key = keys[i];
100
+ var value = changes[key];
101
+ if (value === null || value === undefined || value === '') params.delete(key);
102
+ else params.set(key, value);
103
+ }
104
+ var qs = params.toString();
105
+ var next = window.location.pathname + (qs ? '?' + qs : '');
106
+ window.history.pushState({}, '', next);
107
+ }
108
+
79
109
  // ── Utility ────────────────────────────────────────────────────────────
80
110
 
81
111
  function esc(s) {
@@ -504,7 +534,8 @@
504
534
 
505
535
  // ── Fetch rigs ─────────────────────────────────────────────────────────
506
536
 
507
- function fetchRigs(statusFilter) {
537
+ function fetchRigs(statusFilter, opts) {
538
+ var onLoaded = opts && typeof opts.onLoaded === 'function' ? opts.onLoaded : null;
508
539
  currentStatusFilter = statusFilter || '';
509
540
  var rigUrl = '/api/rig/list?limit=100';
510
541
  if (statusFilter) {
@@ -515,10 +546,12 @@
515
546
  rigs = Array.isArray(result) ? result : [];
516
547
  renderRigList();
517
548
  startRigListPollIfNeeded();
549
+ if (onLoaded) onLoaded();
518
550
  }).catch(function (err) {
519
551
  console.error('Failed to fetch rigs:', err);
520
552
  rigs = [];
521
553
  renderRigList();
554
+ if (onLoaded) onLoaded();
522
555
  });
523
556
  }
524
557
 
@@ -831,10 +864,82 @@
831
864
 
832
865
  // ── Show rig detail ────────────────────────────────────────────────────
833
866
 
834
- function showRigDetail(rig) {
867
+ /**
868
+ * Render a "not found" empty state inside the rig detail view for a
869
+ * deep-linked id that does not resolve. Per D16 the URL param is left
870
+ * untouched so the operator can recover (correct the id, hit Back).
871
+ * Tab state and engine selection are not part of the URL contract so
872
+ * we don't need to clear them here.
873
+ */
874
+ function renderRigDetailNotFound(id) {
875
+ document.getElementById('rig-list-view').style.display = 'none';
876
+ document.getElementById('rig-detail-view').style.display = '';
877
+ document.getElementById('detail-title').textContent = 'Rig not found';
878
+
879
+ // Hide the meta + writ + pipeline + engine surfaces — they reference
880
+ // nodes that updateRigMeta would otherwise populate.
881
+ var hideIds = ['detail-meta', 'writ-details-card', 'engine-detail', 'session-log-section'];
882
+ for (var i = 0; i < hideIds.length; i++) {
883
+ var el = document.getElementById(hideIds[i]);
884
+ if (el) el.style.display = 'none';
885
+ }
886
+
887
+ var pipeline = document.getElementById('pipeline');
888
+ if (pipeline) {
889
+ pipeline.innerHTML =
890
+ '<div class="empty-state" style="padding:1.5rem">' +
891
+ 'No rig with id <code>' + esc(id) + '</code> exists. ' +
892
+ 'It may have been deleted, or the id may be mistyped.</div>';
893
+ }
894
+ }
895
+
896
+ /**
897
+ * Open the detail view for a rig id. Used by the deep-link init path
898
+ * and the popstate handler. Looks the rig up in the local list first
899
+ * (so the renderer still has a complete record); falls back to a
900
+ * direct /api/rig/show fetch if the list is empty or the id is
901
+ * absent (e.g. the operator deep-linked to a rig outside the
902
+ * currently filtered list). On miss, renders the not-found state
903
+ * without rewriting the URL (D16).
904
+ */
905
+ function showRigDetailById(id, opts) {
906
+ var skipUrlPush = !!(opts && opts.skipUrlPush);
907
+ var live = rigs.find(function (r) { return r.id === id; });
908
+ if (live) {
909
+ showRigDetail(live, { skipUrlPush: skipUrlPush });
910
+ return;
911
+ }
912
+ fetch('/api/rig/show?id=' + encodeURIComponent(id))
913
+ .then(function (r) {
914
+ if (!r.ok) throw new Error('HTTP ' + r.status);
915
+ return r.json();
916
+ })
917
+ .then(function (rig) {
918
+ if (rig && rig.id) {
919
+ showRigDetail(rig, { skipUrlPush: skipUrlPush });
920
+ } else {
921
+ if (!skipUrlPush) updateUrl({ rig: id });
922
+ renderRigDetailNotFound(id);
923
+ }
924
+ })
925
+ .catch(function () {
926
+ if (!skipUrlPush) updateUrl({ rig: id });
927
+ renderRigDetailNotFound(id);
928
+ });
929
+ }
930
+
931
+ function showRigDetail(rig, opts) {
932
+ var skipUrlPush = !!(opts && opts.skipUrlPush);
835
933
  currentRig = rig;
836
934
  selectedEngineId = null;
837
935
 
936
+ // Centralised URL push (D12) — every entry path into showRigDetail
937
+ // (writ-title anchor, rig-id anchor, future entry points, deep-link
938
+ // init) emits ?rig=ID for free. The popstate-driven path passes
939
+ // skipUrlPush=true to avoid double-pushing the URL the browser
940
+ // already updated.
941
+ if (!skipUrlPush) updateUrl({ rig: rig.id });
942
+
838
943
  // Reset the session-log surface BEFORE any render (T7): hides the
839
944
  // section, clears the textarea, and nulls transcript state.
840
945
  resetSessionLog();
@@ -1494,7 +1599,8 @@
1494
1599
 
1495
1600
  // ── Back to list ───────────────────────────────────────────────────────
1496
1601
 
1497
- function backToList() {
1602
+ function backToList(opts) {
1603
+ var skipUrlPush = !!(opts && opts.skipUrlPush);
1498
1604
  // T7: explicit session-log reset on back-to-list. resetSessionLog
1499
1605
  // itself calls stopSessionTranscriptPoll and clears the textarea
1500
1606
  // so the list → detail → list → detail cycle never leaks a stale
@@ -1507,6 +1613,12 @@
1507
1613
  selectedEngineId = null;
1508
1614
  document.getElementById('rig-detail-view').style.display = 'none';
1509
1615
  document.getElementById('rig-list-view').style.display = '';
1616
+
1617
+ // D11: push a clean URL so the operator's Forward button keeps
1618
+ // doing what they expect. We deliberately push instead of popping
1619
+ // history — the operator may have arrived directly at ?rig=ID with
1620
+ // no prior list-view entry to pop back to.
1621
+ if (!skipUrlPush) updateUrl({ rig: null });
1510
1622
  }
1511
1623
 
1512
1624
  // ── Config tab ─────────────────────────────────────────────────────────
@@ -1836,8 +1948,32 @@
1836
1948
  backBtn.addEventListener('click', backToList);
1837
1949
  }
1838
1950
 
1839
- // Initial load
1840
- fetchRigs('');
1951
+ // Browser navigation (Back / Forward) — read ?rig=ID from the new
1952
+ // URL and either open the matching detail (skipUrlPush=true so we
1953
+ // don't push the URL the browser already updated) or return to the
1954
+ // list. Pairs with the central push inside showRigDetail (D11/D12).
1955
+ window.addEventListener('popstate', function () {
1956
+ var rigId = currentUrlParams().get('rig');
1957
+ if (rigId) {
1958
+ showRigDetailById(rigId, { skipUrlPush: true });
1959
+ } else {
1960
+ backToList({ skipUrlPush: true });
1961
+ }
1962
+ });
1963
+
1964
+ // Initial load. Deep-link: ?rig=ID. The init path waits for the
1965
+ // first rig list to land (so showRigDetailById can find the live
1966
+ // rig in `rigs`) before opening the detail. A missing/deleted id
1967
+ // falls through to renderRigDetailNotFound (D16) — the URL is
1968
+ // preserved.
1969
+ var initialRigId = currentUrlParams().get('rig');
1970
+ fetchRigs('', {
1971
+ onLoaded: function () {
1972
+ if (initialRigId) {
1973
+ showRigDetailById(initialRigId, { skipUrlPush: true });
1974
+ }
1975
+ },
1976
+ });
1841
1977
 
1842
1978
  // Start the independent Animator pause-banner poll. Runs on every
1843
1979
  // tab (rigs/config) regardless of rig activity (D23 — the banner