@ai-ecoverse/slicc-spectrum 1.4.0 → 1.6.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 (43) hide show
  1. package/README.md +32 -6
  2. package/dist/{chunk-SBRFYELH.js → chunk-4JUIYZ4Q.js} +4 -4
  3. package/dist/{chunk-DKUZSKYB.js → chunk-CDYGCBW7.js} +4 -4
  4. package/dist/{chunk-YPQKCWWG.js → chunk-FXM4K5WL.js} +4 -4
  5. package/dist/{chunk-C6RSQDMS.js → chunk-H57UPFSK.js} +2 -2
  6. package/dist/{chunk-FFZJVWZQ.js → chunk-JCRICTXR.js} +5 -5
  7. package/dist/{chunk-6JNYNXUQ.js → chunk-LR5GBIK7.js} +7 -7
  8. package/dist/{chunk-6GSDEWD5.js → chunk-MJOCPOXZ.js} +8 -8
  9. package/dist/{chunk-JUNZW2NI.js → chunk-N27WNL5Q.js} +3 -3
  10. package/dist/chunk-WCSKGA5W.js +30 -0
  11. package/dist/chunk-WCSKGA5W.js.map +7 -0
  12. package/dist/chunk-YWO2TNED.js +71 -0
  13. package/dist/chunk-YWO2TNED.js.map +7 -0
  14. package/dist/slicc-dummy.js +4 -62
  15. package/dist/slicc-dummy.js.map +4 -4
  16. package/dist/slicc-kernel-model.js +379 -0
  17. package/dist/slicc-kernel-model.js.map +7 -0
  18. package/dist/slicc-terminal.js +3 -26
  19. package/dist/slicc-terminal.js.map +3 -3
  20. package/dist/slicc-ui.js +586 -77
  21. package/dist/slicc-ui.js.map +4 -4
  22. package/dist/types/app/app.d.ts +7 -1
  23. package/dist/types/app/chat.d.ts +8 -0
  24. package/dist/types/app/composer.d.ts +4 -1
  25. package/dist/types/app/dips.d.ts +13 -0
  26. package/dist/types/app/files.d.ts +11 -0
  27. package/dist/types/app/panels.d.ts +15 -4
  28. package/dist/types/app/spectrum.d.ts +3 -0
  29. package/dist/types/components/dock.d.ts +2 -0
  30. package/dist/types/kernel/files.d.ts +20 -0
  31. package/dist/types/kernel/idle.d.ts +51 -0
  32. package/dist/types/kernel/index.d.ts +17 -0
  33. package/dist/types/kernel/terminals.d.ts +21 -0
  34. package/dist/types/kernel.d.ts +7 -0
  35. package/package.json +6 -2
  36. /package/dist/{chunk-SBRFYELH.js.map → chunk-4JUIYZ4Q.js.map} +0 -0
  37. /package/dist/{chunk-DKUZSKYB.js.map → chunk-CDYGCBW7.js.map} +0 -0
  38. /package/dist/{chunk-YPQKCWWG.js.map → chunk-FXM4K5WL.js.map} +0 -0
  39. /package/dist/{chunk-C6RSQDMS.js.map → chunk-H57UPFSK.js.map} +0 -0
  40. /package/dist/{chunk-FFZJVWZQ.js.map → chunk-JCRICTXR.js.map} +0 -0
  41. /package/dist/{chunk-6JNYNXUQ.js.map → chunk-LR5GBIK7.js.map} +0 -0
  42. /package/dist/{chunk-6GSDEWD5.js.map → chunk-MJOCPOXZ.js.map} +0 -0
  43. /package/dist/{chunk-JUNZW2NI.js.map → chunk-N27WNL5Q.js.map} +0 -0
