@jetcrab/pi-desk 1.1.1 → 1.1.5-dev

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 (119) hide show
  1. package/docs/pi-desk/README.md +47 -0
  2. package/docs/pi-desk/commands.md +76 -0
  3. package/docs/pi-desk/examples/local-application/browser/application.js +106 -0
  4. package/docs/pi-desk/examples/local-application/browser/entry.js +9 -0
  5. package/docs/pi-desk/examples/local-application/package.json +9 -0
  6. package/docs/pi-desk/examples/local-application/pi-desk.ts +11 -0
  7. package/docs/pi-desk/plugins.md +119 -0
  8. package/package.json +3 -2
  9. package/src/client/l2_biz/pi-settings/hooks/l2-use-pi-settings.ts +37 -21
  10. package/src/client/l2_biz/pi-settings/l2-pi-settings.tsx +37 -43
  11. package/src/client/l2_biz/pi-settings/views/l2-mcp-settings-editor.tsx +3 -1
  12. package/src/client/l2_biz/pi-settings/views/l2-mcp-settings-list.tsx +1 -1
  13. package/src/client/l2_biz/plugin-host/hooks/l2-use-plugin-catalog.ts +3 -1
  14. package/src/client/l2_biz/plugin-host/hooks/l2-use-plugin-download-source.ts +5 -1
  15. package/src/client/l2_biz/plugin-host/l2-plugin-capability-details.tsx +57 -41
  16. package/src/client/l2_biz/plugin-host/l2-plugin-management-controls.tsx +89 -116
  17. package/src/client/l2_biz/plugin-host/l2-plugin-management.tsx +492 -338
  18. package/src/client/l2_biz/plugin-host/l2-use-plugin-management.ts +72 -22
  19. package/src/client/l2_biz/plugin-host/views/l2-plugin-catalog-detail.tsx +104 -76
  20. package/src/client/l2_biz/plugin-host/views/l2-plugin-catalog-search.tsx +101 -56
  21. package/src/client/l2_biz/plugin-host/views/l2-plugin-direct-install.tsx +91 -59
  22. package/src/client/l2_biz/plugin-host/views/l2-plugin-download-source.tsx +36 -27
  23. package/src/client/l2_biz/plugin-host/views/l2-plugin-installed-list.tsx +218 -208
  24. package/src/client/l2_biz/plugin-host/views/l2-plugin-management-channel.tsx +12 -5
  25. package/src/client/l2_biz/plugin-host/views/l2-plugin-management-dialog.tsx +84 -106
  26. package/src/client/l2_biz/plugin-host/views/l2-plugin-readme.tsx +29 -15
  27. package/src/client/l2_biz/settings/hooks/l2-use-project-model-default-settings.ts +22 -11
  28. package/src/client/l2_biz/settings/l2-settings.tsx +6 -11
  29. package/src/client/l2_biz/settings/views/l2-project-model-default-settings.tsx +20 -14
  30. package/src/client/l2_biz/terminal/l2-terminal-workspace.tsx +35 -1
  31. package/src/client/l2_biz/workbench/file-workspace/l2-work-session-file-preview.tsx +6 -2
  32. package/src/client/l2_biz/workbench/hooks/l2-workbench-chat-viewport.ts +14 -1
  33. package/src/client/l2_biz/workbench/l2-workbench-branch-picker.tsx +33 -5
  34. package/src/client/l2_biz/workbench/l2-workbench-sidebar-layout.tsx +3 -1
  35. package/src/client/l2_biz/workbench/l2-workbench.tsx +20 -3
  36. package/src/client/l3_modules/conversation/l3-conversation-call-summary.tsx +0 -3
  37. package/src/client/l3_modules/project-files/l3-file-context-menu-content.tsx +1 -0
  38. package/src/client/l4_foundation/ui/l4-app-dialog.tsx +3 -1
  39. package/src/client/l4_foundation/ui/l4-image-viewer.tsx +21 -0
  40. package/src/client/l4_foundation/ui/shadcn/checkbox.tsx +27 -0
  41. package/src/client/l4_foundation/ui/shadcn/context-menu.tsx +8 -1
  42. package/src/client/l4_foundation/ui/shadcn/dropdown-menu.tsx +5 -0
  43. package/src/client/l4_foundation/ui/shadcn/popover.tsx +2 -0
  44. package/src/client/l4_foundation/ui/shadcn/select.tsx +2 -0
  45. package/src/client/l4_foundation/ui/shadcn/switch.tsx +31 -0
  46. package/src/client/l4_foundation/ui/shadcn/tabs.tsx +74 -0
  47. package/src/common/l2_biz/plugin/l2-plugin-management-messages.ts +52 -22
  48. package/src/common/l3_modules/conversation/l3-conversation-locale-messages.ts +2 -2
  49. package/src/common/l3_modules/conversation/l3-conversation-pidesk.ts +1 -1
  50. package/src/common/l4_foundation/plugin/l4-plugin-package.ts +1 -0
  51. package/src/server/l2_biz/plugin-management/l2-plugin-catalog.ts +16 -5
  52. package/src/server/l2_biz/plugin-management/l2-plugin-commands.ts +21 -1
  53. package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +21 -2
  54. package/src/server/l2_biz/plugin-management/l2-plugin-updates.ts +17 -3
  55. package/src/server/l4_foundation/pi/l4-pi-basic-session-services.ts +3 -3
  56. package/src/server/l4_foundation/pi/l4-pi-package-maintenance-runner.mts +4 -11
  57. package/src/server/l4_foundation/pi/l4-pi-plugin-registry-config.ts +52 -34
  58. package/src/server/l4_foundation/pi/l4-pi-plugin-registry-network.ts +5 -3
  59. package/src/server/l4_foundation/pi/l4-pi-plugin-registry.ts +23 -8
  60. package/src/server/l4_foundation/pi/l4-pi-session-initialization.ts +2 -5
  61. package/src/server/l4_foundation/pidesk/l4-pidesk-command.ts +8 -1
  62. package/src/server/l4_foundation/pidesk/l4-pidesk-runtime.ts +24 -38
  63. package/src/server/l4_foundation/pidesk/l4-pidesk-system-prompt.ts +11 -0
  64. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  65. package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
  66. package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
  67. package/temp/build/pi-desk/release/.next/react-loadable-manifest.json +1 -1
  68. package/temp/build/pi-desk/release/.next/required-server-files.js +3 -3
  69. package/temp/build/pi-desk/release/.next/required-server-files.json +3 -3
  70. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  71. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  72. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +3 -3
  73. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
  74. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +3 -3
  75. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  76. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  77. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  78. package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
  79. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  80. package/temp/build/pi-desk/release/.next/server/app/page.js +79 -79
  81. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  82. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -77
  83. package/temp/build/pi-desk/release/.next/server/chunks/{81107.js → 35348.js} +2 -2
  84. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +4 -4
  85. package/temp/build/pi-desk/release/.next/server/chunks/36361.js +1 -1
  86. package/temp/build/pi-desk/release/.next/server/chunks/47757.js +6 -75
  87. package/temp/build/pi-desk/release/.next/server/chunks/50520.js +4 -4
  88. package/temp/build/pi-desk/release/.next/server/chunks/58330.js +1 -1
  89. package/temp/build/pi-desk/release/.next/server/chunks/84231.js +2 -2
  90. package/temp/build/pi-desk/release/.next/server/chunks/89236.js +2 -2
  91. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +5 -5
  92. package/temp/build/pi-desk/release/.next/server/chunks/94518.js +1 -1
  93. package/temp/build/pi-desk/release/.next/server/chunks/9874.js +1 -1
  94. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  95. package/temp/build/pi-desk/release/.next/server/middleware-react-loadable-manifest.js +1 -1
  96. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  97. package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
  98. package/temp/build/pi-desk/release/.next/static/chunks/14197-3d3ddd426ac06c9c.js +3 -0
  99. package/temp/build/pi-desk/release/.next/static/chunks/34903-e4205c0becabea76.js +318 -0
  100. package/temp/build/pi-desk/release/.next/static/chunks/{54206.7c0792096df8a5cf.js → 54206.82a63ab971911eda.js} +3 -3
  101. package/temp/build/pi-desk/release/.next/static/chunks/74132-876f256c7a6101af.js +13 -0
  102. package/temp/build/pi-desk/release/.next/static/chunks/78923-17a9c337b29dcecd.js +1 -0
  103. package/temp/build/pi-desk/release/.next/static/chunks/96995-8f8313ea2ac3abd7.js +62 -0
  104. package/temp/build/pi-desk/release/.next/static/chunks/app/{layout-7c5409cced9c2501.js → layout-4faf3a52d219296d.js} +2 -2
  105. package/temp/build/pi-desk/release/.next/static/chunks/app/login/{page-8c87fb9e6c918848.js → page-bf893718bb151f3c.js} +1 -1
  106. package/temp/build/pi-desk/release/.next/static/chunks/app/page-28e1d77d6b884657.js +158 -0
  107. package/temp/build/pi-desk/release/.next/static/chunks/{webpack-45424d28099bbefa.js → webpack-7bfbf627379fb4c1.js} +1 -1
  108. package/temp/build/pi-desk/release/.next/static/css/3213ee28336bddc2.css +1 -0
  109. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  110. package/src/server/l4_foundation/pidesk/l4-pidesk-skill-template.ts +0 -87
  111. package/temp/build/pi-desk/release/.next/static/chunks/27491-8b2d3e345b9142ea.js +0 -318
  112. package/temp/build/pi-desk/release/.next/static/chunks/7089-600a8f5593b7846c.js +0 -3
  113. package/temp/build/pi-desk/release/.next/static/chunks/74132-0884df6a6f11861a.js +0 -13
  114. package/temp/build/pi-desk/release/.next/static/chunks/78923-539a8b5f7af3c54a.js +0 -1
  115. package/temp/build/pi-desk/release/.next/static/chunks/96995-ae32167974365050.js +0 -62
  116. package/temp/build/pi-desk/release/.next/static/chunks/app/page-39b146293b6eb488.js +0 -158
  117. package/temp/build/pi-desk/release/.next/static/css/56486914a8ba0a1b.css +0 -1
  118. /package/temp/build/pi-desk/release/.next/static/{STVrBHA3z9KPtvBE4WcE2 → IgHJ40fniC07-ioYUKobL}/_buildManifest.js +0 -0
  119. /package/temp/build/pi-desk/release/.next/static/{STVrBHA3z9KPtvBE4WcE2 → IgHJ40fniC07-ioYUKobL}/_ssgManifest.js +0 -0
