@trops/dash-core 0.1.605 → 0.1.606

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/index.js CHANGED
@@ -2825,13 +2825,42 @@ var useInstalledWidgets = function useInstalledWidgets() {
2825
2825
  error = _useState6[0],
2826
2826
  setError = _useState6[1];
2827
2827
  var refresh = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
2828
- var _window$mainApi, cMap, builtinWidgets, registryByName, list, installedFromCM, cmSourcePackages, fallbackInstalled, _t;
2828
+ var _window$mainApi, _window$mainApi2, classifyWidget, cMap, builtinWidgets, draftsByPackageDir, draftShortIdToId, allDrafts, _iterator4, _step4, d, shortId, registryByName, list, installedFromCM, cmSourcePackages, fallbackInstalled, _t, _t3;
2829
2829
  return _regeneratorRuntime.wrap(function (_context) {
2830
2830
  while (1) switch (_context.prev = _context.next) {
2831
2831
  case 0:
2832
2832
  setIsLoading(true);
2833
2833
  setError(null);
2834
2834
  _context.prev = 1;
2835
+ classifyWidget = function classifyWidget(reg, fallbackName) {
2836
+ var name = (reg === null || reg === void 0 ? void 0 : reg.name) || fallbackName || "";
2837
+ var path = (reg === null || reg === void 0 ? void 0 : reg.path) || "";
2838
+ // 1. Match against drafts metadata by packageDir (canonical).
2839
+ if (path && draftsByPackageDir.has(path)) {
2840
+ return {
2841
+ kind: "draft",
2842
+ draftId: draftsByPackageDir.get(path).id
2843
+ };
2844
+ }
2845
+ // 2. Fallback: the dir name follows `<base>-draft-<shortId>`;
2846
+ // pluck the shortId and look it up in the drafts list.
2847
+ var m = String(name).match(/-draft-([A-Za-z0-9]+)$/);
2848
+ if (m) {
2849
+ var _shortId = m[1].slice(0, 8);
2850
+ var draftId = draftShortIdToId.get(_shortId) || null;
2851
+ return {
2852
+ kind: "draft",
2853
+ draftId: draftId
2854
+ };
2855
+ }
2856
+ return {
2857
+ kind: "installed",
2858
+ draftId: null
2859
+ };
2860
+ }; // ── Installed widgets from ComponentManager + Registry ───
2861
+ // CM entries with _sourcePackage are registry-installed widgets.
2862
+ // Show each as an individual "installed" entry, enriched with
2863
+ // registry-level metadata (version, path, packageId).
2835
2864
  // ── Built-in widgets from ComponentManager ──────────────
2836
2865
  cMap = ComponentManager.componentMap() || {};
2837
2866
  builtinWidgets = Object.keys(cMap).filter(function (key) {
@@ -2850,33 +2879,80 @@ var useInstalledWidgets = function useInstalledWidgets() {
2850
2879
  version: null,
2851
2880
  path: null,
2852
2881
  source: "builtin",
2882
+ kind: "installed",
2883
+ draftId: null,
2853
2884
  providers: config.providers || [],
2854
2885
  workspace: config.workspace || null,
2855
2886
  componentNames: [key],
2856
2887
  scopedId: key
2857
2888
  };
2858
- }); // ── Installed widgets from ComponentManager + Registry ───
2859
- // CM entries with _sourcePackage are registry-installed widgets.
2860
- // Show each as an individual "installed" entry, enriched with
2861
- // registry-level metadata (version, path, packageId).
2889
+ }); // ── Drafts (in-progress widgets from the AI Builder) ─────
2890
+ // Drafts on disk look like installed packages — their dirs
2891
+ // sit under @ai-built/<name>-draft-<shortId>/ alongside real
2892
+ // installs. We surface them as `kind: "draft"` so consumers
2893
+ // (dashboard picker, Settings → Widgets) can render them
2894
+ // distinctly (Resume/Delete affordances) or filter them out.
2895
+ // The match is `packageDir`-based when available (canonical)
2896
+ // and falls back to a `-draft-` name-pattern check so legacy
2897
+ // drafts without the on-disk metadata still get classified.
2898
+ draftsByPackageDir = new Map();
2899
+ draftShortIdToId = new Map();
2900
+ if (!((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.drafts) !== null && _window$mainApi !== void 0 && _window$mainApi.list)) {
2901
+ _context.next = 6;
2902
+ break;
2903
+ }
2904
+ _context.prev = 2;
2905
+ _context.next = 3;
2906
+ return window.mainApi.drafts.list();
2907
+ case 3:
2908
+ _t = _context.sent;
2909
+ if (_t) {
2910
+ _context.next = 4;
2911
+ break;
2912
+ }
2913
+ _t = [];
2914
+ case 4:
2915
+ allDrafts = _t;
2916
+ _iterator4 = _createForOfIteratorHelper$M(allDrafts);
2917
+ try {
2918
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
2919
+ d = _step4.value;
2920
+ if (d !== null && d !== void 0 && d.packageDir) draftsByPackageDir.set(d.packageDir, d);
2921
+ if (d !== null && d !== void 0 && d.id) {
2922
+ shortId = String(d.id).replace(/^draft-/, "").slice(0, 8);
2923
+ if (shortId) draftShortIdToId.set(shortId, d.id);
2924
+ }
2925
+ }
2926
+ } catch (err) {
2927
+ _iterator4.e(err);
2928
+ } finally {
2929
+ _iterator4.f();
2930
+ }
2931
+ _context.next = 6;
2932
+ break;
2933
+ case 5:
2934
+ _context.prev = 5;
2935
+ _context["catch"](2);
2936
+ case 6:
2862
2937
  registryByName = {};
2863
- if (!((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && _window$mainApi.widgets)) {
2864
- _context.next = 3;
2938
+ if (!((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.widgets)) {
2939
+ _context.next = 8;
2865
2940
  break;
2866
2941
  }
2867
- _context.next = 2;
2942
+ _context.next = 7;
2868
2943
  return window.mainApi.widgets.list();
2869
- case 2:
2944
+ case 7:
2870
2945
  list = _context.sent;
2871
2946
  (list || []).forEach(function (w) {
2872
2947
  registryByName[w.packageId || w.name] = w;
2873
2948
  });
2874
- case 3:
2949
+ case 8:
2875
2950
  installedFromCM = Object.keys(cMap).filter(function (key) {
2876
2951
  return cMap[key].type === "widget" && !!cMap[key]._sourcePackage;
2877
2952
  }).map(function (key) {
2878
2953
  var config = cMap[key];
2879
2954
  var reg = registryByName[config._sourcePackage] || {};
2955
+ var classification = classifyWidget(reg, config._sourcePackage);
2880
2956
  return {
2881
2957
  name: key,
2882
2958
  displayName: config.name || key,
@@ -2887,6 +2963,8 @@ var useInstalledWidgets = function useInstalledWidgets() {
2887
2963
  version: reg.version || null,
2888
2964
  path: reg.path || null,
2889
2965
  source: "installed",
2966
+ kind: classification.kind,
2967
+ draftId: classification.draftId,
2890
2968
  providers: config.providers || [],
2891
2969
  workspace: config.workspace || null,
2892
2970
  componentNames: [key],
@@ -2903,6 +2981,7 @@ var useInstalledWidgets = function useInstalledWidgets() {
2903
2981
  fallbackInstalled = Object.values(registryByName).filter(function (w) {
2904
2982
  return !cmSourcePackages.has(w.name);
2905
2983
  }).map(function (w) {
2984
+ var classification = classifyWidget(w, w.name);
2906
2985
  return {
2907
2986
  name: w.name,
2908
2987
  displayName: w.displayName || w.name,
@@ -2913,6 +2992,8 @@ var useInstalledWidgets = function useInstalledWidgets() {
2913
2992
  version: w.version || null,
2914
2993
  path: w.path || null,
2915
2994
  source: "installed",
2995
+ kind: classification.kind,
2996
+ draftId: classification.draftId,
2916
2997
  providers: w.providers || [],
2917
2998
  workspace: w.workspace || null,
2918
2999
  componentNames: w.componentNames || [],
@@ -2921,31 +3002,31 @@ var useInstalledWidgets = function useInstalledWidgets() {
2921
3002
  };
2922
3003
  });
2923
3004
  setWidgets([].concat(_toConsumableArray(builtinWidgets), _toConsumableArray(installedFromCM), _toConsumableArray(fallbackInstalled)));
2924
- _context.next = 5;
3005
+ _context.next = 10;
2925
3006
  break;
2926
- case 4:
2927
- _context.prev = 4;
2928
- _t = _context["catch"](1);
2929
- setError(_t.message || "Failed to load widgets");
3007
+ case 9:
3008
+ _context.prev = 9;
3009
+ _t3 = _context["catch"](1);
3010
+ setError(_t3.message || "Failed to load widgets");
2930
3011
  setWidgets([]);
2931
- case 5:
2932
- _context.prev = 5;
3012
+ case 10:
3013
+ _context.prev = 10;
2933
3014
  setIsLoading(false);
2934
- return _context.finish(5);
2935
- case 6:
3015
+ return _context.finish(10);
3016
+ case 11:
2936
3017
  case "end":
2937
3018
  return _context.stop();
2938
3019
  }
2939
- }, _callee, null, [[1, 4, 5, 6]]);
3020
+ }, _callee, null, [[1, 9, 10, 11], [2, 5]]);
2940
3021
  })), []);
2941
3022
  var uninstallWidget = React.useCallback(/*#__PURE__*/function () {
2942
3023
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(widgetName) {
2943
- var _window$mainApi2;
2944
- var widget, packageId, cMap, keysToRemove, _t2;
3024
+ var _window$mainApi3;
3025
+ var widget, packageId, cMap, keysToRemove, _t4;
2945
3026
  return _regeneratorRuntime.wrap(function (_context2) {
2946
3027
  while (1) switch (_context2.prev = _context2.next) {
2947
3028
  case 0:
2948
- if ((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.widgets) {
3029
+ if ((_window$mainApi3 = window.mainApi) !== null && _window$mainApi3 !== void 0 && _window$mainApi3.widgets) {
2949
3030
  _context2.next = 1;
2950
3031
  break;
2951
3032
  }
@@ -2976,8 +3057,8 @@ var useInstalledWidgets = function useInstalledWidgets() {
2976
3057
  break;
2977
3058
  case 4:
2978
3059
  _context2.prev = 4;
2979
- _t2 = _context2["catch"](1);
2980
- throw _t2;
3060
+ _t4 = _context2["catch"](1);
3061
+ throw _t4;
2981
3062
  case 5:
2982
3063
  case "end":
2983
3064
  return _context2.stop();
@@ -17685,6 +17766,12 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
17685
17766
  // Filter widgets based on search, author, and provider
17686
17767
  var getFilteredWidgets = function getFilteredWidgets() {
17687
17768
  var filtered = widgets.filter(function (widget) {
17769
+ // Drafts are in-progress widgets — they appear in
17770
+ // Settings → Widgets (as a Draft chip with Resume/Delete
17771
+ // affordances) but never in the dashboard placement picker
17772
+ // since they're not finished products.
17773
+ if (widget.kind === "draft") return false;
17774
+
17688
17775
  // Search filter
17689
17776
  var searchLower = searchQuery.toLowerCase();
17690
17777
  var matchesSearch = !searchQuery || (widget.name || "").toLowerCase().includes(searchLower) || (widget.description || "").toLowerCase().includes(searchLower) || (widget.key || "").toLowerCase().includes(searchLower) || (widget.packageName || "").toLowerCase().includes(searchLower) || (widget.packageTags || []).some(function (t) {
@@ -48678,7 +48765,27 @@ var InstalledWidgetDetail = function InstalledWidgetDetail(_ref) {
48678
48765
  className: "p-2 rounded bg-red-900/30 border border-red-700 text-xs text-red-400",
48679
48766
  children: updateError
48680
48767
  })
48681
- }), widget.source !== "builtin" && /*#__PURE__*/jsxRuntime.jsxs("div", {
48768
+ }), widget.source !== "builtin" && widget.kind === "draft" && /*#__PURE__*/jsxRuntime.jsxs("div", {
48769
+ className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t ".concat(currentTheme["border-primary-medium"] || "border-white/10"),
48770
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
48771
+ title: "Resume",
48772
+ onClick: function onClick() {
48773
+ window.dispatchEvent(new CustomEvent("dash:open-widget-builder", {
48774
+ detail: {
48775
+ resumeDraftId: widget.draftId || null
48776
+ }
48777
+ }));
48778
+ },
48779
+ disabled: !widget.draftId,
48780
+ size: "sm"
48781
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
48782
+ title: "Delete",
48783
+ onClick: function onClick() {
48784
+ return onDelete(widget);
48785
+ },
48786
+ size: "sm"
48787
+ })]
48788
+ }), widget.source !== "builtin" && widget.kind !== "draft" && /*#__PURE__*/jsxRuntime.jsxs("div", {
48682
48789
  className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t ".concat(currentTheme["border-primary-medium"] || "border-white/10"),
48683
48790
  children: [updateInfo && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
48684
48791
  title: isUpdating ? "Updating..." : "Update Package to v".concat(updateInfo.latestVersion),
@@ -50145,7 +50252,12 @@ var WidgetsSection = function WidgetsSection(_ref) {
50145
50252
  className: "flex items-center gap-2",
50146
50253
  children: [widget.displayName || widget.name, widget.source === "builtin" && /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag3, {
50147
50254
  text: "Built-in"
50148
- }), updates.has(widget.name) && /*#__PURE__*/jsxRuntime.jsx("span", {
50255
+ }), widget.kind === "draft" && /*#__PURE__*/jsxRuntime.jsx("span", {
50256
+ className: "px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-amber-900/40 text-amber-200 border border-amber-700/30",
50257
+ "data-testid": "widget-draft-chip-".concat(widget.name),
50258
+ title: "In-progress widget \u2014 open to Resume or Delete from the action menu",
50259
+ children: "Draft"
50260
+ }), widget.kind !== "draft" && updates.has(widget.name) && /*#__PURE__*/jsxRuntime.jsx("span", {
50149
50261
  className: "text-[10px] text-blue-400 font-medium",
50150
50262
  "data-testid": "widget-update-badge-".concat(widget.name),
50151
50263
  children: "Update"