pinokiod 7.2.18 → 7.3.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 (89) hide show
  1. package/Dockerfile +2 -0
  2. package/kernel/api/index.js +13 -179
  3. package/kernel/api/process/index.js +44 -99
  4. package/kernel/bin/conda-python.js +30 -0
  5. package/kernel/bin/conda.js +22 -3
  6. package/kernel/bin/huggingface.js +1 -1
  7. package/kernel/bin/index.js +11 -1
  8. package/kernel/environment.js +11 -205
  9. package/kernel/git.js +13 -0
  10. package/kernel/index.js +1 -64
  11. package/kernel/plugin.js +58 -6
  12. package/kernel/prototype.js +0 -4
  13. package/kernel/shell.js +2 -23
  14. package/kernel/util.js +0 -60
  15. package/package.json +1 -1
  16. package/server/index.js +171 -229
  17. package/server/lib/content_validation.js +33 -47
  18. package/server/public/common.js +29 -103
  19. package/server/public/create-launcher.js +31 -4
  20. package/server/public/electron.css +6 -0
  21. package/server/public/style.css +0 -337
  22. package/server/public/task-launcher.css +3 -11
  23. package/server/public/task-launcher.js +32 -5
  24. package/server/public/universal-launcher.js +26 -3
  25. package/server/socket.js +11 -22
  26. package/server/views/app.ejs +30 -167
  27. package/server/views/d.ejs +35 -33
  28. package/server/views/editor.ejs +4 -25
  29. package/server/views/partials/main_sidebar.ejs +0 -1
  30. package/server/views/partials/menu.ejs +1 -1
  31. package/server/views/pre.ejs +1 -1
  32. package/server/views/shell.ejs +3 -11
  33. package/server/views/task_launch.ejs +10 -10
  34. package/server/views/terminal.ejs +5 -34
  35. package/spec/INSTRUCTION_SYNC.md +5 -5
  36. package/kernel/agent_instructions.js +0 -166
  37. package/kernel/api/shell_run_template.js +0 -273
  38. package/kernel/api/uri/index.js +0 -51
  39. package/kernel/plugin_sources.js +0 -289
  40. package/kernel/watch/context.js +0 -42
  41. package/kernel/watch/drivers/fs.js +0 -71
  42. package/kernel/watch/drivers/poll.js +0 -33
  43. package/kernel/watch/index.js +0 -185
  44. package/server/features/index.js +0 -13
  45. package/server/features/notes/index.js +0 -41
  46. package/server/features/notes/parser.js +0 -174
  47. package/server/features/notes/public/notes.css +0 -955
  48. package/server/features/notes/public/notes.js +0 -1149
  49. package/server/features/notes/registry_import.js +0 -412
  50. package/server/features/notes/routes.js +0 -156
  51. package/server/features/notes/service.js +0 -326
  52. package/server/features/notes/watcher.js +0 -74
  53. package/server/lib/workspace_catalog.js +0 -151
  54. package/server/lib/workspace_runtime.js +0 -390
  55. package/server/public/tasker.css +0 -336
  56. package/server/public/tasker.js +0 -407
  57. package/server/routes/workspaces.js +0 -44
  58. package/server/views/partials/workspace_row.ejs +0 -61
  59. package/server/views/tasker.ejs +0 -40
  60. package/server/views/workspaces.ejs +0 -813
  61. package/system/plugin/antigravity/antigravity.png +0 -0
  62. package/system/plugin/antigravity/pinokio.js +0 -35
  63. package/system/plugin/claude/claude.png +0 -0
  64. package/system/plugin/claude/pinokio.js +0 -61
  65. package/system/plugin/claude-auto/claude.png +0 -0
  66. package/system/plugin/claude-auto/pinokio.js +0 -72
  67. package/system/plugin/claude-desktop/icon.jpeg +0 -0
  68. package/system/plugin/claude-desktop/pinokio.js +0 -37
  69. package/system/plugin/codex/openai.webp +0 -0
  70. package/system/plugin/codex/pinokio.js +0 -56
  71. package/system/plugin/codex-auto/openai.webp +0 -0
  72. package/system/plugin/codex-auto/pinokio.js +0 -63
  73. package/system/plugin/codex-desktop/icon.png +0 -0
  74. package/system/plugin/codex-desktop/pinokio.js +0 -37
  75. package/system/plugin/crush/crush.png +0 -0
  76. package/system/plugin/crush/pinokio.js +0 -29
  77. package/system/plugin/cursor/cursor.jpeg +0 -0
  78. package/system/plugin/cursor/pinokio.js +0 -37
  79. package/system/plugin/gemini/gemini.jpeg +0 -0
  80. package/system/plugin/gemini/pinokio.js +0 -38
  81. package/system/plugin/gemini-auto/gemini.jpeg +0 -0
  82. package/system/plugin/gemini-auto/pinokio.js +0 -41
  83. package/system/plugin/qwen/pinokio.js +0 -48
  84. package/system/plugin/qwen/qwen.png +0 -0
  85. package/system/plugin/vscode/pinokio.js +0 -34
  86. package/system/plugin/vscode/vscode.png +0 -0
  87. package/system/plugin/windsurf/pinokio.js +0 -37
  88. package/system/plugin/windsurf/windsurf.png +0 -0
  89. package/test/plugin-sources.test.js +0 -45
