@design.estate/dees-catalog 11.2.2 → 12.1.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 (28) hide show
  1. package/dist_bundle/bundle.js +1898 -1292
  2. package/dist_bundle/bundle.js.map +1 -1
  3. package/dist_ts_web/00_commitinfo_data.js +1 -1
  4. package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.d.ts +62 -0
  5. package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.d.ts +1 -0
  6. package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.js +38 -0
  7. package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.js +455 -0
  8. package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/index.d.ts +1 -0
  9. package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/index.js +2 -0
  10. package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.d.ts +39 -10
  11. package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.demo.js +81 -27
  12. package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.js +327 -115
  13. package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.d.ts +22 -1
  14. package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.js +42 -3
  15. package/dist_ts_web/elements/00group-harness/index.d.ts +1 -0
  16. package/dist_ts_web/elements/00group-harness/index.js +2 -1
  17. package/dist_ts_web/elements/00group-harness/interfaces.d.ts +35 -16
  18. package/package.json +1 -1
  19. package/readme.md +57 -23
  20. package/ts_web/00_commitinfo_data.ts +1 -1
  21. package/ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.ts +46 -0
  22. package/ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.ts +420 -0
  23. package/ts_web/elements/00group-harness/dees-harness-conversation-picker/index.ts +1 -0
  24. package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.demo.ts +94 -36
  25. package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts +357 -120
  26. package/ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.ts +42 -2
  27. package/ts_web/elements/00group-harness/index.ts +1 -0
  28. package/ts_web/elements/00group-harness/interfaces.ts +41 -16