package/dist/slicc-ui.js CHANGED
@@ -1,3 +1,9 @@
1
+ import {
2
+ SlottableRequestEvent,
3
+ conditionAttributeWithId,
4
+ isWebKit,
5
+ randomID
6
+ } from "./chunk-Y4Z7K443.js";
1
7
  import {
2
8
  IS_MOBILE,
3
9
  IS_TOUCH_DEVICE,
@@ -15,16 +21,7 @@ import {
15
21
  import {
16
22
  SizedMixin,
17
23
  n as n2
18
- } from "./chunk-SBRFYELH.js";
19
- import {
20
- defineElement
21
- } from "./chunk-6A6NIESE.js";
22
- import {
23
- SlottableRequestEvent,
24
- conditionAttributeWithId,
25
- isWebKit,
26
- randomID
27
- } from "./chunk-Y4Z7K443.js";
24
+ } from "./chunk-4JUIYZ4Q.js";
28
25
  import "./chunk-364Y2XOJ.js";
29
26
  import {
30
27
  r
@@ -38,6 +35,9 @@ import {
38
35
  o,
39
36
  o2
40
37
  } from "./chunk-2BBOXTOJ.js";
38
+ import {
39
+ defineElement
40
+ } from "./chunk-6A6NIESE.js";
41
41
  import {
42
42
  A,
43
43
  D,
@@ -2048,7 +2048,7 @@ var MenuItem = class extends LikeAnchor(ObserveSlotText(ObserveSlotPresence(Focu
2048
2048
  <sp-icon-chevron100
2049
2049
  class="spectrum-UIIcon-ChevronRight100 chevron icon"
2050
2050
  ></sp-icon-chevron100>
2051
- ` : (this.dependencyManager.add("sp-overlay"), this.dependencyManager.add("sp-popover"), import("./chunk-FFZJVWZQ.js"), import("./chunk-7PY7B3ZW.js"), b`
2051
+ ` : (this.dependencyManager.add("sp-overlay"), this.dependencyManager.add("sp-popover"), import("./chunk-JCRICTXR.js"), import("./chunk-7PY7B3ZW.js"), b`
2052
2052
  <sp-overlay
2053
2053
  receives-focus="false"
2054
2054
  .triggerElement=${this}
@@ -3113,7 +3113,7 @@ var PickerBase = class extends SizedMixin(ExpandableElement, { noDefaultSize: tr
3113
3113
  `;
3114
3114
  }
3115
3115
  renderLoader() {
3116
- return import("./chunk-JUNZW2NI.js"), b`
3116
+ return import("./chunk-N27WNL5Q.js"), b`
3117
3117
  <sp-progress-circle
3118
3118
  size="s"
3119
3119
  indeterminate
@@ -3174,7 +3174,7 @@ var PickerBase = class extends SizedMixin(ExpandableElement, { noDefaultSize: tr
3174
3174
  renderOverlay(e14) {
3175
3175
  var s9;
3176
3176
  const t14 = this.renderContainer(e14);
3177
- return this.dependencyManager.add("sp-overlay"), import("./chunk-FFZJVWZQ.js"), b`
3177
+ return this.dependencyManager.add("sp-overlay"), import("./chunk-JCRICTXR.js"), b`
3178
3178
  <sp-overlay
3179
3179
  @slottable-request=${this.handleSlottableRequest}
3180
3180
  @beforetoggle=${this.handleBeforetoggle}
@@ -3255,7 +3255,7 @@ var PickerBase = class extends SizedMixin(ExpandableElement, { noDefaultSize: tr
3255
3255
  const t14 = b`
3256
3256
  ${this.dismissHelper} ${e14} ${this.dismissHelper}
3257
3257
  `;
3258
- return this.isMobile.matches && !this.forcePopover ? (this.dependencyManager.add("sp-tray"), import("./chunk-6JNYNXUQ.js"), b`
3258
+ return this.isMobile.matches && !this.forcePopover ? (this.dependencyManager.add("sp-tray"), import("./chunk-LR5GBIK7.js"), b`
3259
3259
  <sp-tray
3260
3260
  id="popover"
3261
3261
  role="presentation"
@@ -3488,7 +3488,7 @@ var Picker = class extends SizedMixin(ExpandableElement, { noDefaultSize: true }
3488
3488
  `;
3489
3489
  }
3490
3490
  renderLoader() {
3491
- return import("./chunk-JUNZW2NI.js"), b`
3491
+ return import("./chunk-N27WNL5Q.js"), b`
3492
3492
  <sp-progress-circle
3493
3493
  size="s"
3494
3494
  indeterminate
@@ -3549,7 +3549,7 @@ var Picker = class extends SizedMixin(ExpandableElement, { noDefaultSize: true }
3549
3549
  renderOverlay(e14) {
3550
3550
  var s9;
3551
3551
  const t14 = this.renderContainer(e14);
3552
- return this.dependencyManager.add("sp-overlay"), import("./chunk-FFZJVWZQ.js"), b`
3552
+ return this.dependencyManager.add("sp-overlay"), import("./chunk-JCRICTXR.js"), b`
3553
3553
  <sp-overlay
3554
3554
  @slottable-request=${this.handleSlottableRequest}
3555
3555
  @beforetoggle=${this.handleBeforetoggle}
@@ -3630,7 +3630,7 @@ var Picker = class extends SizedMixin(ExpandableElement, { noDefaultSize: true }
3630
3630
  const t14 = b`
3631
3631
  ${this.dismissHelper} ${e14} ${this.dismissHelper}
3632
3632
  `;
3633
- return this.isMobile.matches && !this.forcePopover ? (this.dependencyManager.add("sp-tray"), import("./chunk-6JNYNXUQ.js"), b`
3633
+ return this.isMobile.matches && !this.forcePopover ? (this.dependencyManager.add("sp-tray"), import("./chunk-LR5GBIK7.js"), b`
3634
3634
  <sp-tray
3635
3635
  id="popover"
3636
3636
  role="presentation"
@@ -3915,7 +3915,7 @@ var ActionMenu = class extends ObserveSlotPresence(ObserveSlotText(SizedMixin(Ex
3915
3915
  `;
3916
3916
  }
3917
3917
  renderLoader() {
3918
- return import("./chunk-JUNZW2NI.js"), b`
3918
+ return import("./chunk-N27WNL5Q.js"), b`
3919
3919
  <sp-progress-circle
3920
3920
  size="s"
3921
3921
  indeterminate
@@ -3948,7 +3948,7 @@ var ActionMenu = class extends ObserveSlotPresence(ObserveSlotText(SizedMixin(Ex
3948
3948
  renderOverlay(e14) {
3949
3949
  var s9;
3950
3950
  const t14 = this.renderContainer(e14);
3951
- return this.dependencyManager.add("sp-overlay"), import("./chunk-FFZJVWZQ.js"), b`
3951
+ return this.dependencyManager.add("sp-overlay"), import("./chunk-JCRICTXR.js"), b`
3952
3952
  <sp-overlay
3953
3953
  @slottable-request=${this.handleSlottableRequest}
3954
3954
  @beforetoggle=${this.handleBeforetoggle}
@@ -4027,7 +4027,7 @@ var ActionMenu = class extends ObserveSlotPresence(ObserveSlotText(SizedMixin(Ex
4027
4027
  const t14 = b`
4028
4028
  ${this.dismissHelper} ${e14} ${this.dismissHelper}
4029
4029
  `;
4030
- return this.isMobile.matches && !this.forcePopover ? (this.dependencyManager.add("sp-tray"), import("./chunk-6JNYNXUQ.js"), b`
4030
+ return this.isMobile.matches && !this.forcePopover ? (this.dependencyManager.add("sp-tray"), import("./chunk-LR5GBIK7.js"), b`
4031
4031
  <sp-tray
4032
4032
  id="popover"
4033
4033
  role="presentation"
@@ -4305,7 +4305,7 @@ var TruncatedValueTooltipController = class {
4305
4305
  return this.refreshTruncationState();
4306
4306
  }
4307
4307
  async ensureTooltipDeps() {
4308
- this._tooltipDepsLoaded || (await Promise.all([import("./chunk-FFZJVWZQ.js"), import("./chunk-6GSDEWD5.js")]), this._tooltipDepsLoaded = true, Promise.resolve().then(() => {
4308
+ this._tooltipDepsLoaded || (await Promise.all([import("./chunk-JCRICTXR.js"), import("./chunk-MJOCPOXZ.js")]), this._tooltipDepsLoaded = true, Promise.resolve().then(() => {
4309
4309
  this.host.requestUpdate(truncatedValueTooltipUpdatedSymbol, false);
4310
4310
  }));
4311
4311
  }
@@ -4995,6 +4995,49 @@ var IconContrast = class extends IconBase {
4995
4995
  // node_modules/@spectrum-web-components/icons-workflow/icons/sp-icon-contrast.js
4996
4996
  defineElement("sp-icon-contrast", IconContrast);
4997
4997
 
4998
+ // node_modules/@spectrum-web-components/icons-workflow/src/icons-s2/Edit.js
4999
+ var EditIcon = ({ width: t14 = 24, height: l10 = 24, hidden: e14 = false, title: r13 = "Edit" } = {}) => tag2`<svg
5000
+ xmlns="http://www.w3.org/2000/svg"
5001
+ width="${t14}"
5002
+ height="${l10}"
5003
+ viewBox="0 0 20 20"
5004
+ aria-hidden=${e14 ? "true" : "false"}
5005
+ role="img"
5006
+ fill="currentColor"
5007
+ aria-label="${r13}"
5008
+ >
5009
+ <path
5010
+ d="m17.78076,1.75684c-1.27197-1.04102-3.22705-.89844-4.4502.32324L3.07764,12.33398c-.32031.31934-.55859.7168-.68896,1.15039l-1.38428,4.58398c-.08008.26465-.00781.55176.1875.74707.14258.14258.33447.21973.53027.21973.07227,0,.14551-.01074.2168-.03223l4.58252-1.38379c.43359-.12988.83154-.36816,1.15088-.68848,0,0,10.16846-10.16797,10.35547-10.35547.64795-.64746.99316-1.54492.94775-2.45996-.0459-.91504-.48145-1.77539-1.19482-2.3584ZM2.84473,17.16309l.97998-3.24609c.02716-.09033.06714-.17578.11377-.25732l2.40869,2.40918c-.08154.04639-.16718.08643-.25781.11377l-3.24463.98047Zm14.12158-11.64746c-.15472.15552-7.09985,7.1001-9.52545,9.52588l-2.47461-2.4751L14.39111,3.14062c.38623-.38672.896-.58594,1.38965-.58594.38086,0,.75244.11914,1.05029.3623.3916.32129.62109.77246.646,1.27246.0249.49316-.16113.97656-.51074,1.32617Z"
5011
+ fill="currentColor"
5012
+ />
5013
+ </svg>`;
5014
+
5015
+ // node_modules/@spectrum-web-components/icons-workflow/src/icons/Edit.js
5016
+ var EditIcon2 = ({ width: t14 = 24, height: e14 = 24, hidden: a11 = false, title: l10 = "Edit" } = {}) => tag2`<svg
5017
+ xmlns="http://www.w3.org/2000/svg"
5018
+ height="${e14}"
5019
+ viewBox="0 0 36 36"
5020
+ width="${t14}"
5021
+ aria-hidden=${a11 ? "true" : "false"}
5022
+ role="img"
5023
+ fill="currentColor"
5024
+ aria-label="${l10}"
5025
+ >
5026
+ <path
5027
+ d="M33.567 8.2 27.8 2.432a1.215 1.215 0 0 0-.866-.353H26.9a1.371 1.371 0 0 0-.927.406L5.084 23.372a.99.99 0 0 0-.251.422L2.055 33.1c-.114.377.459.851.783.851a.251.251 0 0 0 .062-.007c.276-.063 7.866-2.344 9.311-2.778a.972.972 0 0 0 .414-.249l20.888-20.889a1.372 1.372 0 0 0 .4-.883 1.221 1.221 0 0 0-.346-.945ZM11.4 29.316c-2.161.649-4.862 1.465-6.729 2.022l2.009-6.73Z"
5028
+ />
5029
+ </svg>`;
5030
+
5031
+ // node_modules/@spectrum-web-components/icons-workflow/src/elements/IconEdit.js
5032
+ var IconEdit = class extends IconBase {
5033
+ render() {
5034
+ return setCustomTemplateLiteralTag2(b), this.spectrumVersion === 2 ? EditIcon({ hidden: !this.label, title: this.label }) : EditIcon2({ hidden: !this.label, title: this.label });
5035
+ }
5036
+ };
5037
+
5038
+ // node_modules/@spectrum-web-components/icons-workflow/icons/sp-icon-edit.js
5039
+ defineElement("sp-icon-edit", IconEdit);
5040
+
4998
5041
  // node_modules/@spectrum-web-components/icons-workflow/src/icons-s2/Filter.js
4999
5042
  var FilterIcon = ({ width: l10 = 24, height: t14 = 24, hidden: e14 = false, title: r13 = "Filter" } = {}) => tag2`<svg
5000
5043
  xmlns="http://www.w3.org/2000/svg"
@@ -5245,6 +5288,100 @@ var IconLightbulb = class extends IconBase {
5245
5288
  // node_modules/@spectrum-web-components/icons-workflow/icons/sp-icon-lightbulb.js
5246
5289
  defineElement("sp-icon-lightbulb", IconLightbulb);
5247
5290
 
5291
+ // node_modules/@spectrum-web-components/icons-workflow/src/icons-s2/SaveFloppy.js
5292
+ var SaveFloppyIcon = ({ width: e14 = 24, height: t14 = 24, hidden: l10 = false, title: r13 = "Save Floppy" } = {}) => tag2`<svg
5293
+ xmlns="http://www.w3.org/2000/svg"
5294
+ width="${e14}"
5295
+ height="${t14}"
5296
+ viewBox="0 0 20 20"
5297
+ aria-hidden=${l10 ? "true" : "false"}
5298
+ role="img"
5299
+ fill="currentColor"
5300
+ aria-label="${r13}"
5301
+ >
5302
+ <path
5303
+ d="M17.41406,4.10352l-1.51758-1.51758c-.37793-.37793-.87988-.58594-1.41406-.58594H4.25c-1.24072,0-2.25,1.00977-2.25,2.25v11.5c0,1.24023,1.00928,2.25,2.25,2.25h11.5c1.24072,0,2.25-1.00977,2.25-2.25V5.51758c0-.52637-.21338-1.04199-.58594-1.41406ZM7.75,3.5h4.5v3h-4.5v-3ZM13.25,16.5h-6.5v-4.5h6.5v4.5ZM16.5,15.75c0,.41309-.33643.75-.75.75h-1v-4.5c0-.82715-.67285-1.5-1.5-1.5h-6.5c-.82715,0-1.5.67285-1.5,1.5v4.5h-1c-.41357,0-.75-.33691-.75-.75V4.25c0-.41309.33643-.75.75-.75h2v3c0,.82715.67285,1.5,1.5,1.5h4.5c.82715,0,1.5-.67285,1.5-1.5v-3h.73242c.1333,0,.25879.05176.35352.14648l1.51758,1.51758c.09326.09277.14648.22168.14648.35352v10.23242Z"
5304
+ fill="currentColor"
5305
+ />
5306
+ </svg>`;
5307
+
5308
+ // node_modules/@spectrum-web-components/icons-workflow/src/icons/SaveFloppy.js
5309
+ var SaveFloppyIcon2 = ({ width: e14 = 24, height: t14 = 24, hidden: a11 = false, title: l10 = "Save Floppy" } = {}) => tag2`<svg
5310
+ xmlns="http://www.w3.org/2000/svg"
5311
+ height="${t14}"
5312
+ viewBox="0 0 36 36"
5313
+ width="${e14}"
5314
+ aria-hidden=${a11 ? "true" : "false"}
5315
+ role="img"
5316
+ fill="currentColor"
5317
+ aria-label="${l10}"
5318
+ >
5319
+ <path d="M20 4h4v6h-4z" />
5320
+ <path
5321
+ d="M31.708 8.293s-4.015-4-4.146-4.114A.969.969 0 0 0 27 4h-1v8H14V4H5a1 1 0 0 0-1 1v26a1 1 0 0 0 1 1h26a1 1 0 0 0 1-1V9a1 1 0 0 0-.292-.707ZM26 30H10V16h16Z"
5322
+ />
5323
+ </svg>`;
5324
+
5325
+ // node_modules/@spectrum-web-components/icons-workflow/src/elements/IconSaveFloppy.js
5326
+ var IconSaveFloppy = class extends IconBase {
5327
+ render() {
5328
+ return setCustomTemplateLiteralTag2(b), this.spectrumVersion === 2 ? SaveFloppyIcon({ hidden: !this.label, title: this.label }) : SaveFloppyIcon2({ hidden: !this.label, title: this.label });
5329
+ }
5330
+ };
5331
+
5332
+ // node_modules/@spectrum-web-components/icons-workflow/icons/sp-icon-save-floppy.js
5333
+ defineElement("sp-icon-save-floppy", IconSaveFloppy);
5334
+
5335
+ // node_modules/@spectrum-web-components/icons-workflow/src/icons-s2/OpenIn.js
5336
+ var OpenInIcon = ({ width: e14 = 24, height: t14 = 24, hidden: l10 = false, title: r13 = "Open In" } = {}) => tag2`<svg
5337
+ xmlns="http://www.w3.org/2000/svg"
5338
+ width="${e14}"
5339
+ height="${t14}"
5340
+ viewBox="0 0 20 20"
5341
+ aria-hidden=${l10 ? "true" : "false"}
5342
+ role="img"
5343
+ fill="currentColor"
5344
+ aria-label="${r13}"
5345
+ >
5346
+ <path
5347
+ d="m18,15.75V4.25c0-1.24072-1.00928-2.25-2.25-2.25H4.25c-1.24072,0-2.25,1.00928-2.25,2.25v3.71777c0,.41406.33594.75.75.75s.75-.33594.75-.75v-3.71777c0-.41357.33643-.75.75-.75h11.5c.41357,0,.75.33643.75.75v11.5c0,.41357-.33643.75-.75.75h-3.81104c-.41406,0-.75.33594-.75.75s.33594.75.75.75h3.81104c1.24072,0,2.25-1.00928,2.25-2.25Z"
5348
+ fill="currentColor"
5349
+ />
5350
+ <path
5351
+ d="m11,9.75v4.24268c0,.41406-.33594.75-.75.75s-.75-.33594-.75-.75v-2.43213l-6.46973,6.46973c-.14648.14648-.33838.21973-.53027.21973s-.38379-.07324-.53027-.21973c-.29297-.29297-.29297-.76758,0-1.06055l6.46973-6.46973h-2.43213c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75h4.24268c.41406,0,.75.33594.75.75Z"
5352
+ fill="currentColor"
5353
+ />
5354
+ </svg>`;
5355
+
5356
+ // node_modules/@spectrum-web-components/icons-workflow/src/icons/OpenIn.js
5357
+ var OpenInIcon2 = ({ width: a11 = 24, height: e14 = 24, hidden: t14 = false, title: l10 = "Open In" } = {}) => tag2`<svg
5358
+ xmlns="http://www.w3.org/2000/svg"
5359
+ width="${a11}"
5360
+ height="${e14}"
5361
+ viewBox="0 0 36 36"
5362
+ aria-hidden=${t14 ? "true" : "false"}
5363
+ role="img"
5364
+ fill="currentColor"
5365
+ aria-label="${l10}"
5366
+ >
5367
+ <path
5368
+ d="M33 2H3a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V6h24v24H19a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1Z"
5369
+ />
5370
+ <path
5371
+ d="M18.636 27.764a.784.784 0 0 0 .56.236.803.803 0 0 0 .804-.754v-10.75a.497.497 0 0 0-.496-.496H8.754a.803.803 0 0 0-.754.804.785.785 0 0 0 .235.56l3.786 3.786-9.042 9.042a1 1 0 0 0 0 1.415l1.414 1.414a1 1 0 0 0 1.414 0l9.043-9.042Z"
5372
+ />
5373
+ </svg>`;
5374
+
5375
+ // node_modules/@spectrum-web-components/icons-workflow/src/elements/IconOpenIn.js
5376
+ var IconOpenIn = class extends IconBase {
5377
+ render() {
5378
+ return setCustomTemplateLiteralTag2(b), this.spectrumVersion === 2 ? OpenInIcon({ hidden: !this.label, title: this.label }) : OpenInIcon2({ hidden: !this.label, title: this.label });
5379
+ }
5380
+ };
5381
+
5382
+ // node_modules/@spectrum-web-components/icons-workflow/icons/sp-icon-open-in.js
5383
+ defineElement("sp-icon-open-in", IconOpenIn);
5384
+
5248
5385
  // node_modules/@spectrum-web-components/icons-workflow/src/icons-s2/GlobeGrid.js
5249
5386
  var GlobeGridIcon = ({ width: e14 = 24, height: t14 = 24, hidden: r13 = false, title: l10 = "Globe Grid" } = {}) => tag2`<svg
5250
5387
  xmlns="http://www.w3.org/2000/svg"
@@ -5981,6 +6118,45 @@ var u8 = n7(b);
5981
6118
  var c9 = n7(w);
5982
6119
  var $2 = n7(T);
5983
6120
 
6121
+ // src/app/dips.ts
6122
+ var dipType = "application/x-slicc-sprinkle";
6123
+ var Dips = class extends Emitter {
6124
+ key = "slicc-ui.dips";
6125
+ #out = /* @__PURE__ */ new Set();
6126
+ #storage = null;
6127
+ load(storage) {
6128
+ this.#storage = storage;
6129
+ try {
6130
+ const saved = JSON.parse(storage?.getItem(this.key) ?? "[]");
6131
+ this.#out = new Set(Array.isArray(saved) ? saved.filter((id) => typeof id === "string") : []);
6132
+ } catch {
6133
+ this.#out = /* @__PURE__ */ new Set();
6134
+ }
6135
+ this.emit("change", this.list());
6136
+ }
6137
+ list() {
6138
+ return [...this.#out];
6139
+ }
6140
+ has(id) {
6141
+ return this.#out.has(id);
6142
+ }
6143
+ detach(id) {
6144
+ if (this.#out.has(id)) return;
6145
+ this.#out.add(id);
6146
+ this.#storage?.setItem(this.key, JSON.stringify(this.list()));
6147
+ this.emit("change", this.list());
6148
+ }
6149
+ };
6150
+ function dipsOf(node) {
6151
+ let current = node;
6152
+ while (current) {
6153
+ const found = current.dips;
6154
+ if (found instanceof Dips) return found;
6155
+ current = current.parentNode ?? current.host ?? null;
6156
+ }
6157
+ return null;
6158
+ }
6159
+
5984
6160
  // src/app/fonts.ts
5985
6161
  var adobeClean = [
5986
6162
  ["Regular", 400],
@@ -6204,13 +6380,17 @@ var SliccFileView = class extends ThemedElement {
6204
6380
  ...ThemedElement.properties,
6205
6381
  path: {},
6206
6382
  text: { state: true },
6207
- missing: { state: true }
6383
+ missing: { state: true },
6384
+ draft: { state: true },
6385
+ saving: { state: true }
6208
6386
  };
6209
6387
  constructor() {
6210
6388
  super();
6211
6389
  this.path = "";
6212
6390
  this.text = null;
6213
6391
  this.missing = false;
6392
+ this.draft = null;
6393
+ this.saving = false;
6214
6394
  }
6215
6395
  static styles = [
6216
6396
  shared,
@@ -6220,8 +6400,81 @@ var SliccFileView = class extends ThemedElement {
6220
6400
  flex: 1;
6221
6401
  min-height: 0;
6222
6402
  }
6403
+ textarea {
6404
+ flex: 1;
6405
+ min-height: 0;
6406
+ margin: 0;
6407
+ padding: 8px 12px;
6408
+ border: 0;
6409
+ resize: none;
6410
+ outline: none;
6411
+ background: var(--spectrum-background-layer-2-color);
6412
+ color: var(--spectrum-neutral-content-color-default);
6413
+ font-family: var(--spectrum-code-font-family-stack, ui-monospace, monospace);
6414
+ font-size: 13px;
6415
+ line-height: 20px;
6416
+ tab-size: 2;
6417
+ }
6223
6418
  `
6224
6419
  ];
6420
+ edit() {
6421
+ this.draft = this.text ?? "";
6422
+ this.focusOn("textarea");
6423
+ }
6424
+ cancel() {
6425
+ this.draft = null;
6426
+ }
6427
+ async save() {
6428
+ const model = this.model;
6429
+ if (!model || this.draft === null) return;
6430
+ const draft = this.draft;
6431
+ this.saving = true;
6432
+ try {
6433
+ await model.files.write(this.path, draft);
6434
+ this.text = draft;
6435
+ this.missing = false;
6436
+ if (this.draft === draft) this.draft = null;
6437
+ } finally {
6438
+ this.saving = false;
6439
+ }
6440
+ }
6441
+ #keydown(event) {
6442
+ if (event.key === "Escape") {
6443
+ event.preventDefault();
6444
+ this.cancel();
6445
+ } else if (event.key === "s" && (event.metaKey || event.ctrlKey)) {
6446
+ event.preventDefault();
6447
+ void this.save();
6448
+ }
6449
+ }
6450
+ #actions() {
6451
+ if (this.draft === null) {
6452
+ return b`<sp-action-button size="s" quiet ?disabled=${this.text === null} @click=${() => this.edit()}>
6453
+ <sp-icon-edit slot="icon"></sp-icon-edit>Edit
6454
+ </sp-action-button>`;
6455
+ }
6456
+ return b`<sp-action-button size="s" quiet @click=${() => this.cancel()}>Cancel</sp-action-button>
6457
+ <sp-action-button size="s" ?disabled=${this.saving} @click=${() => this.save()}>
6458
+ <sp-icon-save-floppy slot="icon"></sp-icon-save-floppy>Save
6459
+ </sp-action-button>`;
6460
+ }
6461
+ #body(change) {
6462
+ if (this.draft !== null) {
6463
+ return b`<textarea
6464
+ aria-label=${`Edit ${this.path}`}
6465
+ spellcheck="false"
6466
+ .value=${this.draft}
6467
+ @input=${(event) => {
6468
+ this.draft = event.target.value;
6469
+ }}
6470
+ @keydown=${this.#keydown}
6471
+ ></textarea>`;
6472
+ }
6473
+ if (this.missing) {
6474
+ return b`<div class="note">This file doesn’t exist${change ? " any more" : ""}.</div>`;
6475
+ }
6476
+ return b`<slicc-code-view path=${this.path} color=${this.color} .contents=${this.text}></slicc-code-view>`;
6477
+ }
6225
6478
  subscribe(model) {
6226
6479
  void this.#read(model);
6227
6480
  return [
@@ -6251,8 +6504,9 @@ var SliccFileView = class extends ThemedElement {
6251
6504
  <sp-action-button size="s" quiet @click=${() => request(this, "open-diff", this.path)}>
6252
6505
  <sp-icon-compare slot="icon"></sp-icon-compare>Diff
6253
6506
  </sp-action-button>` : A}
6507
+ ${this.#actions()}
6254
6508
  </div>
6255
- ${this.missing ? b`<div class="note">This file doesn’t exist${change ? " any more" : ""}.</div>` : b`<slicc-code-view path=${this.path} color=${this.color} .contents=${this.text}></slicc-code-view>`}`;
6509
+ ${this.#body(change)}`;
6256
6510
  }
6257
6511
  };
6258
6512
 
@@ -6354,8 +6608,8 @@ function screenClass(width) {
6354
6608
  if (width < 1200) return "tablet";
6355
6609
  return "desktop";
6356
6610
  }
6357
- function surface(id) {
6358
- return surfaces.find((candidate) => candidate.id === id);
6611
+ function surface(id, items = surfaces) {
6612
+ return items.find((candidate) => candidate.id === id);
6359
6613
  }
6360
6614
  function create(tag3, model, params = {}) {
6361
6615
  const element2 = document.createElement(tag3);
@@ -6406,11 +6660,39 @@ function openSurface(dock, item2, screen) {
6406
6660
  ...fresh && item2.width && screen !== "phone" ? { initialWidth: item2.width } : {}
6407
6661
  });
6408
6662
  }
6663
+ function chatId(agentId) {
6664
+ return `chat:${agentId}`;
6665
+ }
6666
+ function chatAgent(id) {
6667
+ return id?.startsWith("chat:") ? id.slice(5) : null;
6668
+ }
6669
+ function chats(dock) {
6670
+ return dock.api.panels.map((panel) => panel.id).filter((id) => chatAgent(id) !== null);
6671
+ }
6672
+ function openChat(dock, agent, screen, focus = true) {
6673
+ const id = chatId(agent.id);
6674
+ if (!dock.has(id)) {
6675
+ const sibling = chats(dock)[0];
6676
+ const place = sibling ? { position: { referencePanel: sibling, direction: "within" } } : placement(dock, "center", screen);
6677
+ dock.open({
6678
+ id,
6679
+ component: "chat",
6680
+ title: agent.name,
6681
+ params: { agent: agent.id },
6682
+ inactive: !focus,
6683
+ ...place
6684
+ });
6685
+ }
6686
+ if (focus) dock.focusPanel(id);
6687
+ else dock.reveal(id);
6688
+ return id;
6689
+ }
6409
6690
  function openDocument(dock, kind, path, screen) {
6410
6691
  const id = `${kind}:${path}`;
6411
6692
  if (!dock.has(id)) {
6412
6693
  const sibling = dock.api.panels.find((panel) => /^(file|diff):/.test(panel.id));
6413
- const place = sibling ? { position: { referencePanel: sibling.id, direction: "within" } } : dock.has("chat") && screen !== "phone" ? { position: { referencePanel: "chat", direction: "right" } } : placement(dock, "center", screen);
6694
+ const chat = chats(dock)[0];
6695
+ const place = sibling ? { position: { referencePanel: sibling.id, direction: "within" } } : chat && screen !== "phone" ? { position: { referencePanel: chat, direction: "right" } } : placement(dock, "center", screen);
6414
6696
  dock.open({
6415
6697
  id,
6416
6698
  component: kind,
@@ -6422,18 +6704,23 @@ function openDocument(dock, kind, path, screen) {
6422
6704
  dock.focusPanel(id);
6423
6705
  return id;
6424
6706
  }
6425
- function defaultLayout(dock, screen) {
6707
+ function defaultLayout(dock, screen, agent, items = surfaces) {
6426
6708
  dock.clear();
6427
6709
  const order = ["center", "left", "right"];
6428
6710
  for (const side of order) {
6429
- for (const item2 of surfaces) {
6430
- if (item2.side === side && item2.open.includes(screen)) openSurface(dock, item2, screen);
6711
+ for (const item2 of items) {
6712
+ if (item2.side !== side || !item2.open.includes(screen)) continue;
6713
+ if (item2.id !== "chat") openSurface(dock, item2, screen);
6714
+ else if (agent) openChat(dock, agent, screen, false);
6431
6715
  }
6432
6716
  }
6433
- dock.api.getPanel("chat")?.api.setActive();
6717
+ const chat = chats(dock)[0];
6718
+ if (chat) dock.api.getPanel(chat)?.api.setActive();
6434
6719
  }
6435
- function closed(dock) {
6436
- return surfaces.filter((item2) => !dock.has(item2.id));
6720
+ function closed(dock, items = surfaces) {
6721
+ return items.filter(
6722
+ (item2) => item2.id === "chat" ? chats(dock).length === 0 : !dock.has(item2.id)
6723
+ );
6437
6724
  }
6438
6725
  function sprinkleSurface(sprinkle) {
6439
6726
  return {
@@ -6445,7 +6732,17 @@ function sprinkleSurface(sprinkle) {
6445
6732
  open: []
6446
6733
  };
6447
6734
  }
6448
- function openSprinkle(dock, sprinkle, screen) {
6735
+ var directions = {
6736
+ left: "left",
6737
+ right: "right",
6738
+ top: "above",
6739
+ bottom: "below",
6740
+ center: "within"
6741
+ };
6742
+ function dropPlacement(panel, position) {
6743
+ return panel ? { position: { referencePanel: panel, direction: directions[position] ?? "within" } } : null;
6744
+ }
6745
+ function openSprinkle(dock, sprinkle, screen, place = null) {
6449
6746
  const id = `sprinkle:${sprinkle.id}`;
6450
6747
  if (!dock.has(id)) {
6451
6748
  dock.open({
@@ -6453,7 +6750,7 @@ function openSprinkle(dock, sprinkle, screen) {
6453
6750
  component: "sprinkle",
6454
6751
  title: sprinkle.title,
6455
6752
  params: { sprinkle: sprinkle.id },
6456
- ...placement(dock, "right", screen)
6753
+ ...place ?? placement(dock, "right", screen)
6457
6754
  });
6458
6755
  }
6459
6756
  dock.focusPanel(id);
@@ -6468,9 +6765,14 @@ function railIcon(icon) {
6468
6765
  return b`<slicc-lucide slot="icon" name=${icon}></slicc-lucide>`;
6469
6766
  }
6470
6767
  var SliccApp = class extends ThemedElement {
6471
- static properties = { ...ThemedElement.properties, screen: { reflect: true } };
6768
+ static properties = {
6769
+ ...ThemedElement.properties,
6770
+ screen: { reflect: true },
6771
+ surfaces: { attribute: false }
6772
+ };
6472
6773
  storage = globalThis.localStorage ?? null;
6473
- layoutKey = "slicc-ui.layout";
6774
+ layoutKey = "slicc-ui.layout.v2";
6775
+ dips = new Dips();
6474
6776
  #fontBase = defaultFontBase;
6475
6777
  #resize = null;
6476
6778
  #started = null;
@@ -6478,6 +6780,7 @@ var SliccApp = class extends ThemedElement {
6478
6780
  constructor() {
6479
6781
  super();
6480
6782
  this.screen = screenClass(globalThis.innerWidth ?? 1280);
6783
+ this.surfaces = surfaces;
6481
6784
  }
6482
6785
  static styles = [
6483
6786
  shared,
@@ -6512,6 +6815,11 @@ var SliccApp = class extends ThemedElement {
6512
6815
  box-sizing: border-box;
6513
6816
  background: var(--spectrum-background-layer-1-color);
6514
6817
  }
6818
+ .rail.drop {
6819
+ background: var(--spectrum-accent-background-color-default);
6820
+ outline: 2px solid var(--spectrum-focus-indicator-color);
6821
+ outline-offset: -2px;
6822
+ }
6515
6823
  .rail.left {
6516
6824
  grid-column: 1;
6517
6825
  border-right: 1px solid var(--spectrum-gray-200);
@@ -6620,10 +6928,20 @@ var SliccApp = class extends ThemedElement {
6620
6928
  const update = () => this.requestUpdate();
6621
6929
  return [
6622
6930
  ...super.subscribe(model),
6623
- model.agent.on("agents", update),
6624
- model.agent.on("active", update),
6931
+ model.agent.on("agents", () => {
6932
+ this.#prune();
6933
+ update();
6934
+ }),
6935
+ model.agent.on("active", () => {
6936
+ const agent = this.#active();
6937
+ if (this.#started && agent && this.#offers("chat")) {
6938
+ openChat(this.dock, agent, this.screen, false);
6939
+ }
6940
+ update();
6941
+ }),
6625
6942
  model.files.on("changes", update),
6626
- model.sprinkles.on("sprinkles", update)
6943
+ model.sprinkles.on("sprinkles", update),
6944
+ this.dips.on("change", update)
6627
6945
  ];
6628
6946
  }
6629
6947
  connectedCallback() {
@@ -6665,21 +6983,31 @@ var SliccApp = class extends ThemedElement {
6665
6983
  const dock = this.dock;
6666
6984
  this.#saving = false;
6667
6985
  dock.factories = {
6668
- ...Object.fromEntries(surfaces.map((item2) => [item2.id, () => create(item2.tag, model)])),
6986
+ ...Object.fromEntries(this.surfaces.map((item2) => [item2.id, () => create(item2.tag, model)])),
6669
6987
  ...Object.fromEntries(
6670
6988
  Object.entries(documents).map(([kind, document2]) => [
6671
6989
  kind,
6672
6990
  (params) => create(document2.tag, model, params)
6673
6991
  ])
6674
6992
  ),
6993
+ ...this.#offers("chat") ? { chat: (params) => create("slicc-chat", model, params) } : {},
6675
6994
  sprinkle: (params) => create("slicc-sprinkle", model, params)
6676
6995
  };
6677
- const restored = dock.restore(this.#saved());
6678
- if (!restored) defaultLayout(dock, this.screen);
6996
+ dock.accepts = [dipType];
6997
+ this.dips.load(this.storage);
6998
+ const saved = this.#saved();
6999
+ const restored = this.#offered(saved, dock.factories) && dock.restore(saved);
7000
+ if (!restored) defaultLayout(dock, this.screen, this.#active(), this.surfaces);
6679
7001
  this.#started = this.screen;
7002
+ this.#prune();
6680
7003
  this.#saving = true;
6681
7004
  this.#save();
6682
7005
  }
7006
+ #offered(layout, factories) {
7007
+ return Object.values(layout?.panels ?? {}).every(
7008
+ (panel) => (panel.contentComponent ?? "") in factories
7009
+ );
7010
+ }
6683
7011
  get storageKey() {
6684
7012
  return `${this.layoutKey}.${this.screen}`;
6685
7013
  }
@@ -6694,30 +7022,79 @@ var SliccApp = class extends ThemedElement {
6694
7022
  if (this.#saving) this.storage?.setItem(this.storageKey, JSON.stringify(this.dock.toJSON()));
6695
7023
  this.requestUpdate();
6696
7024
  }
7025
+ #active() {
7026
+ const model = this.model;
7027
+ return model?.agent.list().find((agent) => agent.id === model.agent.active()) ?? null;
7028
+ }
7029
+ #prune() {
7030
+ const dock = this.renderRoot.querySelector("slicc-dock");
7031
+ if (!dock || !this.#started) return;
7032
+ const known = new Set(this.model?.agent.list().map((agent) => agent.id));
7033
+ for (const id of chats(dock)) {
7034
+ if (!known.has(chatAgent(id))) dock.close(id);
7035
+ }
7036
+ }
7037
+ #activated(event) {
7038
+ const agent = chatAgent(event.detail.id);
7039
+ if (agent && agent !== this.model?.agent.active()) this.model?.agent.select(agent);
7040
+ }
6697
7041
  resetLayout() {
6698
- defaultLayout(this.dock, this.screen);
7042
+ defaultLayout(this.dock, this.screen, this.#active(), this.surfaces);
6699
7043
  this.#save();
6700
7044
  }
6701
7045
  show(id) {
7046
+ const agent = this.#active();
7047
+ if (id === "chat" && agent && this.#offers("chat")) {
7048
+ openChat(this.dock, agent, this.screen);
7049
+ return;
7050
+ }
6702
7051
  const sprinkle = this.model?.sprinkles.list().find((candidate) => `sprinkle:${candidate.id}` === id);
6703
7052
  if (sprinkle) {
6704
7053
  openSprinkle(this.dock, sprinkle, this.screen);
6705
7054
  return;
6706
7055
  }
6707
- const item2 = surface(id);
7056
+ const item2 = surface(id, this.surfaces);
6708
7057
  if (!item2) return;
6709
7058
  openSurface(this.dock, item2, this.screen);
6710
7059
  this.dock.focusPanel(id);
6711
7060
  }
7061
+ #sprinkle(id) {
7062
+ return this.model?.sprinkles.list().find((candidate) => candidate.id === id);
7063
+ }
7064
+ #detach(id, place, open) {
7065
+ const sprinkle = this.#sprinkle(id);
7066
+ if (!sprinkle) return;
7067
+ this.dips.detach(id);
7068
+ if (open) openSprinkle(this.dock, sprinkle, this.screen, place);
7069
+ }
7070
+ #dropped(event) {
7071
+ const { type, data, panel, position } = event.detail;
7072
+ if (type === dipType) this.#detach(data, dropPlacement(panel, position), true);
7073
+ }
7074
+ #railOver(event) {
7075
+ if (!event.dataTransfer?.types.includes(dipType)) return;
7076
+ event.preventDefault();
7077
+ event.currentTarget.classList.add("drop");
7078
+ }
7079
+ #railLeave(event) {
7080
+ event.currentTarget.classList.remove("drop");
7081
+ }
7082
+ #railDrop(event) {
7083
+ event.currentTarget.classList.remove("drop");
7084
+ const id = event.dataTransfer?.getData(dipType);
7085
+ if (!id) return;
7086
+ event.preventDefault();
7087
+ this.#detach(id, null, false);
7088
+ }
6712
7089
  #rail(items, side) {
6713
- return b`<nav class=${`rail ${side}`} aria-label=${`Closed panels, ${side}`}>${items.map(
7090
+ return b`<nav class=${`rail ${side}`} aria-label=${`Closed panels, ${side}`} @dragover=${this.#railOver} @dragleave=${this.#railLeave} @drop=${this.#railDrop}>${items.map(
6714
7091
  (item2) => u8`<sp-action-button quiet size="m" label=${`Open ${item2.title}`} title=${item2.title} data-surface=${item2.id} @click=${() => this.show(item2.id)}>${railIcon(item2.icon)}</sp-action-button>`
6715
7092
  )}</nav>`;
6716
7093
  }
6717
7094
  #rails() {
6718
7095
  const dock = this.renderRoot.querySelector("slicc-dock");
6719
- const sprinkles = (this.model?.sprinkles.list() ?? []).filter((sprinkle) => !sprinkle.inline).map(sprinkleSurface).filter((item2) => !dock?.has(item2.id));
6720
- const shut = dock && this.#started ? [...sprinkles, ...closed(dock)] : [];
7096
+ const sprinkles = (this.model?.sprinkles.list() ?? []).filter((sprinkle) => !sprinkle.inline || this.dips.has(sprinkle.id)).map(sprinkleSurface).filter((item2) => !dock?.has(item2.id));
7097
+ const shut = dock && this.#started ? [...sprinkles, ...closed(dock, this.surfaces)] : [];
6721
7098
  const phone = this.screen === "phone";
6722
7099
  return {
6723
7100
  left: this.#rail(phone ? [] : shut.filter((item2) => item2.side !== "right"), "left"),
@@ -6738,7 +7115,7 @@ var SliccApp = class extends ThemedElement {
6738
7115
  #keydown = (event) => {
6739
7116
  if (!event.altKey || event.ctrlKey || event.metaKey) return;
6740
7117
  const digit = event.code.match(/^Digit([1-9])$/)?.[1] ?? event.key.match(/^[1-9]$/)?.[0];
6741
- const surface2 = digit ? surfaces[Number(digit) - 1] : void 0;
7118
+ const surface2 = digit ? this.surfaces[Number(digit) - 1] : void 0;
6742
7119
  if (surface2) {
6743
7120
  event.preventDefault();
6744
7121
  this.show(surface2.id);
@@ -6760,21 +7137,33 @@ var SliccApp = class extends ThemedElement {
6760
7137
  ${surface2.title}<kbd slot="value">Alt+${index + 1}</kbd>
6761
7138
  </sp-menu-item>`;
6762
7139
  }
6763
- #status() {
7140
+ #offers(id) {
7141
+ return this.surfaces.some((item2) => item2.id === id);
7142
+ }
7143
+ #agentStatus() {
7144
+ if (!this.#offers("chat")) return A;
6764
7145
  const model = this.model;
6765
7146
  const agent = model?.agent.list().find((candidate) => candidate.id === model.agent.active());
6766
7147
  const label = model?.settings.models().find((option2) => option2.id === agent?.model)?.label;
6767
- const changes = model?.files.changes().length ?? 0;
6768
- return b`<footer role="status" aria-label="Status">
6769
- ${agent ? b`<span class="item">${dot(agent.status)}${agent.name} · ${agent.status}</span>
7148
+ return agent ? b`<span class="item">${dot(agent.status)}${agent.name} · ${agent.status}</span>
6770
7149
  <span>${label ?? agent.model}</span>
6771
7150
  <span class="item" title="Context fill"
6772
7151
  >Context <span class="bar"><span style=${`width: ${percent(agent.contextFill)}`}></span></span>
6773
7152
  ${percent(agent.contextFill)}</span
6774
- >` : b`<span>No agent</span>`}
6775
- <button class="link" @click=${() => this.show("changes")}>${changes} ${changes === 1 ? "change" : "changes"}</button>
7153
+ >` : b`<span>No agent</span>`;
7154
+ }
7155
+ #changes() {
7156
+ if (!this.#offers("changes")) return A;
7157
+ const changes = this.model?.files.changes().length ?? 0;
7158
+ return b`<button class="link" @click=${() => this.show("changes")}>${changes} ${changes === 1 ? "change" : "changes"}</button>`;
7159
+ }
7160
+ #status() {
7161
+ return b`<footer role="status" aria-label="Status">
7162
+ ${this.#agentStatus()}
7163
+ ${this.#changes()}
7164
+ <slot name="status"></slot>
6776
7165
  <span class="spacer"></span>
6777
- <span class="hints"><kbd>F6</kbd> next group · <kbd>Alt+1–${Math.min(9, surfaces.length)}</kbd> panels · <kbd>Alt+Shift+T</kbd> theme</span>
7166
+ <span class="hints"><kbd>F6</kbd> next group · <kbd>Alt+1–${Math.min(9, this.surfaces.length)}</kbd> panels · <kbd>Alt+Shift+T</kbd> theme</span>
6778
7167
  </footer>`;
6779
7168
  }
6780
7169
  render() {
@@ -6785,23 +7174,23 @@ var SliccApp = class extends ThemedElement {
6785
7174
  <div class="shell">
6786
7175
  <header>
6787
7176
  <span class="brand">slicc</span>
6788
- <sp-picker size="s" label="Agent" value=${this.model?.agent.active() ?? ""} @change=${this.#pick}>
7177
+ ${this.#offers("chat") ? b`<sp-picker size="s" label="Agent" value=${this.model?.agent.active() ?? ""} @change=${this.#pick}>
6789
7178
  ${agents.map(
6790
7179
  (agent) => b`<sp-menu-item value=${agent.id}>${agent.kind === "scoop" ? `\u21B3 ${agent.name}` : agent.name}</sp-menu-item>`
6791
7180
  )}
6792
- </sp-picker>
7181
+ </sp-picker>` : A}
6793
7182
  <span class="spacer"></span>
6794
- <slicc-tray .model=${this.model}></slicc-tray>
7183
+ ${this.#offers("chat") ? b`<slicc-tray .model=${this.model}></slicc-tray>` : A}
6795
7184
  <sp-action-menu size="s" quiet label="View" @change=${this.#view}>
6796
7185
  <sp-icon-view-grid slot="icon"></sp-icon-view-grid>
6797
7186
  <span slot="label">View</span>
6798
- ${surfaces.map((surface2, index) => this.#menuItem(surface2, index))}
7187
+ ${this.surfaces.map((surface2, index) => this.#menuItem(surface2, index))}
6799
7188
  <sp-menu-divider></sp-menu-divider>
6800
7189
  <sp-menu-item value="reset">Reset layout</sp-menu-item>
6801
7190
  </sp-action-menu>
6802
- <sp-action-button size="s" quiet label="Settings" title="Settings" @click=${() => this.show("settings")}>
7191
+ ${this.#offers("settings") ? b`<sp-action-button size="s" quiet label="Settings" title="Settings" @click=${() => this.show("settings")}>
6803
7192
  <sp-icon-settings slot="icon"></sp-icon-settings>
6804
- </sp-action-button>
7193
+ </sp-action-button>` : A}
6805
7194
  <sp-action-button
6806
7195
  size="s"
6807
7196
  quiet
@@ -6814,6 +7203,9 @@ var SliccApp = class extends ThemedElement {
6814
7203
  <main>
6815
7204
  ${rails.left}
6816
7205
  <slicc-dock empty-text="All panels are closed. Open one from a rail or View." @layout-change=${this.#save}
7206
+ @active-panel-change=${this.#activated}
7207
+ @external-drop=${this.#dropped}
7208
+ @detach-sprinkle=${(event) => this.#detach(event.detail.id, null, true)}
6817
7209
  @open-file=${(event) => this.#request("file", event)}
6818
7210
  @open-diff=${(event) => this.#request("diff", event)}
6819
7211
  @show-surface=${(event) => this.show(event.detail.id)}
@@ -8222,6 +8614,11 @@ var messageCss = i`
8222
8614
 
8223
8615
  // src/app/chat.ts
8224
8616
  var SliccChat = class extends ThemedElement {
8617
+ static properties = { ...ThemedElement.properties, agent: {} };
8618
+ constructor() {
8619
+ super();
8620
+ this.agent = "";
8621
+ }
8225
8622
  static styles = [
8226
8623
  shared,
8227
8624
  messageCss,
@@ -8274,8 +8671,8 @@ var SliccChat = class extends ThemedElement {
8274
8671
  #handlers = {
8275
8672
  color: "light",
8276
8673
  model: null,
8277
- answer: (questionId, answer) => this.model?.agent.answer(this.model.agent.active(), questionId, answer),
8278
- resolve: (messageId, state) => this.model?.agent.resolveLick(this.model.agent.active(), messageId, state),
8674
+ answer: (questionId, answer) => this.model?.agent.answer(this.#id(), questionId, answer),
8675
+ resolve: (messageId, state) => this.model?.agent.resolveLick(this.#id(), messageId, state),
8279
8676
  action: (action) => this.#action(action),
8280
8677
  open: (path) => this.dispatchEvent(
8281
8678
  new CustomEvent("open-file", { detail: { path }, bubbles: true, composed: true })
@@ -8284,13 +8681,15 @@ var SliccChat = class extends ThemedElement {
8284
8681
  subscribe(model) {
8285
8682
  return [
8286
8683
  ...super.subscribe(model),
8287
- model.agent.on("active", () => this.#refresh(true)),
8684
+ model.agent.on("active", () => {
8685
+ if (!this.agent) this.#refresh(true);
8686
+ }),
8288
8687
  model.agent.on("agents", () => this.requestUpdate()),
8289
8688
  model.agent.on("messages", (agentId) => {
8290
- if (agentId === model.agent.active()) this.#refresh(true);
8689
+ if (agentId === this.#id()) this.#refresh(true);
8291
8690
  }),
8292
8691
  model.agent.on("message", ({ agentId }) => {
8293
- if (agentId === model.agent.active()) this.#refresh(false);
8692
+ if (agentId === this.#id()) this.#refresh(false);
8294
8693
  })
8295
8694
  ];
8296
8695
  }
@@ -8309,14 +8708,17 @@ var SliccChat = class extends ThemedElement {
8309
8708
  focus() {
8310
8709
  this.focusOn("slicc-composer");
8311
8710
  }
8711
+ #id() {
8712
+ return this.agent || (this.model?.agent.active() ?? "");
8713
+ }
8312
8714
  #agent() {
8313
- const model = this.model;
8314
- return model?.agent.list().find((agent) => agent.id === model.agent.active());
8715
+ const id = this.#id();
8716
+ return this.model?.agent.list().find((agent) => agent.id === id);
8315
8717
  }
8316
8718
  #action(action) {
8317
8719
  const model = this.model;
8318
8720
  if (!model) return;
8319
- const id = model.agent.active();
8721
+ const id = this.#id();
8320
8722
  if (action === "retry") {
8321
8723
  const last = model.agent.messages(id).filter((message) => message.role === "user").at(-1);
8322
8724
  if (last) void model.agent.send(id, { text: last.text, attachments: last.attachments });
@@ -8380,7 +8782,7 @@ var SliccChat = class extends ThemedElement {
8380
8782
  ${agent && messages.length > 0 ? this.#items(messages, agent) : b`<div class="empty">No messages yet. Ask ${agent?.name ?? "the agent"} something.</div>`}
8381
8783
  </div>
8382
8784
  </div>
8383
- ${this.model ? b`<slicc-composer .model=${this.model}></slicc-composer>` : A}
8785
+ ${this.model ? b`<slicc-composer .model=${this.model} .agent=${this.agent}></slicc-composer>` : A}
8384
8786
  `;
8385
8787
  }
8386
8788
  };
@@ -8472,7 +8874,8 @@ var SliccComposer = class extends ModelElement {
8472
8874
  value: { state: true },
8473
8875
  attachments: { state: true },
8474
8876
  popup: { state: true },
8475
- dictating: { state: true }
8877
+ dictating: { state: true },
8878
+ agent: {}
8476
8879
  };
8477
8880
  #drafts = /* @__PURE__ */ new Map();
8478
8881
  #history = -1;
@@ -8486,6 +8889,7 @@ var SliccComposer = class extends ModelElement {
8486
8889
  this.attachments = [];
8487
8890
  this.popup = null;
8488
8891
  this.dictating = false;
8892
+ this.agent = "";
8489
8893
  }
8490
8894
  static styles = [
8491
8895
  shared,
@@ -8684,14 +9088,22 @@ var SliccComposer = class extends ModelElement {
8684
9088
  }
8685
9089
  `
8686
9090
  ];
9091
+ willUpdate(changed) {
9092
+ super.willUpdate(changed);
9093
+ if (changed.has("agent") && this.agent && this.model && this.agent !== this.#agent) {
9094
+ this.#switch(this.agent);
9095
+ }
9096
+ }
8687
9097
  subscribe(model) {
8688
- this.#switch(model.agent.active());
9098
+ this.#switch(this.agent || model.agent.active());
8689
9099
  void model.files.list().then((entries) => {
8690
9100
  this.#paths = entries.filter((entry) => entry.kind === "file").map((entry) => entry.path);
8691
9101
  });
8692
9102
  const update = () => this.requestUpdate();
8693
9103
  return [
8694
- model.agent.on("active", (id) => this.#switch(id)),
9104
+ model.agent.on("active", (id) => {
9105
+ if (!this.agent) this.#switch(id);
9106
+ }),
8695
9107
  model.agent.on("agents", update),
8696
9108
  model.agent.on("messages", update),
8697
9109
  model.agent.on("message", update),
@@ -9943,6 +10355,7 @@ async function frameFonts(files, base) {
9943
10355
  (font) => Boolean(font.data)
9944
10356
  );
9945
10357
  }
10358
+ var grip = w`<svg class="grip" viewBox="0 0 8 14" width="8" height="14" aria-hidden="true">${[2, 7, 12].flatMap((y5) => [2, 6].map((x5) => w`<circle cx=${x5} cy=${y5} r="1.25"></circle>`))}</svg>`;
9946
10359
  var SliccSprinkle = class extends ThemedElement {
9947
10360
  static properties = {
9948
10361
  ...ThemedElement.properties,
@@ -9972,6 +10385,43 @@ var SliccSprinkle = class extends ThemedElement {
9972
10385
  height: 100%;
9973
10386
  border: 0;
9974
10387
  }
10388
+ .handle {
10389
+ display: flex;
10390
+ align-items: center;
10391
+ gap: 6px;
10392
+ width: max-content;
10393
+ max-width: 100%;
10394
+ box-sizing: border-box;
10395
+ height: 28px;
10396
+ padding: 0 4px 0 6px;
10397
+ border: 1px solid var(--spectrum-gray-200);
10398
+ border-bottom: 0;
10399
+ border-radius: 6px 6px 0 0;
10400
+ background: var(--spectrum-background-layer-1-color);
10401
+ color: var(--spectrum-neutral-subdued-content-color-default);
10402
+ font-size: var(--spectrum-font-size-75);
10403
+ cursor: grab;
10404
+ user-select: none;
10405
+ }
10406
+ .handle:active {
10407
+ cursor: grabbing;
10408
+ }
10409
+ .handle .grip {
10410
+ fill: currentColor;
10411
+ }
10412
+ .handle .name {
10413
+ color: var(--spectrum-neutral-content-color-default);
10414
+ }
10415
+ .moved {
10416
+ display: flex;
10417
+ align-items: center;
10418
+ gap: 8px;
10419
+ padding: 8px 12px;
10420
+ border: 1px dashed var(--spectrum-gray-300);
10421
+ border-radius: 8px;
10422
+ color: var(--spectrum-neutral-subdued-content-color-default);
10423
+ font-size: var(--spectrum-font-size-75);
10424
+ }
9975
10425
  .note {
9976
10426
  padding: 24px;
9977
10427
  color: var(--spectrum-neutral-subdued-content-color-default);
@@ -9997,22 +10447,50 @@ var SliccSprinkle = class extends ThemedElement {
9997
10447
  this.height = data.height;
9998
10448
  }
9999
10449
  };
10450
+ #dips = new Dips();
10000
10451
  subscribe(model) {
10452
+ this.#dips = dipsOf(this) ?? this.#dips;
10001
10453
  globalThis.addEventListener("message", this.#message);
10002
10454
  return [
10003
10455
  ...super.subscribe(model),
10004
10456
  () => globalThis.removeEventListener("message", this.#message),
10005
- model.sprinkles.on("sprinkles", () => this.requestUpdate())
10457
+ model.sprinkles.on("sprinkles", () => this.requestUpdate()),
10458
+ this.#dips.on("change", () => this.requestUpdate())
10006
10459
  ];
10007
10460
  }
10461
+ #drag = (event) => {
10462
+ const data = this.#data;
10463
+ event.dataTransfer?.setData(dipType, this.sprinkle);
10464
+ event.dataTransfer?.setData("text/plain", data?.title ?? this.sprinkle);
10465
+ if (event.dataTransfer) event.dataTransfer.effectAllowed = "move";
10466
+ };
10467
+ #send(type, id) {
10468
+ this.dispatchEvent(new CustomEvent(type, { detail: { id }, bubbles: true, composed: true }));
10469
+ }
10008
10470
  get #data() {
10009
10471
  return this.model?.sprinkles.list().find((candidate) => candidate.id === this.sprinkle);
10010
10472
  }
10011
10473
  render() {
10012
10474
  const data = this.#data;
10013
10475
  if (!data) return b`<div class="note">This sprinkle is gone.</div>`;
10476
+ if (this.inline && this.#dips.has(data.id)) {
10477
+ return b`<div class="moved">
10478
+ <sp-icon-open-in size="s"></sp-icon-open-in>
10479
+ <span>${data.title} is open as a panel.</span>
10480
+ <sp-action-button size="s" quiet @click=${() => this.#send("show-surface", `sprinkle:${data.id}`)}>Show</sp-action-button>
10481
+ </div>`;
10482
+ }
10014
10483
  const style = `color-scheme:${this.color};${this.inline ? `height:${this.height}px;` : ""}`;
10015
- return b`<iframe title=${data.title} sandbox="allow-scripts" style=${style} .srcdoc=${frameDocument(data.html, this.color, data.name)}></iframe>`;
10484
+ const frame = b`<iframe title=${data.title} sandbox="allow-scripts" style=${style} .srcdoc=${frameDocument(data.html, this.color, data.name)}></iframe>`;
10485
+ if (!this.inline) return frame;
10486
+ return b`<div class="handle" draggable="true" title="Drag into the dock or a rail to open as a panel" @dragstart=${this.#drag}>
10487
+ ${grip}
10488
+ <span class="name">${data.title}</span>
10489
+ <sp-action-button size="xs" quiet label=${`Open ${data.title} as a panel`} title="Open as a panel" @click=${() => this.#send("detach-sprinkle", data.id)}>
10490
+ <sp-icon-open-in slot="icon"></sp-icon-open-in>
10491
+ </sp-action-button>
10492
+ </div>
10493
+ ${frame}`;
10016
10494
  }
10017
10495
  };
10018
10496
 
@@ -10997,7 +11475,7 @@ var bundledLanguagesInfo = [
10997
11475
  {
10998
11476
  "id": "html",
10999
11477
  "name": "HTML",
11000
- "import": (() => import("./chunk-YPQKCWWG.js"))
11478
+ "import": (() => import("./chunk-FXM4K5WL.js"))
11001
11479
  },
11002
11480
  {
11003
11481
  "id": "html-derivative",
@@ -52132,6 +52610,7 @@ var theme = {
52132
52610
  };
52133
52611
  var SliccDock = class extends HTMLElement {
52134
52612
  factories = {};
52613
+ accepts = [];
52135
52614
  #api = null;
52136
52615
  #contents = /* @__PURE__ */ new Map();
52137
52616
  get api() {
@@ -52179,12 +52658,30 @@ var SliccDock = class extends HTMLElement {
52179
52658
  api.onDidActivePanelChange(
52180
52659
  ({ panel }) => this.#dispatch("active-panel-change", { id: panel?.id ?? null })
52181
52660
  );
52661
+ api.onUnhandledDragOver((event) => {
52662
+ if (this.#accepted(event.nativeEvent)) event.accept();
52663
+ });
52664
+ api.onDidDrop((event) => {
52665
+ const type = this.#accepted(event.nativeEvent);
52666
+ if (!type) return;
52667
+ const transfer = event.nativeEvent.dataTransfer;
52668
+ this.#dispatch("external-drop", {
52669
+ type,
52670
+ data: transfer.getData(type),
52671
+ panel: event.group?.activePanel?.id ?? null,
52672
+ position: event.position
52673
+ });
52674
+ });
52182
52675
  api.onDidRemovePanel((panel) => {
52183
52676
  this.#contents.delete(panel.id);
52184
52677
  this.#dispatch("panel-close", { id: panel.id });
52185
52678
  });
52186
52679
  this.#api = api;
52187
52680
  }
52681
+ #accepted(native) {
52682
+ const types = native instanceof DragEvent ? [...native.dataTransfer?.types ?? []] : [];
52683
+ return this.accepts.find((type) => types.includes(type));
52684
+ }
52188
52685
  #create(id, name) {
52189
52686
  const element2 = document.createElement("div");
52190
52687
  element2.className = "panel";
@@ -52216,6 +52713,10 @@ var SliccDock = class extends HTMLElement {
52216
52713
  }
52217
52714
  return this.api.addPanel(options);
52218
52715
  }
52716
+ reveal(id) {
52717
+ const panel = this.api.getPanel(id);
52718
+ panel?.group.model.openPanel(panel, { skipSetGroupActive: true });
52719
+ }
52219
52720
  close(id) {
52220
52721
  this.api.getPanel(id)?.api.close();
52221
52722
  }
@@ -61493,8 +61994,16 @@ var SliccFileTree = class extends HTMLElement {
61493
61994
  return this.#paths;
61494
61995
  }
61495
61996
  set paths(value) {
61997
+ const expanded = this.#paths.length > 0 ? this.#expandedNow() : this.#expanded;
61496
61998
  this.#paths = value;
61497
- this.#tree?.resetPaths(value, { initialExpandedPaths: this.#expanded });
61999
+ this.#tree?.resetPaths(value, { initialExpandedPaths: expanded });
62000
+ }
62001
+ #expandedNow() {
62002
+ const tree = this.#tree;
62003
+ return this.#paths.filter((path) => {
62004
+ const item2 = path.endsWith("/") ? tree?.getItem(path) : null;
62005
+ return !!item2 && "isExpanded" in item2 && item2.isExpanded();
62006
+ }).map((path) => path.slice(0, -1));
61498
62007
  }
61499
62008
  get gitStatus() {
61500
62009
  return this.#status;