@design.estate/dees-catalog 11.2.1 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_bundle/bundle.js +1927 -1305
- package/dist_bundle/bundle.js.map +1 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.d.ts +62 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.js +38 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.js +455 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/index.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/index.js +2 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.d.ts +39 -10
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.demo.js +81 -27
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.js +327 -115
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.d.ts +6 -2
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.js +68 -17
- package/dist_ts_web/elements/00group-harness/index.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/index.js +2 -1
- package/dist_ts_web/elements/00group-harness/interfaces.d.ts +35 -16
- package/package.json +2 -2
- package/readme.md +56 -24
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.ts +46 -0
- package/ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.ts +420 -0
- package/ts_web/elements/00group-harness/dees-harness-conversation-picker/index.ts +1 -0
- package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.demo.ts +94 -36
- package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts +357 -120
- package/ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.ts +67 -16
- package/ts_web/elements/00group-harness/index.ts +1 -0
- package/ts_web/elements/00group-harness/interfaces.ts +41 -16
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) |
|
|
@@ -2640,7 +2641,7 @@ Scrollable streaming-safe log. Up to 40 canonical entries (`messages` + `permiss
|
|
|
2640
2641
|
|
|
2641
2642
|
`refreshMessages(ids?)` reconciles in-place host mutations without replacing canonical objects. With IDs, it refreshes only matching message rows that are currently mounted; matching offscreen rows remain unmounted and use the mutated canonical objects when later mounted. With IDs omitted, it rebuilds structural transcript state and refreshes all mounted rows. `[]` is a no-op.
|
|
2642
2643
|
|
|
2643
|
-
Producers with authoritative source chronology can set `IHarnessMessage.order` to `{ messageIndex, partIndex }`; explicitly ordered messages retain that relative order while timestamps continue to place legacy messages and ancillary cards. Consecutive tool calls use one generic responsive-grid pipeline at their chronological position, partitioned by descriptor layout: compact tools share rows with compact tools, subagents share rows only with subagents, and terminal plus file-write cards span a whole row. Consecutive same-layout runs are always capped at four cards per group row, even when their tool kinds differ. Columns respond to the row's own width rather than the viewport, and status changes never regroup cards. Because a compact group sits inside the content measure, its column count is bounded by that measure — two columns at the 820px default; the wider three- and four-column steps apply when a host widens `--dees-harness-content-width`. Rows are held to a reading measure — `--dees-harness-content-width`, default `820px`, capped at the available width — while terminal and file-write rows keep the full pane, so prose stays readable and diffs and command output get the room they need. A subagent group takes the pane only from three cards upward; one or two stay on the measure. A terminal or file-write card keeps the pane only while it is open: once collapsed it returns to the reading measure, because a one-line header does not need the room its output did. This holds for every card in a terminal/file-write group, not only a lone one — those cards span all the columns of their row and stack vertically, so each follows its own disclosure and a collapsed command can sit above an open diff. The row itself still spans the pane; the card centres inside it and
|
|
2644
|
+
Producers with authoritative source chronology can set `IHarnessMessage.order` to `{ messageIndex, partIndex }`; explicitly ordered messages retain that relative order while timestamps continue to place legacy messages and ancillary cards. Consecutive tool calls use one generic responsive-grid pipeline at their chronological position, partitioned by descriptor layout: compact tools share rows with compact tools, subagents share rows only with subagents, and terminal plus file-write cards span a whole row. Consecutive same-layout runs are always capped at four cards per group row, even when their tool kinds differ. Columns respond to the row's own width rather than the viewport, and status changes never regroup cards. Because a compact group sits inside the content measure, its column count is bounded by that measure — two columns at the 820px default; the wider three- and four-column steps apply when a host widens `--dees-harness-content-width`. Rows are held to a reading measure — `--dees-harness-content-width`, default `820px`, capped at the available width — while terminal and file-write rows keep the full pane, so prose stays readable and diffs and command output get the room they need. A subagent group takes the pane only from three cards upward; one or two stay on the measure. A terminal or file-write card keeps the pane only while it is open: once collapsed it returns to the reading measure, because a one-line header does not need the room its output did. This holds for every card in a terminal/file-write group, not only a lone one — those cards span all the columns of their row and stack vertically, so each follows its own disclosure and a collapsed command can sit above an open diff. The row itself still spans the pane; the card surface centres inside it and interpolates between the two widths on the standard disclosure timing, in step with the body height and the outcome line, so a toggle never snaps at either end. A card that mounts collapsed is already at its measure and does not animate into it. The genuinely side-by-side grids — compact tools and subagents — are never offered this width and keep their cell width in both states. The list publishes the collapsed width to its terminal/file-write rows as `--dees-harness-collapsed-tool-width`, derived from `--dees-harness-content-width`; a host can set it on a row to widen those cards, or set `100%` to keep collapsed cards full-bleed; setting it on the chat or the list also reaches compact and subagent cells, so prefer row-level overrides. The docked composer keeps its full-bleed bar and insets its content to the same measure, so the prompt lines up with the messages above it. The status line under the transcript sits on that measure too, so the working indicator starts where the messages start rather than at the pane edge. Set the custom property on the chat or the list to widen or disable the column; it is read when rows are measured, so change it at mount rather than while a virtualized transcript is scrolled. Untouched projected subtask cards collapse individually on completion with the normal disclosure animation; other cards retain their descriptor or user-selected disclosure state. Auto-follow responds to streamed growth but does not repeatedly repin while a disclosure shrinks. Permission requests, questions, and nested-stream limits behave as before. Props: `messages`, `permissions`/`permissionsBusy`, `questions`, `status`, `viewState`, `transcriptKey`, `hasEarlierMessages`, `loadingEarlier`, `autoFollow`, `hideScrollbar`, `fadeScrollEdges`, `showRoles`, `showTimestamps`, `allowSubtaskStreams`, `markdownWhileStreaming` (default `true`), `emptyTitle`/`emptyText` (+ `slot="empty"`). Native browser find and selection cover the mounted window; hosts that require complete-history search or copy should operate on their canonical `messages`, `permissions`, and `questions` models.
|
|
2644
2645
|
|
|
2645
2646
|
#### `DeesHarnessMessage`
|
|
2646
2647
|
|
|
@@ -2654,7 +2655,7 @@ One message: role accent, markdown (assistant default, `message.markdown` overri
|
|
|
2654
2655
|
|
|
2655
2656
|
#### `DeesHarnessToolCard`
|
|
2656
2657
|
|
|
2657
|
-
Tool-call card: shared chrome (icon, label, subtitle, status pill, duration, MCP badges) with a per-kind body. Kind resolution goes through `DeesHarnessToolRegistry` (see below); bodies for the seeded kinds — terminal, file-read, file-write (renders a before/after diff via `dees-dataview-codebox` when the input carries previous content), file-delete, dir-list, browser (inline screenshots), http, json, search, subtask, project-task, todo, mcp, unknown — live in `renderers.ts`. File-write cards retain the user's inline/split choice while the same call updates. Numeric patch hunks preserve their source line numbers; patches and replacement snippets without coordinates hide gutters rather than presenting fabricated positions. A producer-supplied `IHarnessToolCall.title` leads the subtitle when present — a harness's own one-line description of the call, such as `Read SKILL.md` for a shell invocation — and the descriptor-derived line stays reachable as the hover tooltip; a blank title falls back to the derived line. Overflowing subtitles use a 40px right-edge fade and reveal the full line on hover plus once after a two-second initial delay. Expand/collapse always uses a smooth disclosure transition. Initially closed bodies mount lazily on first expansion, then retain the same DOM and become inert plus `aria-hidden` while closed. A closed card also reflects `data-collapsed` on its host and honours `--dees-harness-collapsed-tool-width` as its own `max-width`, so a transcript row can hold a collapsed card to a narrower measure than an open one; unset — a direct tool-card host, a grid cell — the card fills its row in both states. Long outputs truncate at 6,000 chars with a "Show all" expander. Terminal and error cards open by default, and a terminal card collapses itself again once its command has finished without reporting a failure. A producer whose failed commands come back as `completed` with the failure only in the output must signal it through `exitCode`, `isError` or `status: 'error'`, or the card collapses behind its one-line outcome. A missing exit code is not a failure — most harnesses never send one — so a completed command collapses whether or not it reported `exitCode: 0`. A non-zero exit, an error status, `isError`, and a stopped command all keep their output on screen. A collapsed terminal shows a one-line outcome (exit code when the call carried one, line count or `no output`, and the last meaningful line) beneath the command; an exit code is never invented for a call that did not report one. It is derived from the call's own output rather than from any producer-supplied description, so it is present for every producer. An explicit expand or collapse by the user always wins and is never overridden when the call settles. Descriptors opt in through `collapseWhenFinished` and supply the line through `summary`. Terminal output uses a black inner log surface and follows the live tail after reaching the card-height cap. Scrolling upward detaches the tail; leaving the card returns to the bottom after five seconds, while re-entering cancels that pending return. Terminal calls may provide `exitCode` separately when `output` is one combined process stream; the renderer retains support for `{ stdout, stderr, exitCode }` output objects. A subagent card is capped by `--dees-harness-active-subtask-height` (default `320px`) rather than fixed to it: a settled agent whose brief and result fit sizes to its own text, and only content past the cap hands the overflow to the panels, which scroll with a hidden scrollbar and a fade mask at the clipped edge. Both the Agent Brief and the Result carry that affordance, and the drill-in action stays pinned at the bottom of the card. A live child keeps the full window so its streaming transcript has a stable area to scroll in.
|
|
2658
|
+
Tool-call card: shared chrome (icon, label, subtitle, status pill, duration, MCP badges) with a per-kind body. Kind resolution goes through `DeesHarnessToolRegistry` (see below); bodies for the seeded kinds — terminal, file-read, file-write (renders a before/after diff via `dees-dataview-codebox` when the input carries previous content), file-delete, dir-list, browser (inline screenshots), http, json, search, subtask, project-task, todo, mcp, unknown — live in `renderers.ts`. File-write cards retain the user's inline/split choice while the same call updates. Numeric patch hunks preserve their source line numbers; patches and replacement snippets without coordinates hide gutters rather than presenting fabricated positions. A producer-supplied `IHarnessToolCall.title` leads the subtitle when present — a harness's own one-line description of the call, such as `Read SKILL.md` for a shell invocation — and the descriptor-derived line stays reachable as the hover tooltip; a blank title falls back to the derived line. Overflowing subtitles use a 40px right-edge fade and reveal the full line on hover plus once after a two-second initial delay. Expand/collapse always uses a smooth disclosure transition: the card surface width, the body height and the collapsed outcome line all run on `--dees-transition-default` with `--dees-ease-standard`, started by the same update, and all three stop together under `prefers-reduced-motion: reduce`. Width is constrained on the card surface rather than the host, because the shared default stylesheet applies a universal background/colour transition to every element and that rule reaches this element from its parent's tree, where it outranks any host-scoped rule. Initially closed bodies mount lazily on first expansion, then retain the same DOM and become inert plus `aria-hidden` while closed; the outcome line likewise stays mounted and is hidden from assistive technology while the card is open. A closed card also reflects `data-collapsed` on its host and honours `--dees-harness-collapsed-tool-width` as its own `max-width`, so a transcript row can hold a collapsed card to a narrower measure than an open one; unset — a direct tool-card host, a grid cell — the card fills its row in both states. Long outputs truncate at 6,000 chars with a "Show all" expander. Terminal and error cards open by default, and a terminal card collapses itself again once its command has finished without reporting a failure. A producer whose failed commands come back as `completed` with the failure only in the output must signal it through `exitCode`, `isError` or `status: 'error'`, or the card collapses behind its one-line outcome. A missing exit code is not a failure — most harnesses never send one — so a completed command collapses whether or not it reported `exitCode: 0`. A non-zero exit, an error status, `isError`, and a stopped command all keep their output on screen. A collapsed terminal shows a one-line outcome (exit code when the call carried one, line count or `no output`, and the last meaningful line) beneath the command, which opens and closes with the same timing as the body so the header never steps by a line; an exit code is never invented for a call that did not report one. It is derived from the call's own output rather than from any producer-supplied description, so it is present for every producer. An explicit expand or collapse by the user always wins and is never overridden when the call settles. Descriptors opt in through `collapseWhenFinished` and supply the line through `summary`. Terminal output uses a black inner log surface and follows the live tail after reaching the card-height cap. Scrolling upward detaches the tail; leaving the card returns to the bottom after five seconds, while re-entering cancels that pending return. Terminal calls may provide `exitCode` separately when `output` is one combined process stream; the renderer retains support for `{ stdout, stderr, exitCode }` output objects. A subagent card is capped by `--dees-harness-active-subtask-height` (default `320px`) rather than fixed to it: a settled agent whose brief and result fit sizes to its own text, and only content past the cap hands the overflow to the panels, which scroll with a hidden scrollbar and a fade mask at the clipped edge. Both the Agent Brief and the Result carry that affordance, and the drill-in action stays pinned at the bottom of the card. A live child keeps the full window so its streaming transcript has a stable area to scroll in.
|
|
2658
2659
|
|
|
2659
2660
|
After mutating a canonical tool call in place, call `refreshCall()`. It refreshes the mounted card, any mounted nested subtask transcript, and any open fullscreen card while retaining the same canonical call and nested-message object references; it does not clone or replace them.
|
|
2660
2661
|
|
|
@@ -2767,6 +2768,25 @@ Scratchpad edits emit `harness-scratchpad-save` with `{ text, expectedRevision }
|
|
|
2767
2768
|
|
|
2768
2769
|
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
2770
|
|
|
2771
|
+
#### `DeesHarnessConversationPicker`
|
|
2772
|
+
|
|
2773
|
+
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.
|
|
2774
|
+
|
|
2775
|
+
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.
|
|
2776
|
+
|
|
2777
|
+
`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.
|
|
2778
|
+
|
|
2779
|
+
```typescript
|
|
2780
|
+
const target = await DeesHarnessConversationPicker.pick({
|
|
2781
|
+
sessions: list.sessions,
|
|
2782
|
+
groups: list.groups,
|
|
2783
|
+
excludeTargets: currentTargets,
|
|
2784
|
+
eligibleTargets: list.eligibleTargetsByResourceId[resource.id],
|
|
2785
|
+
heading: `Attach ${resource.title} to…`,
|
|
2786
|
+
});
|
|
2787
|
+
if (target) detail.requestAssociation(target, currentTargets.length ? 'attach-additional' : 'attach');
|
|
2788
|
+
```
|
|
2789
|
+
|
|
2770
2790
|
#### `DeesHarnessSessionList`
|
|
2771
2791
|
|
|
2772
2792
|
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 +2805,29 @@ The compact **New group** button sits beside search whenever `enableGrouping` is
|
|
|
2785
2805
|
|
|
2786
2806
|
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
2807
|
|
|
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.
|
|
2808
|
+
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
2809
|
|
|
2790
|
-
**Attaching is a
|
|
2810
|
+
**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
2811
|
|
|
2792
2812
|
```typescript
|
|
2793
2813
|
list.resourceAssociations = [
|
|
2794
|
-
{ resourceId: 'file:notes',
|
|
2814
|
+
{ resourceId: 'file:notes', targets: [{ kind: 'resource', id: 'terminal:build' }] },
|
|
2815
|
+
{
|
|
2816
|
+
resourceId: 'terminal:build',
|
|
2817
|
+
targets: [{ kind: 'session', id: 's-4' }, { kind: 'session', id: 's-0' }],
|
|
2818
|
+
},
|
|
2795
2819
|
];
|
|
2796
2820
|
```
|
|
2797
2821
|
|
|
2798
|
-
|
|
2822
|
+
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.
|
|
2823
|
+
|
|
2824
|
+
`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
2825
|
|
|
2800
2826
|
```typescript
|
|
2801
|
-
import
|
|
2802
|
-
|
|
2803
|
-
|
|
2827
|
+
import {
|
|
2828
|
+
DeesHarnessConversationPicker,
|
|
2829
|
+
type IHarnessResourceContextDetail,
|
|
2830
|
+
type THarnessResourceAssociateDetail,
|
|
2804
2831
|
} from '@design.estate/dees-catalog';
|
|
2805
2832
|
|
|
2806
2833
|
const list = document.querySelector('dees-harness-session-list')!;
|
|
@@ -2810,37 +2837,42 @@ list.resources = [
|
|
|
2810
2837
|
{ id: 'file:notes', kind: 'file', title: 'Release notes', preview: '6.7.0 draft' },
|
|
2811
2838
|
];
|
|
2812
2839
|
list.resourceAssociations = [
|
|
2813
|
-
{ resourceId: 'shell:build',
|
|
2840
|
+
{ resourceId: 'shell:build', targets: [{ kind: 'session', id: 'session-1' }] },
|
|
2814
2841
|
];
|
|
2815
2842
|
list.eligibleTargetsByResourceId = {
|
|
2816
2843
|
'shell:build': [{ kind: 'session', id: 'session-1' }, { kind: 'session', id: 'session-2' }],
|
|
2817
2844
|
'file:notes': [{ kind: 'session', id: 'session-2' }, { kind: 'resource', id: 'shell:build' }],
|
|
2818
2845
|
};
|
|
2819
2846
|
|
|
2820
|
-
list.addEventListener('harness-resource-
|
|
2821
|
-
const resourceEvent = event as CustomEvent<
|
|
2822
|
-
const { resource, toTarget } = resourceEvent.detail;
|
|
2823
|
-
await persistAssociation(resource.id, toTarget);
|
|
2847
|
+
list.addEventListener('harness-resource-associate', async (event) => {
|
|
2848
|
+
const resourceEvent = event as CustomEvent<THarnessResourceAssociateDetail>;
|
|
2849
|
+
const { resource, mode, fromTarget, toTarget } = resourceEvent.detail;
|
|
2850
|
+
await persistAssociation(resource.id, { mode, fromTarget, toTarget });
|
|
2824
2851
|
list.resourceAssociations = await loadAssociations();
|
|
2825
2852
|
});
|
|
2826
2853
|
|
|
2827
|
-
list.addEventListener('harness-resource-context', (event) => {
|
|
2854
|
+
list.addEventListener('harness-resource-context', async (event) => {
|
|
2828
2855
|
const resourceEvent = event as CustomEvent<IHarnessResourceContextDetail>;
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2856
|
+
const { resource, targets } = resourceEvent.detail;
|
|
2857
|
+
resourceEvent.detail.close();
|
|
2858
|
+
const target = await DeesHarnessConversationPicker.pick({
|
|
2859
|
+
sessions: list.sessions,
|
|
2860
|
+
groups: list.groups,
|
|
2861
|
+
excludeTargets: targets,
|
|
2862
|
+
eligibleTargets: list.eligibleTargetsByResourceId[resource.id],
|
|
2863
|
+
heading: `Attach ${resource.title} to…`,
|
|
2835
2864
|
});
|
|
2865
|
+
if (target) {
|
|
2866
|
+
resourceEvent.detail.requestAssociation(target, targets.length ? 'attach-additional' : 'attach');
|
|
2867
|
+
}
|
|
2836
2868
|
});
|
|
2837
2869
|
```
|
|
2838
2870
|
|
|
2839
|
-
`harness-resource-select` and `harness-resource-open` carry `{ resource,
|
|
2871
|
+
`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
2872
|
|
|
2841
|
-
All component-originated association
|
|
2873
|
+
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
2874
|
|
|
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
|
|
2875
|
+
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
2876
|
|
|
2845
2877
|
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
2878
|
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@design.estate/dees-catalog',
|
|
6
|
-
version: '
|
|
6
|
+
version: '12.0.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
|
+
);
|