@@ -54,6 +54,11 @@ export declare class DeesTerminalView extends DeesElement {
54
54
  private pendingWriteBytes;
55
55
  private pendingWritesDropped;
56
56
  private setupPromise;
57
+ /**
58
+ * Set only by an explicit `focus()` that arrived before the terminal existed. Nothing else sets
59
+ * it, so a re-render, a write, or a resize can never move the caret into this element.
60
+ */
61
+ private focusWhenReady;
57
62
  private readyPending;
58
63
  private readyResolve;
59
64
  private readyReject;
@@ -72,7 +77,23 @@ export declare class DeesTerminalView extends DeesElement {
72
77
  write(dataArg: string | Uint8Array): void;
73
78
  /** Reset the screen and scrollback, e.g. before a full replay. */
74
79
  clear(): void;
75
- focus(): void;
80
+ /**
81
+ * Moves the caret into the terminal's input surface, so the next keystroke goes to the pty
82
+ * rather than to whatever the page focused last. This is the call a host makes when the user
83
+ * selects a terminal in a list.
84
+ *
85
+ * The terminal is created asynchronously — the xterm modules are loaded on first connection —
86
+ * so a call that arrives before it exists is remembered and applied once it is ready, exactly
87
+ * once. The same applies to an element that is focused while detached and then reattached: the
88
+ * pending request is dropped on disconnect, because by then the user's intent has expired, and
89
+ * a fresh `focus()` after the move is what a host should issue.
90
+ *
91
+ * Only this method arms that behaviour; re-renders, buffered output and background updates
92
+ * never steal focus.
93
+ */
94
+ focus(optionsArg?: FocusOptions): void;
95
+ /** True while an explicit `focus()` is waiting for the terminal to come up. */
96
+ get focusPending(): boolean;
76
97
  /** Current grid size, or undefined while no terminal is live. */
77
98
  get currentSize(): ITerminalResizeDetail | undefined;
78
99
  private createReadyPromise;
@@ -109,6 +109,11 @@ let DeesTerminalView = (() => {
109
109
  pendingWriteBytes = 0;
110
110
  pendingWritesDropped = false;
111
111
  setupPromise;
112
+ /**
113
+ * Set only by an explicit `focus()` that arrived before the terminal existed. Nothing else sets
114
+ * it, so a re-render, a write, or a resize can never move the caret into this element.
115
+ */
116
+ focusWhenReady = false;
112
117
  readyPending = true;
113
118
  readyResolve = () => undefined;
114
119
  readyReject = () => undefined;
@@ -311,8 +316,34 @@ let DeesTerminalView = (() => {
311
316
  this.pendingWriteBytes = chunkByteLength(RIS);
312
317
  this.pendingWritesDropped = false;
313
318
  }
314
- focus() {
315
- this.terminal?.focus();
319
+ /**
320
+ * Moves the caret into the terminal's input surface, so the next keystroke goes to the pty
321
+ * rather than to whatever the page focused last. This is the call a host makes when the user
322
+ * selects a terminal in a list.
323
+ *
324
+ * The terminal is created asynchronously — the xterm modules are loaded on first connection —
325
+ * so a call that arrives before it exists is remembered and applied once it is ready, exactly
326
+ * once. The same applies to an element that is focused while detached and then reattached: the
327
+ * pending request is dropped on disconnect, because by then the user's intent has expired, and
328
+ * a fresh `focus()` after the move is what a host should issue.
329
+ *
330
+ * Only this method arms that behaviour; re-renders, buffered output and background updates
331
+ * never steal focus.
332
+ */
333
+ focus(optionsArg) {
334
+ const terminal = this.terminal;
335
+ if (terminal && this.isConnected) {
336
+ this.focusWhenReady = false;
337
+ terminal.focus();
338
+ return;
339
+ }
340
+ // Preventing scroll is a hint for the eventual focus, not a reason to skip it.
341
+ void optionsArg;
342
+ this.focusWhenReady = true;
343
+ }
344
+ /** True while an explicit `focus()` is waiting for the terminal to come up. */
345
+ get focusPending() {
346
+ return this.focusWhenReady;
316
347
  }
317
348
  /** Current grid size, or undefined while no terminal is live. */
318
349
  get currentSize() {
@@ -455,6 +486,11 @@ let DeesTerminalView = (() => {
455
486
  this.refit();
456
487
  this.resizeObserver = new ResizeObserver(() => this.refit());
457
488
  this.resizeObserver.observe(host);
489
+ // An explicit focus() that arrived before the terminal existed is honoured now, once.
490
+ if (this.focusWhenReady) {
491
+ this.focusWhenReady = false;
492
+ terminal.focus();
493
+ }
458
494
  this.readyResolve();
459
495
  }
460
496
  refit() {
@@ -488,6 +524,9 @@ let DeesTerminalView = (() => {
488
524
  // re-announce its grid and may retry a load that failed.
489
525
  this.lastReportedSize = '';
490
526
  this.setupPromise = undefined;
527
+ // A focus request belongs to the connection it was made in; a reattached element must not
528
+ // grab the caret from wherever the user moved it meanwhile.
529
+ this.focusWhenReady = false;
491
530
  // Buffered output deliberately survives, so a replay that arrived while the
492
531
  // element was detached still reaches the next connection.
493
532
  if (this.readyPending) {
@@ -501,4 +540,4 @@ let DeesTerminalView = (() => {
501
540
  return DeesTerminalView = _classThis;
502
541
  })();
503
542
  export { DeesTerminalView };
504
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy10ZXJtaW5hbC12aWV3LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHNfd2ViL2VsZW1lbnRzLzAwZ3JvdXAtaGFybmVzcy9kZWVzLXRlcm1pbmFsLXZpZXcvZGVlcy10ZXJtaW5hbC12aWV3LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDeEQsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osR0FBRyxFQUNILGFBQWEsRUFFYixRQUFRLEdBQ1QsTUFBTSw2QkFBNkIsQ0FBQztBQUdyQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQTJCbEU7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFFcEQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDO0FBRXBCLG1EQUFtRDtBQUNuRCxNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQTZCLEVBQVUsRUFBRSxDQUNoRSxPQUFPLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO0FBRTNFOzs7Ozs7Ozs7O0dBVUc7SUFFVSxnQkFBZ0I7NEJBRDVCLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQzs7OztzQkFDRSxXQUFXOzs7Ozs7O2dDQUFuQixTQUFRLFdBQVc7Ozs7b0NBSzlDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztvQ0FHMUIsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFB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
543
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy10ZXJtaW5hbC12aWV3LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHNfd2ViL2VsZW1lbnRzLzAwZ3JvdXAtaGFybmVzcy9kZWVzLXRlcm1pbmFsLXZpZXcvZGVlcy10ZXJtaW5hbC12aWV3LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDeEQsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osR0FBRyxFQUNILGFBQWEsRUFFYixRQUFRLEdBQ1QsTUFBTSw2QkFBNkIsQ0FBQztBQUdyQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQTJCbEU7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFFcEQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDO0FBRXBCLG1EQUFtRDtBQUNuRCxNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQTZCLEVBQVUsRUFBRSxDQUNoRSxPQUFPLFFBQVEsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO0FBRTNFOzs7Ozs7Ozs7O0dBVUc7SUFFVSxnQkFBZ0I7NEJBRDVCLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQzs7OztzQkFDRSxXQUFXOzs7Ozs7O2dDQUFuQixTQUFRLFdBQVc7Ozs7b0NBSzlDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztvQ0FHMUIsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFB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
@@ -8,6 +8,7 @@ export * from './dees-harness-overflow-text.js';
8
8
  export * from './dees-harness-chat/index.js';
9
9
  export * from './dees-harness-composer/index.js';
10
10
  export * from './dees-harness-content-blocks/index.js';
11
+ export * from './dees-harness-conversation-picker/index.js';
11
12
  export * from './dees-harness-message/index.js';
12
13
  export * from './dees-harness-permission-card/index.js';
13
14
  export * from './dees-harness-question-card/index.js';
@@ -11,6 +11,7 @@ export * from './dees-harness-overflow-text.js';
11
11
  export * from './dees-harness-chat/index.js';
12
12
  export * from './dees-harness-composer/index.js';
13
13
  export * from './dees-harness-content-blocks/index.js';
14
+ export * from './dees-harness-conversation-picker/index.js';
14
15
  export * from './dees-harness-message/index.js';
15
16
  export * from './dees-harness-permission-card/index.js';
16
17
  export * from './dees-harness-question-card/index.js';
@@ -23,4 +24,4 @@ export * from './dees-harness-status/index.js';
23
24
  export * from './dees-harness-todos/index.js';
24
25
  export * from './dees-harness-tool-card/index.js';
25
26
  export * from './dees-harness-usage/index.js';
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90c193ZWIvZWxlbWVudHMvMDBncm91cC1oYXJuZXNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9DQUFvQztBQUNwQywyRUFBMkU7QUFDM0UsNkVBQTZFO0FBQzdFLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUYsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGlDQUFpQyxDQUFDO0FBRWhELGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxrQ0FBa0MsQ0FBQztBQUNqRCxjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMsaUNBQWlDLENBQUM7QUFDaEQsY0FBYyx5Q0FBeUMsQ0FBQztBQUN4RCxjQUFjLHVDQUF1QyxDQUFDO0FBQ3RELGNBQWMsc0NBQXNDLENBQUM7QUFDckQsY0FBYyxtQ0FBbUMsQ0FBQztBQUNsRCxjQUFjLHNDQUFzQyxDQUFDO0FBQ3JELGNBQWMseUNBQXlDLENBQUM7QUFDeEQsY0FBYywrQkFBK0IsQ0FBQztBQUM5QyxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsK0JBQStCLENBQUM7QUFDOUMsY0FBYyxtQ0FBbUMsQ0FBQztBQUNsRCxjQUFjLCtCQUErQixDQUFDIn0=
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90c193ZWIvZWxlbWVudHMvMDBncm91cC1oYXJuZXNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9DQUFvQztBQUNwQywyRUFBMkU7QUFDM0UsNkVBQTZFO0FBQzdFLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUYsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGlDQUFpQyxDQUFDO0FBRWhELGNBQWMsOEJBQThCLENBQUM7QUFDN0MsY0FBYyxrQ0FBa0MsQ0FBQztBQUNqRCxjQUFjLHdDQUF3QyxDQUFDO0FBQ3ZELGNBQWMsNkNBQTZDLENBQUM7QUFDNUQsY0FBYyxpQ0FBaUMsQ0FBQztBQUNoRCxjQUFjLHlDQUF5QyxDQUFDO0FBQ3hELGNBQWMsdUNBQXVDLENBQUM7QUFDdEQsY0FBYyxzQ0FBc0MsQ0FBQztBQUNyRCxjQUFjLG1DQUFtQyxDQUFDO0FBQ2xELGNBQWMsc0NBQXNDLENBQUM7QUFDckQsY0FBYyx5Q0FBeUMsQ0FBQztBQUN4RCxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsZ0NBQWdDLENBQUM7QUFDL0MsY0FBYywrQkFBK0IsQ0FBQztBQUM5QyxjQUFjLG1DQUFtQyxDQUFDO0FBQ2xELGNBQWMsK0JBQStCLENBQUMifQ==
@@ -364,42 +364,57 @@ export interface IHarnessResourceMeta<TState extends string = string> {
364
364
  draggable?: boolean;
365
365
  }
366
366
  /**
367
- * A controlled zero-or-one association for one resource. The target is any
368
- * other list item — a session or another resource such as a terminal.
367
+ * The controlled set of associations for one resource. A resource can be attached to several
368
+ * items at once, and a target is any other list item — a session or another resource such as a
369
+ * terminal. An empty array is an unattached resource.
369
370
  */
370
371
  export interface IHarnessResourceAssociation {
371
372
  resourceId: string;
372
- target: IHarnessSessionListItemRef;
373
+ targets: IHarnessSessionListItemRef[];
373
374
  }
374
375
  export interface IHarnessResourceEventDetail<TState extends string = string> {
375
376
  resource: IHarnessResourceMeta<TState>;
376
- /** The controlled association target, or null when the resource is unattached. */
377
- target: IHarnessSessionListItemRef | null;
377
+ /** The controlled association targets; empty when the resource is unattached. */
378
+ targets: IHarnessSessionListItemRef[];
378
379
  }
379
380
  /**
380
- * Association is an explicit host action, never a drop: dragging a resource
381
- * only moves it inside the ordered list.
381
+ * Attaching is an explicit choice, never an accident of reordering: a drag only attaches when it
382
+ * is released on the centre of a row, and the edges of that same row stay positional. Keyboard
383
+ * moves are always positional; keyboard attaching goes through the host's menu.
382
384
  */
383
- export type THarnessResourceAssociationInteractionSource = 'action' | 'keyboard';
384
- export type THarnessResourceAssociationRequestDetail<TState extends string = string> = {
385
- intent: 'attach';
385
+ export type THarnessResourceAssociationInteractionSource = 'action' | 'keyboard' | 'pointer';
386
+ /**
387
+ * A validated association request. `attach` adds the first target, `attach-additional` adds
388
+ * another one beside existing targets, `move` replaces one specific target, and `detach` removes
389
+ * one. `fromTarget` always names the attachment being replaced or removed, never the whole set.
390
+ */
391
+ export type THarnessResourceAssociateDetail<TState extends string = string> = {
392
+ mode: 'attach';
386
393
  resource: IHarnessResourceMeta<TState>;
387
394
  fromTarget: null;
388
395
  toTarget: IHarnessSessionListItemRef;
389
396
  source: THarnessResourceAssociationInteractionSource;
390
397
  } | {
391
- intent: 'detach';
398
+ mode: 'attach-additional';
392
399
  resource: IHarnessResourceMeta<TState>;
393
- fromTarget: IHarnessSessionListItemRef;
394
- toTarget: null;
400
+ fromTarget: null;
401
+ toTarget: IHarnessSessionListItemRef;
395
402
  source: THarnessResourceAssociationInteractionSource;
396
403
  } | {
397
- intent: 'reassign';
404
+ mode: 'move';
398
405
  resource: IHarnessResourceMeta<TState>;
399
406
  fromTarget: IHarnessSessionListItemRef;
400
407
  toTarget: IHarnessSessionListItemRef;
401
408
  source: THarnessResourceAssociationInteractionSource;
409
+ } | {
410
+ mode: 'detach';
411
+ resource: IHarnessResourceMeta<TState>;
412
+ fromTarget: IHarnessSessionListItemRef;
413
+ toTarget: null;
414
+ source: THarnessResourceAssociationInteractionSource;
402
415
  };
416
+ /** Explicit mode for `requestAssociation`; omitted lets the list infer it from the current set. */
417
+ export type THarnessResourceAssociateMode = THarnessResourceAssociateDetail['mode'];
403
418
  export type THarnessResourceContextSource = 'pointer' | 'action' | 'keyboard';
404
419
  /** Detail of `harness-resource-context`; the host owns the actual menu. */
405
420
  export interface IHarnessResourceContextDetail<TState extends string = string> extends IHarnessResourceEventDetail<TState> {
@@ -407,8 +422,12 @@ export interface IHarnessResourceContextDetail<TState extends string = string> e
407
422
  clientY: number;
408
423
  source: THarnessResourceContextSource;
409
424
  originalEvent: MouseEvent | KeyboardEvent;
410
- /** Routes a host menu choice through the component's validated controlled request event. */
411
- requestAssociation: (toTarget: IHarnessSessionListItemRef | null) => boolean;
425
+ /**
426
+ * Routes a host menu choice through the component's validated controlled request event. With no
427
+ * mode, an unattached resource attaches and a singly attached one moves; a resource with several
428
+ * attachments is refused, because only the host knows which attachment was meant.
429
+ */
430
+ requestAssociation: (toTarget: IHarnessSessionListItemRef | null, mode?: THarnessResourceAssociateMode, fromTarget?: IHarnessSessionListItemRef | null) => boolean;
412
431
  /** Closes the external-menu disclosure state and restores focus to its invoking control. */
413
432
  close: () => void;
414
433
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design.estate/dees-catalog",
3
- "version": "11.2.2",
3
+ "version": "12.1.0",
4
4
  "private": false,
5
5
  "description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
6
6
  "main": "dist_ts_web/index.js",
package/readme.md CHANGED
@@ -165,6 +165,7 @@ task guide and examples deliberately; the generated table does not replace them.
165
165
  | `dees-harness-chat` | harness | [DeesHarnessChat](#deesharnesschat) | [Source](ts_web/elements/00group-harness/dees-harness-chat/dees-harness-chat.ts) |
166
166
  | `dees-harness-composer` | harness | [DeesHarnessComposer](#deesharnesscomposer) | [Source](ts_web/elements/00group-harness/dees-harness-composer/dees-harness-composer.ts) |
167
167
  | `dees-harness-content-blocks` | harness | [DeesHarnessContentBlocks](#deesharnesscontentblocks) | [Source](ts_web/elements/00group-harness/dees-harness-content-blocks/dees-harness-content-blocks.ts) |
168
+ | `dees-harness-conversation-picker` | harness | [DeesHarnessConversationPicker](#deesharnessconversationpicker) | [Source](ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.ts) |
168
169
  | `dees-harness-message` | harness | [DeesHarnessMessage](#deesharnessmessage) | [Source](ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.ts) |
169
170
  | `dees-harness-message-list` | harness | [DeesHarnessMessageList](#deesharnessmessagelist) | [Source](ts_web/elements/00group-harness/dees-harness-message-list/dees-harness-message-list.ts) |
170
171
  | `dees-harness-overflow-text` | harness | [DeesHarnessOverflowText](#deesharnessoverflowtext) | [Source](ts_web/elements/00group-harness/dees-harness-overflow-text.ts) |
@@ -2753,10 +2754,12 @@ Token usage chip (`in · out · total`, `compact` shows the total only); cache r
2753
2754
 
2754
2755
  #### `DeesTerminalView`
2755
2756
 
2756
- Transport-agnostic xterm.js surface. The host pipes remote PTY output in with `write(data)` and receives keystrokes as `terminal-input` (`{ data }`); there is no process, runtime or socket coupling. `terminal-resize` (`{ rows, cols }`) reports the grid after every refit so the host can negotiate a PTY size, and `currentSize` reads it back (`undefined` while no terminal is live). `fontSize` sets the grid font, `disabled` stops `terminal-input` from being emitted, and `focus()` focuses the grid. xterm is loaded through `DeesServiceLibLoader`; CSP-locked or offline hosts call `provideXtermModules()` first to supply their own bundled copy instead of the CDN.
2757
+ Transport-agnostic xterm.js surface. The host pipes remote PTY output in with `write(data)` and receives keystrokes as `terminal-input` (`{ data }`); there is no process, runtime or socket coupling. `terminal-resize` (`{ rows, cols }`) reports the grid after every refit so the host can negotiate a PTY size, and `currentSize` reads it back (`undefined` while no terminal is live). `fontSize` sets the grid font, `disabled` stops `terminal-input` from being emitted, and `focus()` moves the caret into the terminal's input surface. xterm is loaded through `DeesServiceLibLoader`; CSP-locked or offline hosts call `provideXtermModules()` first to supply their own bundled copy instead of the CDN.
2757
2758
 
2758
2759
  `write()` is safe before the terminal exists and while the element is detached: output is buffered and replayed in order on the next connection, bounded by the exported `maxPendingWriteBytes` (8 MiB — `Uint8Array` chunks count their `byteLength`, strings their UTF-16 memory). Past that bound the oldest chunks are dropped and the replay emits RIS first, so a truncated prefix is never rendered as if it were contiguous. `clear()` resets screen and scrollback through the write stream (RIS, `ESC c`) rather than around it, so it is ordered against output already queued in xterm — write, `clear()`, write leaves only the later output on screen.
2759
2760
 
2761
+ `focus()` is the call a host makes when the user selects a terminal — after a click, or after `Enter`/`Space` on a row — so the next keystroke goes to the pty instead of the page. Because the terminal is created asynchronously on first connection, a `focus()` that arrives before it exists is remembered and applied exactly once when it becomes ready; `focusPending` reads that state back. The request belongs to the connection it was made in and is dropped on disconnect, so an element moved between containers never grabs the caret back from wherever the user went — issue a fresh `focus()` after the move. Nothing else moves focus: re-renders, buffered output and background writes never steal it.
2762
+
2760
2763
  `ready` resolves once the terminal of the current connection is live; a fresh promise is created per connection, so a reattached element can be awaited again. Every connection builds a terminal and every disconnection disposes it, so an element moved between containers, or returned to, is a live surface rather than a dead one; buffered output survives the move. A failed xterm load is not an unhandled rejection: it dispatches the bubbling, composed `terminal-error` (`ITerminalErrorDetail { error }`), rejects `ready` with the same error, leaves the element writable, and is retried on the next connection. xterm's own flow-control refusal is reported the same way. Sizing comes from the host element — give it a bounded height, as the demo does.
2761
2764
 
2762
2765
  #### `DeesHarnessSessionSidebar`
@@ -2767,6 +2770,25 @@ Scratchpad edits emit `harness-scratchpad-save` with `{ text, expectedRevision }
2767
2770
 
2768
2771
  Direct sidebar hosts can set `intelligenceAvailabilityStatus`, `intelligenceUnavailableReason`, and `intelligenceHeading`; `intelligenceEnabled` still controls whether the section exists. The properties default to `available`, an empty reason, and `Session Intelligence`. A blank heading falls back to `Session Intelligence`, and unavailable state without a reason renders `<heading> is unavailable.` Only `available` permits `harness-session-intelligence-ask`; checking and unavailable states retain history and expose accessible status text. The availability union is exported as `THarnessIntelligenceAvailabilityStatus`.
2769
2772
 
2773
+ #### `DeesHarnessConversationPicker`
2774
+
2775
+ Keyboard-first picker for one conversation, or one attachable resource, used wherever a menu would otherwise list every possible target. It is presentation only: it never mutates a session, a resource, or an association — it resolves one choice and leaves the change to the host.
2776
+
2777
+ Set `.sessions`, `.groups` and `.resources` to the same models the list renders. `.excludeTargets` removes targets that would be a no-op (a resource's existing attachments), and `.eligibleTargets` restricts the offer to a host-declared allow-list; absent means unrestricted. Typing filters on title, project label and group name — the same fields the session list searches. Up/Down move the active row, Enter picks it, Escape cancels. `harness-picker-choose` carries `{ target: IHarnessSessionListItemRef }`; `harness-picker-cancel` carries nothing.
2778
+
2779
+ `DeesHarnessConversationPicker.pick(options)` is the one-call form: it opens the picker inside `DeesModal`, resolves with the chosen ref or `null` on cancel, closes the modal, and returns focus to whatever had it before. Reuse it for disambiguation as well — pass a resource's current attachments as `eligibleTargets` to ask which attachment a Move or Detach applies to.
2780
+
2781
+ ```typescript
2782
+ const target = await DeesHarnessConversationPicker.pick({
2783
+ sessions: list.sessions,
2784
+ groups: list.groups,
2785
+ excludeTargets: currentTargets,
2786
+ eligibleTargets: list.eligibleTargetsByResourceId[resource.id],
2787
+ heading: `Attach ${resource.title} to…`,
2788
+ });
2789
+ if (target) detail.requestAssociation(target, currentTargets.length ? 'attach-additional' : 'attach');
2790
+ ```
2791
+
2770
2792
  #### `DeesHarnessSessionList`
2771
2793
 
2772
2794
  Searchable, card-based conversation column for sidebars or a `DeesModal` (`harness-session-select` on click, `harness-session-open` on double-click/Enter). Cards stay collapsed until their independent accessible expansion control is used. Selection and working-state changes do not affect expansion.
@@ -2785,22 +2807,29 @@ The compact **New group** button sits beside search whenever `enableGrouping` is
2785
2807
 
2786
2808
  The Sessions demo pairs the list with a selected-session workspace. Its controls step through starting, working, feedback, approval, completion and failure without timers or backend operations. Question and permission responses update the selected session; declining approval pauses it. The narrow layout switches between the preserved list and detail panes with an **All sessions** control that restores row focus.
2787
2809
 
2788
- Generic host resources use the exported `IHarnessResourceMeta` and `IHarnessResourceAssociation` contracts. Set `.resources`, `.resourceAssociations`, `.selectedResourceId`, and `.eligibleTargetsByResourceId`. Resource rows render as top-level rows in the ordered list, never as children of a session. Optional `projectLabel` renders on the resource metadata line after the kind and is searched like the title and preview. Resource metadata is presentation-only: the list never mounts a terminal, browser, file viewer, or other runtime.
2810
+ Generic host resources use the exported `IHarnessResourceMeta` and `IHarnessResourceAssociation` contracts. Set `.resources`, `.resourceAssociations`, `.selectedResourceId`, and `.eligibleTargetsByResourceId`. Resource rows render as top-level rows in the ordered list, never as children of a session. Optional `projectLabel` renders on the resource metadata line after the kind and is searched like the title and preview. A resource can be attached to several items at once: `IHarnessResourceAssociation.targets` is a set of refs, de-duplicated on projection, and the row shows one marker per attachment — two by name, the rest as a `+N` count with every name in the row's title. `IHarnessResourceEventDetail.targets` carries the same set on select, open and context events. Resource metadata is presentation-only: the list never mounts a terminal, browser, file viewer, or other runtime.
2789
2811
 
2790
- **Attaching is a separate explicit action, not a drop.** An association is an access grant: it shows as a decorative marker on the resource row (a link icon plus the target's title, resolved from `sessions` or `resources` regardless of search or collapse) and never moves the row. Dropping is purely positional and never attaches. The association stays single-valued — a resource has at most one target — and the target is any other item, so a resource may be attached to a session **or** to another resource such as a terminal:
2812
+ **Attaching is a deliberate gesture, never an accident of reordering.** An association is an access grant: it shows as a decorative marker on the resource row (a link icon plus each target's title, resolved from `sessions` or `resources` regardless of search or collapse) and never moves the row. A resource dropped on the **centre half of a row** attaches to it; the outer quarters of that same row, and every gap between rows, stay purely positional. The row being targeted shows a ring, a tint and a link badge, and no insertion gap opens while it does. A drag attaches an unattached resource and moves a singly attached one. A resource attached to several conversations is only repositioned by drag — it offers no attach affordance on any row, because a drag cannot say which of its attachments was meant; use **Move to…** for that. Keyboard moves stay positional; attaching by keyboard goes through the host's menu. The target is any other item, so a resource may be attached to a session **or** to another resource such as a terminal, and to several at once:
2791
2813
 
2792
2814
  ```typescript
2793
2815
  list.resourceAssociations = [
2794
- { resourceId: 'file:notes', target: { kind: 'resource', id: 'terminal:build' } },
2816
+ { resourceId: 'file:notes', targets: [{ kind: 'resource', id: 'terminal:build' }] },
2817
+ {
2818
+ resourceId: 'terminal:build',
2819
+ targets: [{ kind: 'session', id: 's-4' }, { kind: 'session', id: 's-0' }],
2820
+ },
2795
2821
  ];
2796
2822
  ```
2797
2823
 
2798
- Association records are projected only when the resource exists, the target exists, the target is not the resource itself, and no earlier record claimed that resource. `eligibleTargetsByResourceId` restricts attach/reassign targets for host menus: a missing entry leaves the resource unrestricted, an empty array means no eligible target. Which resource kinds may host an attachment is the host's rule, not the component's.
2824
+ Targets are projected only when the resource exists, the target exists, the target is not the resource itself, and no earlier target in the same record already claimed it. `eligibleTargetsByResourceId` restricts targets for both the host menu and the drop affordance: a missing entry leaves the resource unrestricted, an empty array means no eligible target, and an ineligible row offers no attach affordance and commits nothing. Which resource kinds may host an attachment is the host's rule, not the component's.
2825
+
2826
+ `requestResourceAssociation(resourceId, toTarget, source?, mode?, fromTarget?)` and the context detail's `requestAssociation(toTarget, mode?, fromTarget?)` emit `harness-resource-associate` with `THarnessResourceAssociateDetail`: `mode` is `attach`, `attach-additional`, `move` or `detach`, and `fromTarget` names the single attachment being replaced or removed. With no mode, an unattached resource attaches and a singly attached one moves; a resource with several attachments is refused, because only the host knows which one the user meant — pass a mode and a `fromTarget`, or ask with `DeesHarnessConversationPicker`.
2799
2827
 
2800
2828
  ```typescript
2801
- import type {
2802
- IHarnessResourceContextDetail,
2803
- THarnessResourceAssociationRequestDetail,
2829
+ import {
2830
+ DeesHarnessConversationPicker,
2831
+ type IHarnessResourceContextDetail,
2832
+ type THarnessResourceAssociateDetail,
2804
2833
  } from '@design.estate/dees-catalog';
2805
2834
 
2806
2835
  const list = document.querySelector('dees-harness-session-list')!;
@@ -2810,37 +2839,42 @@ list.resources = [
2810
2839
  { id: 'file:notes', kind: 'file', title: 'Release notes', preview: '6.7.0 draft' },
2811
2840
  ];
2812
2841
  list.resourceAssociations = [
2813
- { resourceId: 'shell:build', target: { kind: 'session', id: 'session-1' } },
2842
+ { resourceId: 'shell:build', targets: [{ kind: 'session', id: 'session-1' }] },
2814
2843
  ];
2815
2844
  list.eligibleTargetsByResourceId = {
2816
2845
  'shell:build': [{ kind: 'session', id: 'session-1' }, { kind: 'session', id: 'session-2' }],
2817
2846
  'file:notes': [{ kind: 'session', id: 'session-2' }, { kind: 'resource', id: 'shell:build' }],
2818
2847
  };
2819
2848
 
2820
- list.addEventListener('harness-resource-association-request', async (event) => {
2821
- const resourceEvent = event as CustomEvent<THarnessResourceAssociationRequestDetail>;
2822
- const { resource, toTarget } = resourceEvent.detail;
2823
- await persistAssociation(resource.id, toTarget);
2849
+ list.addEventListener('harness-resource-associate', async (event) => {
2850
+ const resourceEvent = event as CustomEvent<THarnessResourceAssociateDetail>;
2851
+ const { resource, mode, fromTarget, toTarget } = resourceEvent.detail;
2852
+ await persistAssociation(resource.id, { mode, fromTarget, toTarget });
2824
2853
  list.resourceAssociations = await loadAssociations();
2825
2854
  });
2826
2855
 
2827
- list.addEventListener('harness-resource-context', (event) => {
2856
+ list.addEventListener('harness-resource-context', async (event) => {
2828
2857
  const resourceEvent = event as CustomEvent<IHarnessResourceContextDetail>;
2829
- openHostMenu({
2830
- x: resourceEvent.detail.clientX,
2831
- y: resourceEvent.detail.clientY,
2832
- attach: (target) => resourceEvent.detail.requestAssociation(target),
2833
- detach: () => resourceEvent.detail.requestAssociation(null),
2834
- onClose: resourceEvent.detail.close,
2858
+ const { resource, targets } = resourceEvent.detail;
2859
+ resourceEvent.detail.close();
2860
+ const target = await DeesHarnessConversationPicker.pick({
2861
+ sessions: list.sessions,
2862
+ groups: list.groups,
2863
+ excludeTargets: targets,
2864
+ eligibleTargets: list.eligibleTargetsByResourceId[resource.id],
2865
+ heading: `Attach ${resource.title} to…`,
2835
2866
  });
2867
+ if (target) {
2868
+ resourceEvent.detail.requestAssociation(target, targets.length ? 'attach-additional' : 'attach');
2869
+ }
2836
2870
  });
2837
2871
  ```
2838
2872
 
2839
- `harness-resource-select` and `harness-resource-open` carry `{ resource, target }`, where `target` is the controlled association ref or null. `harness-resource-context` adds viewport coordinates, the pointer/Actions/keyboard source, the original event, `requestAssociation(toTarget)`, and `close()` for focus restoration. The visible Actions button has menu disclosure semantics; native `ContextMenu` and `Shift+F10` invoke the same host-owned path. The component does not require `DeesContextmenu` and does not own menu choices.
2873
+ `harness-resource-select` and `harness-resource-open` carry `{ resource, targets }`, where `targets` is the controlled set of association refs and is empty for an unattached resource. `harness-resource-context` adds viewport coordinates, the pointer/Actions/keyboard source, the original event, `requestAssociation(toTarget, mode?, fromTarget?)`, and `close()` for focus restoration. The visible Actions button has menu disclosure semantics; native `ContextMenu` and `Shift+F10` invoke the same host-owned path. The component does not require `DeesContextmenu` and does not own menu choices.
2840
2874
 
2841
- All component-originated association request paths converge on the public `requestResourceAssociation(resourceId, toTarget, source?)` method. A valid change emits one bubbling/composed `harness-resource-association-request` discriminated by `intent: 'attach' | 'detach' | 'reassign'` and carrying `resource`, `fromTarget`, `toTarget`, and `source: 'action' | 'keyboard'`. The method returns `false` and emits nothing for unknown resources, unknown or ineligible targets, a target that is the resource itself, detach from an unattached resource, or the current target. It never mutates resources, associations, selection, groups, or order.
2875
+ All component-originated association paths converge on the public `requestResourceAssociation(resourceId, toTarget, source?, mode?, fromTarget?)` method. A valid change emits one bubbling/composed `harness-resource-associate` discriminated by `mode: 'attach' | 'attach-additional' | 'move' | 'detach'` and carrying `resource`, `fromTarget`, `toTarget`, and `source: 'action' | 'keyboard' | 'pointer'`. The method returns `false` and emits nothing for unknown resources, unknown or ineligible targets, a target that is the resource itself, a target already in the set, a `move`/`detach` whose `fromTarget` is not in the set, an `attach` on an already attached resource, an `attach-additional` on an unattached one, or an ambiguous request with no mode. It never mutates resources, associations, selection, groups, or order.
2842
2876
 
2843
- Association projection is deterministic and non-destructive: resource records without a non-empty ID, kind, or title, unknown resource/target references, self-targets, and later duplicate records for a resource are ignored; the first valid association wins. Duplicate resource metadata IDs likewise use the first resource. Eligibility does not hide an existing authoritative association, which remains visible and detachable. Requested changes are announced separately from completion; completion is announced only after the controlled association input reflects the requested target.
2877
+ Association projection is deterministic and non-destructive: resource records without a non-empty ID, kind, or title, unknown resource/target references, self-targets, and repeated targets are ignored; several records for one resource merge into one de-duplicated set. Duplicate resource metadata IDs likewise use the first resource. Eligibility does not hide an existing authoritative association, which remains visible and detachable. Requested changes are announced separately from completion; completion is announced only after the controlled association input reflects the requested set.
2844
2878
 
2845
2879
  Search covers resource ID, kind, title, and preview, and matches sessions and resources as peers — a matching session no longer reveals its attached resources, and a matching resource no longer reveals its target. Resources render with zero sessions. Resource dragging edge-scrolls the list exactly like session dragging and emits only `harness-item-move`. Use the Actions/context path for keyboard and mobile association workflows; coarse-pointer grip and Actions targets are at least 44px.
2846
2880
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-catalog',
6
- version: '11.2.2',
6
+ version: '12.1.0',
7
7
  description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
8
8
  }
@@ -0,0 +1,46 @@
1
+ import { html } from '@design.estate/dees-element';
2
+ import { demoPage } from '../../../demos/templates.js';
3
+ import type { IHarnessSessionGroup, IHarnessSessionMeta, IHarnessResourceMeta } from '../interfaces.js';
4
+
5
+ const demoSessions: IHarnessSessionMeta[] = [
6
+ { id: 's1', title: 'Fix sitemap cache key', projectLabel: 'storefront', updatedAt: Date.now() - 1_000 },
7
+ { id: 's2', title: 'Investigate model rate limits', projectLabel: 'gateway', updatedAt: Date.now() - 2_000 },
8
+ { id: 's3', title: 'Prepare the catalog release', projectLabel: 'catalog', updatedAt: Date.now() - 3_000 },
9
+ { id: 's4', title: 'Improve agent onboarding', updatedAt: Date.now() - 4_000 },
10
+ ];
11
+
12
+ const demoResources: IHarnessResourceMeta[] = [
13
+ { id: 'terminal:build', kind: 'terminal', title: 'Build shell', icon: 'lucide:Terminal', projectLabel: 'storefront' },
14
+ ];
15
+
16
+ const demoGroups: IHarnessSessionGroup[] = [
17
+ { id: 'active', name: 'Workspace', itemIds: [{ kind: 'session', id: 's1' }, { kind: 'session', id: 's2' }] },
18
+ { id: 'review', name: 'Review', itemIds: [{ kind: 'session', id: 's3' }] },
19
+ ];
20
+
21
+ export const demoFunc = () => demoPage(
22
+ 'Conversation picker',
23
+ 'Keyboard-first target picker: type to filter on title, project label or group, Enter picks, Escape cancels.',
24
+ html`
25
+ <style>
26
+ .pickerDemo {
27
+ max-width: 420px;
28
+ padding: 16px;
29
+ border: 1px solid var(--dees-color-border-subtle);
30
+ border-radius: var(--dees-radius-xl);
31
+ background: var(--dees-color-bg-secondary);
32
+ }
33
+ </style>
34
+ <div class="pickerDemo">
35
+ <dees-harness-conversation-picker
36
+ heading="Attach Build shell to…"
37
+ .sessions=${demoSessions}
38
+ .groups=${demoGroups}
39
+ .resources=${demoResources}
40
+ .excludeTargets=${[{ kind: 'session' as const, id: 's4' }]}
41
+ @harness-picker-choose=${(event: CustomEvent) => console.log('picked', event.detail.target)}
42
+ @harness-picker-cancel=${() => console.log('cancelled')}
43
+ ></dees-harness-conversation-picker>
44
+ </div>
45
+ `,
46
+ );