@@ -2857,343 +2857,6 @@ body.dark .swal2-popup.pinokio-download-modal .pinokio-download-cancel.swal2-can
2857
2857
  body.dark .swal2-popup.pinokio-download-modal .pinokio-download-cancel.swal2-cancel:hover {
2858
2858
  background: rgba(148, 163, 184, 0.18) !important;
2859
2859
  }
2860
- .pinokio-install-inline-status .install-status-shell {
2861
- display: flex;
2862
- align-items: flex-start;
2863
- gap: 12px;
2864
- min-height: 44px;
2865
- }
2866
- .pinokio-install-inline-status .install-status-copy {
2867
- min-width: 0;
2868
- flex: 1;
2869
- }
2870
- .pinokio-install-inline-status .install-status-title {
2871
- color: inherit;
2872
- font-size: 15px;
2873
- line-height: 1.2;
2874
- font-weight: 700;
2875
- }
2876
- .pinokio-install-inline-status .install-status-detail {
2877
- margin-top: 4px;
2878
- color: rgba(235, 222, 197, 0.82);
2879
- font-size: 12px;
2880
- line-height: 1.35;
2881
- word-break: break-word;
2882
- }
2883
- body.dark .pinokio-install-inline-status .install-status-detail {
2884
- color: rgba(239, 233, 214, 0.76);
2885
- }
2886
- .pinokio-install-inline-status .install-status-detail > *:first-child {
2887
- margin-top: 0;
2888
- }
2889
- .pinokio-install-inline-status .install-status-detail > *:last-child {
2890
- margin-bottom: 0;
2891
- }
2892
- .pinokio-install-inline-status .install-status-spinner {
2893
- width: 18px;
2894
- height: 18px;
2895
- flex: 0 0 18px;
2896
- margin-top: 1px;
2897
- position: relative;
2898
- display: inline-flex;
2899
- align-items: center;
2900
- justify-content: center;
2901
- }
2902
- .pinokio-install-inline-status .install-status-grid-anchor,
2903
- .pinokio-install-inline-status .install-status-grid-tile,
2904
- .pinokio-install-inline-status .install-status-grid-chaser,
2905
- .pinokio-install-inline-status .install-status-grid-pixel {
2906
- position: absolute;
2907
- top: 0;
2908
- left: 0;
2909
- box-sizing: border-box;
2910
- display: none;
2911
- transform-origin: center;
2912
- }
2913
- .pinokio-install-inline-status .install-status-grid-anchor,
2914
- .pinokio-install-inline-status .install-status-grid-tile,
2915
- .pinokio-install-inline-status .install-status-grid-chaser {
2916
- width: 7px;
2917
- height: 7px;
2918
- border-radius: 2px;
2919
- }
2920
- .pinokio-install-inline-status .install-status-grid-anchor {
2921
- background: currentColor;
2922
- opacity: 0.16;
2923
- }
2924
- .pinokio-install-inline-status .install-status-grid-tile,
2925
- .pinokio-install-inline-status .install-status-grid-chaser,
2926
- .pinokio-install-inline-status .install-status-grid-pixel {
2927
- background: currentColor;
2928
- }
2929
- .pinokio-install-inline-status .install-status-grid-pixel {
2930
- width: 4px;
2931
- height: 4px;
2932
- border-radius: 1px;
2933
- }
2934
- .pinokio-install-inline-status .install-status-grid-anchor-1,
2935
- .pinokio-install-inline-status .install-status-grid-tile-1,
2936
- .pinokio-install-inline-status .install-status-grid-chaser {
2937
- top: 1px;
2938
- left: 1px;
2939
- }
2940
- .pinokio-install-inline-status .install-status-grid-anchor-2,
2941
- .pinokio-install-inline-status .install-status-grid-tile-2 {
2942
- top: 1px;
2943
- left: 12px;
2944
- }
2945
- .pinokio-install-inline-status .install-status-grid-anchor-3,
2946
- .pinokio-install-inline-status .install-status-grid-tile-3 {
2947
- top: 12px;
2948
- left: 12px;
2949
- }
2950
- .pinokio-install-inline-status .install-status-grid-anchor-4,
2951
- .pinokio-install-inline-status .install-status-grid-tile-4 {
2952
- top: 12px;
2953
- left: 1px;
2954
- }
2955
- .pinokio-install-inline-status .install-status-grid-pixel {
2956
- top: 2px;
2957
- left: 2px;
2958
- }
2959
- [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile {
2960
- display: block;
2961
- }
2962
- [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-1 {
2963
- animation: pinokio-grid-shift-1 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2964
- }
2965
- [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-2 {
2966
- animation: pinokio-grid-shift-2 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2967
- }
2968
- [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2969
- animation: pinokio-grid-shift-3 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2970
- }
2971
- [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-4 {
2972
- animation: pinokio-grid-shift-4 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2973
- }
2974
- [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-anchor {
2975
- display: block;
2976
- }
2977
- [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-1,
2978
- [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-2,
2979
- [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2980
- display: block;
2981
- }
2982
- [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-1 {
2983
- animation: pinokio-single-vacancy-1 1.55s cubic-bezier(0.62, 0, 0.22, 1) infinite;
2984
- }
2985
- [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-2 {
2986
- animation: pinokio-single-vacancy-2 1.55s cubic-bezier(0.62, 0, 0.22, 1) infinite;
2987
- }
2988
- [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2989
- animation: pinokio-single-vacancy-3 1.55s cubic-bezier(0.62, 0, 0.22, 1) infinite;
2990
- }
2991
- [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile {
2992
- display: block;
2993
- }
2994
- [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-1,
2995
- [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2996
- animation: pinokio-pulse-swap-a 1.18s ease-in-out infinite;
2997
- }
2998
- [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-2,
2999
- [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3000
- animation: pinokio-pulse-swap-b 1.18s ease-in-out infinite;
3001
- }
3002
- [data-install-spinner-variant="corner-chase"] .pinokio-install-inline-status .install-status-grid-anchor {
3003
- display: block;
3004
- }
3005
- [data-install-spinner-variant="corner-chase"] .pinokio-install-inline-status .install-status-grid-chaser {
3006
- display: block;
3007
- animation: pinokio-corner-chase 1.05s cubic-bezier(0.6, 0, 0.2, 1) infinite;
3008
- }
3009
- [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile {
3010
- display: block;
3011
- }
3012
- [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-1 {
3013
- animation: pinokio-grid-flip-1 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3014
- }
3015
- [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-2 {
3016
- animation: pinokio-grid-flip-2 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3017
- }
3018
- [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-3 {
3019
- animation: pinokio-grid-flip-3 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3020
- }
3021
- [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3022
- animation: pinokio-grid-flip-4 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3023
- }
3024
- [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile {
3025
- display: block;
3026
- animation: pinokio-stack-ripple 1.15s ease-in-out infinite;
3027
- }
3028
- [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile-2 {
3029
- animation-delay: -0.16s;
3030
- }
3031
- [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile-3 {
3032
- animation-delay: -0.32s;
3033
- }
3034
- [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3035
- animation-delay: -0.48s;
3036
- }
3037
- [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor {
3038
- display: block;
3039
- width: 4px;
3040
- height: 4px;
3041
- border-radius: 1px;
3042
- opacity: 0.22;
3043
- }
3044
- [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-1 {
3045
- top: 2px;
3046
- left: 2px;
3047
- }
3048
- [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-2 {
3049
- top: 2px;
3050
- left: 14px;
3051
- }
3052
- [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-3 {
3053
- top: 14px;
3054
- left: 14px;
3055
- }
3056
- [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-4 {
3057
- top: 14px;
3058
- left: 2px;
3059
- }
3060
- [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-pixel {
3061
- display: block;
3062
- animation: pinokio-pixel-orbit 1s cubic-bezier(0.6, 0, 0.2, 1) infinite;
3063
- }
3064
- [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-anchor {
3065
- display: block;
3066
- }
3067
- [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile {
3068
- display: block;
3069
- }
3070
- [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-1 {
3071
- animation: pinokio-binary-shuffle-1 1.1s steps(1, end) infinite;
3072
- }
3073
- [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-2 {
3074
- animation: pinokio-binary-shuffle-2 1.1s steps(1, end) infinite;
3075
- }
3076
- [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-3 {
3077
- animation: pinokio-binary-shuffle-3 1.1s steps(1, end) infinite;
3078
- }
3079
- [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3080
- animation: pinokio-binary-shuffle-4 1.1s steps(1, end) infinite;
3081
- }
3082
- @keyframes pinokio-grid-shift-1 {
3083
- 0%, 100% { transform: translate(0, 0); }
3084
- 25% { transform: translate(11px, 0); }
3085
- 50% { transform: translate(11px, 11px); }
3086
- 75% { transform: translate(0, 11px); }
3087
- }
3088
- @keyframes pinokio-grid-shift-2 {
3089
- 0%, 100% { transform: translate(0, 0); }
3090
- 25% { transform: translate(0, 11px); }
3091
- 50% { transform: translate(-11px, 11px); }
3092
- 75% { transform: translate(-11px, 0); }
3093
- }
3094
- @keyframes pinokio-grid-shift-3 {
3095
- 0%, 100% { transform: translate(0, 0); }
3096
- 25% { transform: translate(-11px, 0); }
3097
- 50% { transform: translate(-11px, -11px); }
3098
- 75% { transform: translate(0, -11px); }
3099
- }
3100
- @keyframes pinokio-grid-shift-4 {
3101
- 0%, 100% { transform: translate(0, 0); }
3102
- 25% { transform: translate(0, -11px); }
3103
- 50% { transform: translate(11px, -11px); }
3104
- 75% { transform: translate(11px, 0); }
3105
- }
3106
- @keyframes pinokio-single-vacancy-1 {
3107
- 0%, 50% { transform: translate(0, 0); }
3108
- 65%, 100% { transform: translate(11px, 0); }
3109
- }
3110
- @keyframes pinokio-single-vacancy-2 {
3111
- 0%, 15% { transform: translate(0, 0); }
3112
- 30%, 100% { transform: translate(0, 11px); }
3113
- }
3114
- @keyframes pinokio-single-vacancy-3 {
3115
- 0% { transform: translate(0, 0); }
3116
- 15%, 70% { transform: translate(-11px, 0); }
3117
- 85%, 100% { transform: translate(-11px, -11px); }
3118
- }
3119
- @keyframes pinokio-pulse-swap-a {
3120
- 0%, 45%, 100% {
3121
- opacity: 1;
3122
- transform: scale(1);
3123
- }
3124
- 50%, 95% {
3125
- opacity: 0.34;
3126
- transform: scale(0.82);
3127
- }
3128
- }
3129
- @keyframes pinokio-pulse-swap-b {
3130
- 0%, 45%, 100% {
3131
- opacity: 0.34;
3132
- transform: scale(0.82);
3133
- }
3134
- 50%, 95% {
3135
- opacity: 1;
3136
- transform: scale(1);
3137
- }
3138
- }
3139
- @keyframes pinokio-corner-chase {
3140
- 0%, 100% { transform: translate(0, 0); }
3141
- 25% { transform: translate(11px, 0); }
3142
- 50% { transform: translate(11px, 11px); }
3143
- 75% { transform: translate(0, 11px); }
3144
- }
3145
- @keyframes pinokio-grid-flip-1 {
3146
- 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3147
- 50% { transform: translate(11px, 0) scale(0.86); opacity: 0.72; }
3148
- }
3149
- @keyframes pinokio-grid-flip-2 {
3150
- 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3151
- 50% { transform: translate(-11px, 0) scale(0.86); opacity: 0.72; }
3152
- }
3153
- @keyframes pinokio-grid-flip-3 {
3154
- 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3155
- 50% { transform: translate(-11px, 0) scale(0.86); opacity: 0.72; }
3156
- }
3157
- @keyframes pinokio-grid-flip-4 {
3158
- 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3159
- 50% { transform: translate(11px, 0) scale(0.86); opacity: 0.72; }
3160
- }
3161
- @keyframes pinokio-stack-ripple {
3162
- 0%, 100% {
3163
- opacity: 0.38;
3164
- transform: scale(0.76);
3165
- }
3166
- 30% {
3167
- opacity: 1;
3168
- transform: scale(1);
3169
- }
3170
- 55% {
3171
- opacity: 0.62;
3172
- transform: scale(0.9);
3173
- }
3174
- }
3175
- @keyframes pinokio-pixel-orbit {
3176
- 0%, 100% { transform: translate(0, 0); }
3177
- 25% { transform: translate(12px, 0); }
3178
- 50% { transform: translate(12px, 12px); }
3179
- 75% { transform: translate(0, 12px); }
3180
- }
3181
- @keyframes pinokio-binary-shuffle-1 {
3182
- 0%, 24%, 75%, 100% { opacity: 1; transform: scale(1); }
3183
- 25%, 74% { opacity: 0; transform: scale(0.82); }
3184
- }
3185
- @keyframes pinokio-binary-shuffle-2 {
3186
- 0%, 24%, 75%, 100% { opacity: 0; transform: scale(0.82); }
3187
- 25%, 74% { opacity: 1; transform: scale(1); }
3188
- }
3189
- @keyframes pinokio-binary-shuffle-3 {
3190
- 0%, 49% { opacity: 1; transform: scale(1); }
3191
- 50%, 100% { opacity: 0; transform: scale(0.82); }
3192
- }
3193
- @keyframes pinokio-binary-shuffle-4 {
3194
- 0%, 49% { opacity: 0; transform: scale(0.82); }
3195
- 50%, 100% { opacity: 1; transform: scale(1); }
3196
- }
3197
2860
  .pinokio-install-inline-status {
3198
2861
  padding: 14px 18px;
3199
2862
  box-sizing: border-box;
@@ -1575,19 +1575,11 @@ body.dark .task-link-button.danger {
1575
1575
  }
1576
1576
 
1577
1577
  .task-run-footer {
1578
- display: grid;
1579
- gap: 8px;
1580
- margin-top: 2px;
1581
- padding-top: 14px;
1582
- border-top: 1px solid var(--task-border);
1578
+ margin-top: 14px;
1583
1579
  }
1584
1580
 
1585
- .task-run-actions,
1586
- .task-run-footer .task-run-button {
1581
+ .task-run-actions {
1587
1582
  margin: 0;
1588
- width: 100%;
1589
- min-height: 38px;
1590
- font-size: 12px;
1591
1583
  }
1592
1584
 
1593
1585
  .task-submit-feedback {
@@ -1864,7 +1856,7 @@ body.dark .task-link-button.danger {
1864
1856
  opacity: 0.55;
1865
1857
  }
1866
1858
 
1867
- .task-run-footer .task-submit-feedback {
1859
+ .task-prompt-actions .task-submit-feedback {
1868
1860
  margin-top: 2px;
1869
1861
  }
1870
1862
 
@@ -3,6 +3,34 @@
3
3
 
4
4
  const CATEGORY_ORDER = ["CLI", "IDE"];
5
5
  const TOOL_PREFERENCE_KEY = "pinokio.universalLauncher.tool";
6
+ const TOOL_VALUE_ALIASES = {
7
+ claude: "code/claude",
8
+ codex: "code/codex",
9
+ gemini: "code/gemini"
10
+ };
11
+ const FALLBACK_TOOLS = [
12
+ {
13
+ value: "code/claude",
14
+ label: "Claude Code",
15
+ iconSrc: "/asset/plugin/code/claude/claude.png",
16
+ isDefault: true,
17
+ category: "CLI"
18
+ },
19
+ {
20
+ value: "code/codex",
21
+ label: "OpenAI Codex",
22
+ iconSrc: "/asset/plugin/code/codex/openai.webp",
23
+ isDefault: false,
24
+ category: "CLI"
25
+ },
26
+ {
27
+ value: "code/gemini",
28
+ label: "Google Gemini CLI",
29
+ iconSrc: "/asset/plugin/code/gemini/gemini.jpeg",
30
+ isDefault: false,
31
+ category: "CLI"
32
+ }
33
+ ];
6
34
  const TASK_INSTALL_SHELL_CLIENT = {
7
35
  cols: 120,
8
36
  rows: 32
@@ -75,7 +103,7 @@
75
103
  if (!trimmed) {
76
104
  return "";
77
105
  }
78
- return trimmed;
106
+ return TOOL_VALUE_ALIASES[trimmed] || trimmed;
79
107
  }
80
108
 
81
109
  function getStoredToolPreference() {
@@ -413,10 +441,9 @@
413
441
  }
414
442
  const payload = await response.json();
415
443
  const tools = mapPluginMenuToTools(payload && Array.isArray(payload.menu) ? payload.menu : []);
416
- return tools;
417
- } catch (error) {
418
- console.warn("Failed to load task launcher plugins", error);
419
- return [];
444
+ return tools.length > 0 ? tools : FALLBACK_TOOLS.slice();
445
+ } catch (_) {
446
+ return FALLBACK_TOOLS.slice();
420
447
  }
421
448
  }
422
449
 
@@ -20,6 +20,29 @@
20
20
  SSH_ASKPASS: '',
21
21
  GCM_INTERACTIVE: 'never',
22
22
  };
23
+ const FALLBACK_TOOLS = [
24
+ {
25
+ value: 'code/claude',
26
+ label: 'Claude Code',
27
+ iconSrc: '/asset/plugin/code/claude/claude.png',
28
+ isDefault: true,
29
+ category: 'CLI',
30
+ },
31
+ {
32
+ value: 'code/codex',
33
+ label: 'OpenAI Codex',
34
+ iconSrc: '/asset/plugin/code/codex/openai.webp',
35
+ isDefault: false,
36
+ category: 'CLI',
37
+ },
38
+ {
39
+ value: 'code/gemini',
40
+ label: 'Google Gemini CLI',
41
+ iconSrc: '/asset/plugin/code/gemini/gemini.jpeg',
42
+ isDefault: false,
43
+ category: 'CLI',
44
+ },
45
+ ];
23
46
  const INTENTS = {
24
47
  create_app: {
25
48
  label: 'Create app',
@@ -245,11 +268,11 @@
245
268
  })
246
269
  .then((payload) => {
247
270
  const tools = mapPluginMenuToTools(payload && Array.isArray(payload.menu) ? payload.menu : []);
248
- return tools;
271
+ return tools.length > 0 ? tools : FALLBACK_TOOLS.slice();
249
272
  })
250
273
  .catch((error) => {
251
- console.warn('Failed to load universal launcher plugins', error);
252
- return [];
274
+ console.warn('Falling back to default tools for universal launcher', error);
275
+ return FALLBACK_TOOLS.slice();
253
276
  })
254
277
  .finally(() => {
255
278
  loadingTools = null;
package/server/socket.js CHANGED
@@ -284,7 +284,7 @@ class Socket {
284
284
  } else {
285
285
  let buf = this.buffer[id]
286
286
  let sh = this.active_shell[id]
287
- this.subscribe(ws, id, buf, sh, req)
287
+ this.subscribe(ws, id, buf, sh)
288
288
  if (req.mode !== "listen") {
289
289
  // Run only if currently not running
290
290
  if (!this.parent.kernel.api.running[id]) {
@@ -308,7 +308,7 @@ class Socket {
308
308
  if (req.id) {
309
309
  let buf = this.buffer[req.id]
310
310
  let sh = this.active_shell[req.id]
311
- this.subscribe(ws, req.id, buf, sh, req)
311
+ this.subscribe(ws, req.id, buf, sh)
312
312
  if (req.mode === "listen") {
313
313
  return
314
314
  }
@@ -345,7 +345,13 @@ class Socket {
345
345
  // Mark local client sockets by IP matching any local address
346
346
  try {
347
347
  const ip = ws._ip || ''
348
- ws._isLocalClient = this.isLocalAddress(ip)
348
+ const isLocal = (addr) => {
349
+ if (!addr || typeof addr !== 'string') return false
350
+ if (this.localAddresses.has(addr)) return true
351
+ const v = addr.trim().toLowerCase()
352
+ return v.startsWith('::ffff:127.') || v.startsWith('127.')
353
+ }
354
+ ws._isLocalClient = isLocal(ip)
349
355
  if (ws._isLocalClient && ws._deviceId) {
350
356
  this.localDeviceIds.add(ws._deviceId)
351
357
  }
@@ -425,22 +431,18 @@ class Socket {
425
431
  this.old_buffer = structuredClone(this.buffer)
426
432
  }, 5000)
427
433
  }
428
- subscribe(ws, id, buf, sh, req = {}) {
434
+ subscribe(ws, id, buf, sh) {
429
435
  let resolvedShellId = sh || null
430
436
  let resolvedState = buf
431
437
  let hasState = typeof resolvedState === "string" ? resolvedState.length > 0 : Boolean(resolvedState)
432
- let resolvedShell = null
433
438
  if ((!resolvedShellId || !hasState) && this.parent && this.parent.kernel && this.parent.kernel.shell && Array.isArray(this.parent.kernel.shell.shells)) {
434
- const directShell = this.parent.kernel.shell.get(id)
435
- const liveDirectShell = directShell && directShell.done !== true ? directShell : null
436
- const groupedShell = liveDirectShell || this.parent.kernel.shell.shells.find((candidate) => {
439
+ const groupedShell = this.parent.kernel.shell.shells.find((candidate) => {
437
440
  return candidate
438
441
  && candidate.done !== true
439
442
  && typeof candidate.group === "string"
440
443
  && candidate.group === id
441
444
  })
442
445
  if (groupedShell) {
443
- resolvedShell = groupedShell
444
446
  if (!resolvedShellId) {
445
447
  resolvedShellId = groupedShell.id
446
448
  }
@@ -453,12 +455,6 @@ class Socket {
453
455
  }
454
456
  }
455
457
  }
456
- if (!resolvedShell && resolvedShellId && this.parent && this.parent.kernel && this.parent.kernel.shell) {
457
- resolvedShell = this.parent.kernel.shell.get(resolvedShellId)
458
- }
459
- if (resolvedShell && req && req.input) {
460
- resolvedShell.input = true
461
- }
462
458
  if (this.parent.kernel.api.running[id] || resolvedShellId || hasState) {
463
459
  ws.send(JSON.stringify({
464
460
  type: "connect",
@@ -656,13 +652,6 @@ class Socket {
656
652
  return this.localDeviceIds.has(deviceId)
657
653
  }
658
654
 
659
- isLocalAddress(addr) {
660
- if (!addr || typeof addr !== 'string') return false
661
- if (this.localAddresses.has(addr)) return true
662
- const v = addr.trim().toLowerCase()
663
- return v === 'localhost' || v === '::1' || v.startsWith('::ffff:127.') || v.startsWith('127.')
664
- }
665
-
666
655
  ensureNotificationBridge() {
667
656
  if (this.notificationBridgeDispose) {
668
657
  return