@@ -1,6 +1,12 @@
1
1
  'use client'
2
2
 
3
3
  import { useTranslation } from 'react-i18next'
4
+ import { ChevronDownIcon } from 'lucide-react'
5
+ import {
6
+ Collapsible,
7
+ CollapsibleContent,
8
+ CollapsibleTrigger
9
+ } from '@client/l4_foundation/ui/shadcn/collapsible'
4
10
  import type {
5
11
  L2PluginCatalogDetail,
6
12
  L2PluginDownloadSource
@@ -61,69 +67,95 @@ export function L2PluginDirectInstall(props: DirectInstallProps): React.JSX.Elem
61
67
  id="plugin-direct-source"
62
68
  value={props.source}
63
69
  placeholder={t('batchSourcePlaceholder')}
64
- rows={3}
70
+ rows={2}
71
+ disabled={props.pending}
65
72
  onChange={(event) => props.onSource(event.target.value)}
66
73
  />
67
74
  {props.isNpm || props.multiple ? (
68
- <>
69
- <div className="flex flex-wrap items-center gap-2 text-sm">
70
- <span>{t('installChannel')}</span>
71
- <L2PluginManagementChannel
72
- value={props.tag}
73
- label={t('installChannel')}
74
- placeholder={t('defaultChannel')}
75
- onChange={props.onTag}
76
- />
77
- </div>
78
- {props.isNpm ? (
79
- <Button size="sm" variant="outline" disabled={props.loading} onClick={props.onRead}>
80
- {t(props.loading ? 'loadingPackage' : 'readPackage')}
81
- </Button>
82
- ) : null}
83
- {props.detail ? (
84
- <div className="flex flex-wrap items-center gap-2 text-sm">
85
- <span className="min-w-0 font-medium [overflow-wrap:anywhere]">
86
- {props.detail.name}
87
- </span>
88
- <Select
89
- value={props.selectedVersion}
90
- disabled={props.loading}
91
- items={[
92
- { value: '', label: t('automaticVersion') },
93
- ...[...new Set([props.detail.version, ...props.detail.versions])].map(
94
- (version) => ({ value: version, label: version })
95
- )
96
- ]}
97
- onValueChange={(version) => {
98
- if (version !== null) props.onVersion(version)
99
- }}
100
- >
101
- <SelectTrigger aria-label={t('version')} className="max-w-full">
102
- <SelectValue />
103
- </SelectTrigger>
104
- <SelectContent positionerClassName="z-[160]">
105
- <SelectItem value="">{t('automaticVersion')}</SelectItem>
106
- {[...new Set([props.detail.version, ...props.detail.versions])].map((version) => (
107
- <SelectItem key={version} value={version}>
108
- {version}
109
- </SelectItem>
110
- ))}
111
- </SelectContent>
112
- </Select>
113
- <span className="text-xs text-muted-foreground">
114
- {t('targetVersion', { version: props.detail.version })}
115
- </span>
75
+ <Collapsible>
76
+ <CollapsibleTrigger className="group flex min-h-8 items-center gap-2 text-sm font-medium outline-none focus-visible:ring-2 focus-visible:ring-ring">
77
+ {t('advancedOptions')}
78
+ <ChevronDownIcon className="size-4 transition-transform group-aria-expanded:rotate-180" />
79
+ </CollapsibleTrigger>
80
+ <CollapsibleContent keepMounted className="hidden data-open:block">
81
+ <div className="space-y-3 pt-2">
82
+ <div className="flex flex-wrap items-center gap-2 text-sm">
83
+ <span>{t('installChannel')}</span>
84
+ <L2PluginManagementChannel
85
+ value={props.tag}
86
+ label={t('installChannel')}
87
+ placeholder={t('defaultChannel')}
88
+ disabled={props.pending}
89
+ onChange={props.onTag}
90
+ />
91
+ </div>
92
+ {props.isNpm ? (
93
+ <Button size="sm" variant="outline" disabled={props.loading} onClick={props.onRead}>
94
+ {t(props.loading ? 'loadingPackage' : 'readPackage')}
95
+ </Button>
96
+ ) : null}
97
+ {props.detail ? (
98
+ <div className="flex flex-wrap items-center gap-2 text-sm">
99
+ <span className="min-w-0 font-medium [overflow-wrap:anywhere]">
100
+ {props.detail.name}
101
+ </span>
102
+ <Select
103
+ value={props.selectedVersion}
104
+ onOpenChange={(open, details) => {
105
+ if (open && (props.loading || props.pending)) details.cancel()
106
+ }}
107
+ items={[
108
+ { value: '', label: t('automaticVersion') },
109
+ ...[...new Set([props.detail.version, ...props.detail.versions])].map(
110
+ (version) => ({ value: version, label: version })
111
+ )
112
+ ]}
113
+ onValueChange={(version) => {
114
+ if (version !== null && !props.loading && !props.pending)
115
+ props.onVersion(version)
116
+ }}
117
+ >
118
+ <SelectTrigger
119
+ aria-label={t('version')}
120
+ aria-disabled={props.loading || props.pending}
121
+ className="max-w-full"
122
+ >
123
+ <SelectValue />
124
+ </SelectTrigger>
125
+ <SelectContent positionerClassName="z-[160]">
126
+ <SelectItem value="" disabled={props.loading || props.pending}>
127
+ {t('automaticVersion')}
128
+ </SelectItem>
129
+ {[...new Set([props.detail.version, ...props.detail.versions])].map(
130
+ (version) => (
131
+ <SelectItem
132
+ key={version}
133
+ value={version}
134
+ disabled={props.loading || props.pending}
135
+ >
136
+ {version}
137
+ </SelectItem>
138
+ )
139
+ )}
140
+ </SelectContent>
141
+ </Select>
142
+ <span className="text-xs text-muted-foreground">
143
+ {t('targetVersion', { version: props.detail.version })}
144
+ </span>
145
+ </div>
146
+ ) : null}
147
+ <L2PluginDownloadSourceSelector
148
+ id="plugin-direct-download"
149
+ mode={props.override}
150
+ registry={props.registry}
151
+ override
152
+ saving={props.pending}
153
+ onMode={props.onMode}
154
+ onRegistry={props.onRegistry}
155
+ />
116
156
  </div>
117
- ) : null}
118
- <L2PluginDownloadSourceSelector
119
- id="plugin-direct-download"
120
- mode={props.override}
121
- registry={props.registry}
122
- override
123
- onMode={props.onMode}
124
- onRegistry={props.onRegistry}
125
- />
126
- </>
157
+ </CollapsibleContent>
158
+ </Collapsible>
127
159
  ) : null}
128
160
  {props.error ? (
129
161
  <p
@@ -4,6 +4,13 @@ import { useTranslation } from 'react-i18next'
4
4
  import type { L2PluginDownloadSource } from '@common/l2_biz/plugin/l2-plugin-catalog-contract'
5
5
  import { Button } from '@client/l4_foundation/ui/shadcn/button'
6
6
  import { Input } from '@client/l4_foundation/ui/shadcn/input'
7
+ import {
8
+ Select,
9
+ SelectContent,
10
+ SelectItem,
11
+ SelectTrigger,
12
+ SelectValue
13
+ } from '@client/l4_foundation/ui/shadcn/select'
7
14
 
8
15
  interface DownloadSourceProps {
9
16
  id: string
@@ -43,35 +50,42 @@ export function L2PluginDownloadSourceSelector({
43
50
  : mode === 'official'
44
51
  ? 'https://registry.npmjs.org'
45
52
  : mode === 'domestic'
46
- ? 'https://registry.npmmirror.com'
53
+ ? 'https://mirrors.cloud.tencent.com/npm'
47
54
  : mode === 'custom'
48
55
  ? (savedRegistry ?? registry)
49
56
  : null
57
+ const options = [
58
+ ...(override ? [{ value: 'default' as const, label: t('useDefaultSource') }] : []),
59
+ ...(['local', 'auto', 'domestic', 'official', 'custom'] as const).map((value) => ({
60
+ value,
61
+ label: t(`download_${value}`)
62
+ }))
63
+ ]
50
64
  return (
51
- <div className="min-w-0 space-y-2 text-sm">
65
+ <div className="min-w-0 space-y-3 text-sm">
52
66
  <div className="flex flex-wrap items-center gap-2">
53
67
  <label htmlFor={id} className="font-medium">
54
68
  {t(override ? 'installDownloadSource' : 'downloadSource')}
55
69
  </label>
56
- <select
57
- id={id}
70
+ <Select
58
71
  value={mode}
59
- disabled={saving}
60
- onChange={(event) => onMode(event.target.value as DownloadSourceProps['mode'])}
61
- className="min-h-8 max-w-full rounded-lg border border-input bg-background px-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50"
72
+ items={options}
73
+ disabled={loading}
74
+ onValueChange={(value) => {
75
+ if (value && !saving) onMode(value)
76
+ }}
62
77
  >
63
- {override ? <option value="default">{t('useDefaultSource')}</option> : null}
64
- {(['auto', 'domestic', 'official', 'custom'] as const).map((value) => (
65
- <option key={value} value={value}>
66
- {t(`download_${value}`)}
67
- </option>
68
- ))}
69
- </select>
70
- {loading ? (
71
- <span role="status" className="text-muted-foreground">
72
- {t('recommending')}
73
- </span>
74
- ) : null}
78
+ <SelectTrigger id={id} className="max-w-full">
79
+ <SelectValue />
80
+ </SelectTrigger>
81
+ <SelectContent positionerClassName="z-[160]">
82
+ {options.map((option) => (
83
+ <SelectItem key={option.value} value={option.value} disabled={saving}>
84
+ {option.label}
85
+ </SelectItem>
86
+ ))}
87
+ </SelectContent>
88
+ </Select>
75
89
  {saving ? (
76
90
  <span role="status" className="text-muted-foreground">
77
91
  {t('saving')}
@@ -90,6 +104,7 @@ export function L2PluginDownloadSourceSelector({
90
104
  value={registry}
91
105
  placeholder="https://registry.example.com"
92
106
  className="min-w-0 flex-1 basis-48"
107
+ disabled={saving}
93
108
  onChange={(event) => onRegistry(event.target.value)}
94
109
  />
95
110
  {onSave ? (
@@ -99,14 +114,8 @@ export function L2PluginDownloadSourceSelector({
99
114
  ) : null}
100
115
  </div>
101
116
  </div>
102
- ) : null}
103
- {!override ? (
104
- <details>
105
- <summary className="cursor-pointer py-1 text-muted-foreground">
106
- {t('sourceDetails')}
107
- </summary>
108
- <p className="mt-1 break-all text-muted-foreground">{resolved ?? t('recommending')}</p>
109
- </details>
117
+ ) : !override && resolved ? (
118
+ <p className="break-all text-xs text-muted-foreground">{resolved}</p>
110
119
  ) : null}
111
120
  {error ? (
112
121
  <div role="alert" className="flex flex-wrap items-center gap-2 text-destructive">