@open-mercato/ai-assistant 0.4.2-canary-c02407ff85

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 (193) hide show
  1. package/AGENTS.md +1090 -0
  2. package/README.md +607 -0
  3. package/build.mjs +92 -0
  4. package/dist/di.js +8 -0
  5. package/dist/di.js.map +7 -0
  6. package/dist/frontend/components/CommandPalette/CommandFooter.js +80 -0
  7. package/dist/frontend/components/CommandPalette/CommandFooter.js.map +7 -0
  8. package/dist/frontend/components/CommandPalette/CommandHeader.js +53 -0
  9. package/dist/frontend/components/CommandPalette/CommandHeader.js.map +7 -0
  10. package/dist/frontend/components/CommandPalette/CommandInput.js +29 -0
  11. package/dist/frontend/components/CommandPalette/CommandInput.js.map +7 -0
  12. package/dist/frontend/components/CommandPalette/CommandItem.js +92 -0
  13. package/dist/frontend/components/CommandPalette/CommandItem.js.map +7 -0
  14. package/dist/frontend/components/CommandPalette/CommandPalette.js +244 -0
  15. package/dist/frontend/components/CommandPalette/CommandPalette.js.map +7 -0
  16. package/dist/frontend/components/CommandPalette/CommandPaletteProvider.js +42 -0
  17. package/dist/frontend/components/CommandPalette/CommandPaletteProvider.js.map +7 -0
  18. package/dist/frontend/components/CommandPalette/CommandPaletteWrapper.js +18 -0
  19. package/dist/frontend/components/CommandPalette/CommandPaletteWrapper.js.map +7 -0
  20. package/dist/frontend/components/CommandPalette/DebugPanel.js +215 -0
  21. package/dist/frontend/components/CommandPalette/DebugPanel.js.map +7 -0
  22. package/dist/frontend/components/CommandPalette/MessageBubble.js +64 -0
  23. package/dist/frontend/components/CommandPalette/MessageBubble.js.map +7 -0
  24. package/dist/frontend/components/CommandPalette/ToolCallConfirmation.js +91 -0
  25. package/dist/frontend/components/CommandPalette/ToolCallConfirmation.js.map +7 -0
  26. package/dist/frontend/components/CommandPalette/ToolCallDisplay.js +47 -0
  27. package/dist/frontend/components/CommandPalette/ToolCallDisplay.js.map +7 -0
  28. package/dist/frontend/components/CommandPalette/ToolChatPage.js +74 -0
  29. package/dist/frontend/components/CommandPalette/ToolChatPage.js.map +7 -0
  30. package/dist/frontend/components/CommandPalette/index.js +28 -0
  31. package/dist/frontend/components/CommandPalette/index.js.map +7 -0
  32. package/dist/frontend/constants.js +41 -0
  33. package/dist/frontend/constants.js.map +7 -0
  34. package/dist/frontend/hooks/index.js +13 -0
  35. package/dist/frontend/hooks/index.js.map +7 -0
  36. package/dist/frontend/hooks/useCommandPalette.js +1094 -0
  37. package/dist/frontend/hooks/useCommandPalette.js.map +7 -0
  38. package/dist/frontend/hooks/useMcpTools.js +66 -0
  39. package/dist/frontend/hooks/useMcpTools.js.map +7 -0
  40. package/dist/frontend/hooks/usePageContext.js +48 -0
  41. package/dist/frontend/hooks/usePageContext.js.map +7 -0
  42. package/dist/frontend/hooks/useRecentActions.js +56 -0
  43. package/dist/frontend/hooks/useRecentActions.js.map +7 -0
  44. package/dist/frontend/hooks/useRecentTools.js +55 -0
  45. package/dist/frontend/hooks/useRecentTools.js.map +7 -0
  46. package/dist/frontend/index.js +35 -0
  47. package/dist/frontend/index.js.map +7 -0
  48. package/dist/frontend/types.js +1 -0
  49. package/dist/frontend/types.js.map +7 -0
  50. package/dist/frontend/utils/index.js +7 -0
  51. package/dist/frontend/utils/index.js.map +7 -0
  52. package/dist/frontend/utils/toolMatcher.js +95 -0
  53. package/dist/frontend/utils/toolMatcher.js.map +7 -0
  54. package/dist/index.js +57 -0
  55. package/dist/index.js.map +7 -0
  56. package/dist/modules/ai_assistant/acl.js +14 -0
  57. package/dist/modules/ai_assistant/acl.js.map +7 -0
  58. package/dist/modules/ai_assistant/api/chat/route.js +152 -0
  59. package/dist/modules/ai_assistant/api/chat/route.js.map +7 -0
  60. package/dist/modules/ai_assistant/api/health/route.js +27 -0
  61. package/dist/modules/ai_assistant/api/health/route.js.map +7 -0
  62. package/dist/modules/ai_assistant/api/route/route.js +123 -0
  63. package/dist/modules/ai_assistant/api/route/route.js.map +7 -0
  64. package/dist/modules/ai_assistant/api/settings/route.js +60 -0
  65. package/dist/modules/ai_assistant/api/settings/route.js.map +7 -0
  66. package/dist/modules/ai_assistant/api/tools/execute/route.js +58 -0
  67. package/dist/modules/ai_assistant/api/tools/execute/route.js.map +7 -0
  68. package/dist/modules/ai_assistant/api/tools/route.js +48 -0
  69. package/dist/modules/ai_assistant/api/tools/route.js.map +7 -0
  70. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js +10 -0
  71. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js.map +7 -0
  72. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js +28 -0
  73. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js.map +7 -0
  74. package/dist/modules/ai_assistant/cli.js +192 -0
  75. package/dist/modules/ai_assistant/cli.js.map +7 -0
  76. package/dist/modules/ai_assistant/di.js +11 -0
  77. package/dist/modules/ai_assistant/di.js.map +7 -0
  78. package/dist/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.js +257 -0
  79. package/dist/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.js.map +7 -0
  80. package/dist/modules/ai_assistant/index.js +13 -0
  81. package/dist/modules/ai_assistant/index.js.map +7 -0
  82. package/dist/modules/ai_assistant/lib/ai-sdk.js +13 -0
  83. package/dist/modules/ai_assistant/lib/ai-sdk.js.map +7 -0
  84. package/dist/modules/ai_assistant/lib/api-discovery-tools.js +249 -0
  85. package/dist/modules/ai_assistant/lib/api-discovery-tools.js.map +7 -0
  86. package/dist/modules/ai_assistant/lib/api-endpoint-index-config.js +177 -0
  87. package/dist/modules/ai_assistant/lib/api-endpoint-index-config.js.map +7 -0
  88. package/dist/modules/ai_assistant/lib/api-endpoint-index.js +210 -0
  89. package/dist/modules/ai_assistant/lib/api-endpoint-index.js.map +7 -0
  90. package/dist/modules/ai_assistant/lib/auth.js +87 -0
  91. package/dist/modules/ai_assistant/lib/auth.js.map +7 -0
  92. package/dist/modules/ai_assistant/lib/chat-config.js +117 -0
  93. package/dist/modules/ai_assistant/lib/chat-config.js.map +7 -0
  94. package/dist/modules/ai_assistant/lib/client-factory.js +60 -0
  95. package/dist/modules/ai_assistant/lib/client-factory.js.map +7 -0
  96. package/dist/modules/ai_assistant/lib/http-server.js +367 -0
  97. package/dist/modules/ai_assistant/lib/http-server.js.map +7 -0
  98. package/dist/modules/ai_assistant/lib/in-process-client.js +126 -0
  99. package/dist/modules/ai_assistant/lib/in-process-client.js.map +7 -0
  100. package/dist/modules/ai_assistant/lib/mcp-client.js +146 -0
  101. package/dist/modules/ai_assistant/lib/mcp-client.js.map +7 -0
  102. package/dist/modules/ai_assistant/lib/mcp-dev-server.js +283 -0
  103. package/dist/modules/ai_assistant/lib/mcp-dev-server.js.map +7 -0
  104. package/dist/modules/ai_assistant/lib/mcp-server-config.js +160 -0
  105. package/dist/modules/ai_assistant/lib/mcp-server-config.js.map +7 -0
  106. package/dist/modules/ai_assistant/lib/mcp-server.js +156 -0
  107. package/dist/modules/ai_assistant/lib/mcp-server.js.map +7 -0
  108. package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js +44 -0
  109. package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js.map +7 -0
  110. package/dist/modules/ai_assistant/lib/opencode-client.js +247 -0
  111. package/dist/modules/ai_assistant/lib/opencode-client.js.map +7 -0
  112. package/dist/modules/ai_assistant/lib/opencode-handlers.js +398 -0
  113. package/dist/modules/ai_assistant/lib/opencode-handlers.js.map +7 -0
  114. package/dist/modules/ai_assistant/lib/schema-utils.js +94 -0
  115. package/dist/modules/ai_assistant/lib/schema-utils.js.map +7 -0
  116. package/dist/modules/ai_assistant/lib/tool-executor.js +55 -0
  117. package/dist/modules/ai_assistant/lib/tool-executor.js.map +7 -0
  118. package/dist/modules/ai_assistant/lib/tool-index-config.js +125 -0
  119. package/dist/modules/ai_assistant/lib/tool-index-config.js.map +7 -0
  120. package/dist/modules/ai_assistant/lib/tool-loader.js +88 -0
  121. package/dist/modules/ai_assistant/lib/tool-loader.js.map +7 -0
  122. package/dist/modules/ai_assistant/lib/tool-registry.js +65 -0
  123. package/dist/modules/ai_assistant/lib/tool-registry.js.map +7 -0
  124. package/dist/modules/ai_assistant/lib/tool-search.js +192 -0
  125. package/dist/modules/ai_assistant/lib/tool-search.js.map +7 -0
  126. package/dist/modules/ai_assistant/lib/types.js +1 -0
  127. package/dist/modules/ai_assistant/lib/types.js.map +7 -0
  128. package/package.json +108 -0
  129. package/src/di.ts +11 -0
  130. package/src/frontend/components/CommandPalette/CommandFooter.tsx +113 -0
  131. package/src/frontend/components/CommandPalette/CommandHeader.tsx +76 -0
  132. package/src/frontend/components/CommandPalette/CommandInput.tsx +50 -0
  133. package/src/frontend/components/CommandPalette/CommandItem.tsx +111 -0
  134. package/src/frontend/components/CommandPalette/CommandPalette.tsx +276 -0
  135. package/src/frontend/components/CommandPalette/CommandPaletteProvider.tsx +60 -0
  136. package/src/frontend/components/CommandPalette/CommandPaletteWrapper.tsx +21 -0
  137. package/src/frontend/components/CommandPalette/DebugPanel.tsx +257 -0
  138. package/src/frontend/components/CommandPalette/MessageBubble.tsx +73 -0
  139. package/src/frontend/components/CommandPalette/ToolCallConfirmation.tsx +130 -0
  140. package/src/frontend/components/CommandPalette/ToolCallDisplay.tsx +57 -0
  141. package/src/frontend/components/CommandPalette/ToolChatPage.tsx +125 -0
  142. package/src/frontend/components/CommandPalette/index.ts +14 -0
  143. package/src/frontend/constants.ts +35 -0
  144. package/src/frontend/hooks/index.ts +5 -0
  145. package/src/frontend/hooks/useCommandPalette.ts +1389 -0
  146. package/src/frontend/hooks/useMcpTools.ts +73 -0
  147. package/src/frontend/hooks/usePageContext.ts +61 -0
  148. package/src/frontend/hooks/useRecentActions.ts +64 -0
  149. package/src/frontend/hooks/useRecentTools.ts +69 -0
  150. package/src/frontend/index.ts +39 -0
  151. package/src/frontend/types.ts +260 -0
  152. package/src/frontend/utils/index.ts +1 -0
  153. package/src/frontend/utils/toolMatcher.ts +127 -0
  154. package/src/index.ts +92 -0
  155. package/src/modules/ai_assistant/acl.ts +10 -0
  156. package/src/modules/ai_assistant/api/chat/route.ts +213 -0
  157. package/src/modules/ai_assistant/api/health/route.ts +30 -0
  158. package/src/modules/ai_assistant/api/route/route.ts +149 -0
  159. package/src/modules/ai_assistant/api/settings/route.ts +73 -0
  160. package/src/modules/ai_assistant/api/tools/execute/route.ts +71 -0
  161. package/src/modules/ai_assistant/api/tools/route.ts +57 -0
  162. package/src/modules/ai_assistant/backend/config/ai-assistant/page.meta.ts +26 -0
  163. package/src/modules/ai_assistant/backend/config/ai-assistant/page.tsx +12 -0
  164. package/src/modules/ai_assistant/cli.ts +233 -0
  165. package/src/modules/ai_assistant/di.ts +9 -0
  166. package/src/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.tsx +418 -0
  167. package/src/modules/ai_assistant/index.ts +11 -0
  168. package/src/modules/ai_assistant/lib/ai-sdk.ts +5 -0
  169. package/src/modules/ai_assistant/lib/api-discovery-tools.ts +334 -0
  170. package/src/modules/ai_assistant/lib/api-endpoint-index-config.ts +243 -0
  171. package/src/modules/ai_assistant/lib/api-endpoint-index.ts +381 -0
  172. package/src/modules/ai_assistant/lib/auth.ts +185 -0
  173. package/src/modules/ai_assistant/lib/chat-config.ts +152 -0
  174. package/src/modules/ai_assistant/lib/client-factory.ts +130 -0
  175. package/src/modules/ai_assistant/lib/http-server.ts +498 -0
  176. package/src/modules/ai_assistant/lib/in-process-client.ts +205 -0
  177. package/src/modules/ai_assistant/lib/mcp-client.ts +221 -0
  178. package/src/modules/ai_assistant/lib/mcp-dev-server.ts +373 -0
  179. package/src/modules/ai_assistant/lib/mcp-server-config.ts +287 -0
  180. package/src/modules/ai_assistant/lib/mcp-server.ts +214 -0
  181. package/src/modules/ai_assistant/lib/mcp-tool-adapter.ts +76 -0
  182. package/src/modules/ai_assistant/lib/opencode-client.ts +426 -0
  183. package/src/modules/ai_assistant/lib/opencode-handlers.ts +676 -0
  184. package/src/modules/ai_assistant/lib/schema-utils.ts +142 -0
  185. package/src/modules/ai_assistant/lib/tool-executor.ts +71 -0
  186. package/src/modules/ai_assistant/lib/tool-index-config.ts +178 -0
  187. package/src/modules/ai_assistant/lib/tool-loader.ts +149 -0
  188. package/src/modules/ai_assistant/lib/tool-registry.ts +114 -0
  189. package/src/modules/ai_assistant/lib/tool-search.ts +308 -0
  190. package/src/modules/ai_assistant/lib/types.ts +147 -0
  191. package/test-schema.ts +37 -0
  192. package/tsconfig.json +10 -0
  193. package/watch.mjs +6 -0
package/package.json ADDED
@@ -0,0 +1,108 @@
1
+ {
2
+ "name": "@open-mercato/ai-assistant",
3
+ "version": "0.4.2-canary-c02407ff85",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "scripts": {
7
+ "build": "node build.mjs",
8
+ "watch": "node watch.mjs",
9
+ "mcp:dev": "mercato ai_assistant mcp:dev",
10
+ "mcp:serve-http": "mercato ai_assistant mcp:serve-http"
11
+ },
12
+ "exports": {
13
+ ".": "./dist/index.js",
14
+ "./modules/ai_assistant": {
15
+ "types": "./src/modules/ai_assistant/index.ts",
16
+ "default": "./dist/modules/ai_assistant/index.js"
17
+ },
18
+ "./tools": {
19
+ "types": "./src/modules/ai_assistant/lib/tool-registry.ts",
20
+ "default": "./dist/modules/ai_assistant/lib/tool-registry.js"
21
+ },
22
+ "./types": {
23
+ "types": "./src/modules/ai_assistant/lib/types.ts",
24
+ "default": "./dist/modules/ai_assistant/lib/types.js"
25
+ },
26
+ "./ai-sdk": {
27
+ "types": "./src/modules/ai_assistant/lib/ai-sdk.ts",
28
+ "default": "./dist/modules/ai_assistant/lib/ai-sdk.js"
29
+ },
30
+ "./frontend": {
31
+ "types": "./src/frontend/index.ts",
32
+ "default": "./dist/frontend/index.js"
33
+ },
34
+ "./*.ts": {
35
+ "types": "./src/*.ts",
36
+ "default": "./dist/*.js"
37
+ },
38
+ "./*.tsx": {
39
+ "types": "./src/*.tsx",
40
+ "default": "./dist/*.js"
41
+ },
42
+ "./*.json": "./src/*.json",
43
+ "./*": {
44
+ "types": [
45
+ "./src/*.ts",
46
+ "./src/*.tsx"
47
+ ],
48
+ "default": "./dist/*.js"
49
+ },
50
+ "./*/*.json": "./src/*/*.json",
51
+ "./*/*": {
52
+ "types": [
53
+ "./src/*/*.ts",
54
+ "./src/*/*.tsx"
55
+ ],
56
+ "default": "./dist/*/*.js"
57
+ },
58
+ "./*/*/*.json": "./src/*/*/*.json",
59
+ "./*/*/*": {
60
+ "types": [
61
+ "./src/*/*/*.ts",
62
+ "./src/*/*/*.tsx"
63
+ ],
64
+ "default": "./dist/*/*/*.js"
65
+ },
66
+ "./*/*/*/*.json": "./src/*/*/*/*.json",
67
+ "./*/*/*/*": {
68
+ "types": [
69
+ "./src/*/*/*/*.ts",
70
+ "./src/*/*/*/*.tsx"
71
+ ],
72
+ "default": "./dist/*/*/*/*.js"
73
+ },
74
+ "./*/*/*/*/*.json": "./src/*/*/*/*/*.json",
75
+ "./*/*/*/*/*": {
76
+ "types": [
77
+ "./src/*/*/*/*/*.ts",
78
+ "./src/*/*/*/*/*.tsx"
79
+ ],
80
+ "default": "./dist/*/*/*/*/*.js"
81
+ }
82
+ },
83
+ "dependencies": {
84
+ "@ai-sdk/anthropic": "^3.0.12",
85
+ "@ai-sdk/google": "^1.2.6",
86
+ "@ai-sdk/openai": "^3.0.5",
87
+ "@modelcontextprotocol/sdk": "^1.25.2",
88
+ "ai": "^6.0.33",
89
+ "cmdk": "^1.0.0",
90
+ "framer-motion": "^11.0.0",
91
+ "react-json-view-lite": "^2.5.0",
92
+ "react-markdown": "^9.0.0",
93
+ "zod-to-json-schema": "^3.25.1"
94
+ },
95
+ "peerDependencies": {
96
+ "@open-mercato/shared": "0.4.2-canary-c02407ff85",
97
+ "@open-mercato/ui": "0.4.2-canary-c02407ff85",
98
+ "zod": ">=3.23.0"
99
+ },
100
+ "devDependencies": {
101
+ "@open-mercato/cli": "0.4.2-canary-c02407ff85",
102
+ "tsx": "^4.21.0"
103
+ },
104
+ "publishConfig": {
105
+ "access": "public"
106
+ },
107
+ "stableVersion": "0.3.13"
108
+ }
package/src/di.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { AwilixContainer } from 'awilix'
2
+
3
+ /**
4
+ * Register AI Assistant module services in the DI container.
5
+ *
6
+ * This is called by the app bootstrap to register package-level services.
7
+ */
8
+ export async function register(container: AwilixContainer): Promise<void> {
9
+ const { register: registerModule } = await import('./modules/ai_assistant/di')
10
+ registerModule(container)
11
+ }
@@ -0,0 +1,113 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Code, ShieldCheck } from 'lucide-react'
5
+ import { cn } from '@open-mercato/shared/lib/utils'
6
+ import type { PalettePhase, ConnectionStatus } from '../../types'
7
+
8
+ interface CommandFooterProps {
9
+ phase: PalettePhase
10
+ connectionStatus: ConnectionStatus
11
+ isSessionAuthorized?: boolean
12
+ showDebug?: boolean
13
+ onToggleDebug?: () => void
14
+ }
15
+
16
+ function ConnectionIndicator({ status }: { status: ConnectionStatus }) {
17
+ const statusConfig: Record<ConnectionStatus, { color: string; text: string }> = {
18
+ connected: { color: 'bg-emerald-500', text: 'Connected' },
19
+ connecting: { color: 'bg-yellow-500 animate-pulse', text: 'Connecting...' },
20
+ disconnected: { color: 'bg-gray-400', text: 'Disconnected' },
21
+ error: { color: 'bg-red-500', text: 'Error' },
22
+ }
23
+
24
+ const config = statusConfig[status]
25
+
26
+ return (
27
+ <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
28
+ <div className={cn('h-1.5 w-1.5 rounded-full', config.color)} />
29
+ <span>{config.text}</span>
30
+ </div>
31
+ )
32
+ }
33
+
34
+ function KeyboardShortcut({ keys }: { keys: string[] }) {
35
+ return (
36
+ <div className="flex items-center gap-0.5">
37
+ {keys.map((key, i) => (
38
+ <kbd
39
+ key={i}
40
+ className={cn(
41
+ 'inline-flex h-5 min-w-[20px] items-center justify-center rounded',
42
+ 'bg-muted px-1.5 text-[10px] font-medium text-muted-foreground'
43
+ )}
44
+ >
45
+ {key}
46
+ </kbd>
47
+ ))}
48
+ </div>
49
+ )
50
+ }
51
+
52
+ export function CommandFooter({
53
+ phase,
54
+ connectionStatus,
55
+ isSessionAuthorized = false,
56
+ showDebug = false,
57
+ onToggleDebug,
58
+ }: CommandFooterProps) {
59
+ const idleShortcuts = [
60
+ { label: 'Submit', keys: ['\u21B5'] },
61
+ { label: 'Close', keys: ['Esc'] },
62
+ ]
63
+
64
+ const chatShortcuts = [
65
+ { label: 'Send', keys: ['\u21B5'] },
66
+ { label: 'Back', keys: ['Esc'] },
67
+ ]
68
+
69
+ const shortcuts = phase === 'idle' ? idleShortcuts : chatShortcuts
70
+
71
+ return (
72
+ <div className="relative flex items-center justify-between px-3 py-2 border-t bg-muted/20 text-xs">
73
+ <div className="flex items-center gap-3">
74
+ <ConnectionIndicator status={connectionStatus} />
75
+
76
+ {/* Session authorization indicator */}
77
+ {isSessionAuthorized && (
78
+ <div className="flex items-center gap-1 text-xs text-emerald-600 dark:text-emerald-400">
79
+ <ShieldCheck className="h-3 w-3" />
80
+ <span>Authorized</span>
81
+ </div>
82
+ )}
83
+
84
+ {/* Debug toggle button */}
85
+ {onToggleDebug && (
86
+ <button
87
+ type="button"
88
+ onClick={onToggleDebug}
89
+ className={cn(
90
+ 'flex items-center gap-1 transition-colors',
91
+ showDebug
92
+ ? 'text-blue-500 hover:text-blue-400'
93
+ : 'text-muted-foreground hover:text-foreground'
94
+ )}
95
+ title="Toggle debug panel"
96
+ >
97
+ <Code className="w-3 h-3" />
98
+ <span>{showDebug ? 'Hide Debug' : 'Debug'}</span>
99
+ </button>
100
+ )}
101
+ </div>
102
+
103
+ <div className="flex items-center gap-3">
104
+ {shortcuts.map((shortcut, i) => (
105
+ <div key={i} className="flex items-center gap-1.5 text-muted-foreground">
106
+ <span>{shortcut.label}</span>
107
+ <KeyboardShortcut keys={shortcut.keys} />
108
+ </div>
109
+ ))}
110
+ </div>
111
+ </div>
112
+ )
113
+ }
@@ -0,0 +1,76 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { ArrowLeft, Wrench, MessageSquare } from 'lucide-react'
5
+ import { cn } from '@open-mercato/shared/lib/utils'
6
+ import type { PalettePhase, ToolInfo } from '../../types'
7
+
8
+ interface CommandHeaderProps {
9
+ phase: PalettePhase
10
+ selectedTool: ToolInfo | null
11
+ onBack: () => void
12
+ }
13
+
14
+ export function CommandHeader({ phase, selectedTool, onBack }: CommandHeaderProps) {
15
+ // Only show header when not in idle phase
16
+ if (phase === 'idle') {
17
+ return null
18
+ }
19
+
20
+ // Show routing header
21
+ if (phase === 'routing') {
22
+ return (
23
+ <div className="flex items-center gap-2 px-3 py-2 border-b bg-muted/30">
24
+ <button
25
+ type="button"
26
+ onClick={onBack}
27
+ className={cn(
28
+ 'flex items-center justify-center h-6 w-6 rounded-md',
29
+ 'hover:bg-muted transition-colors',
30
+ 'text-muted-foreground hover:text-foreground'
31
+ )}
32
+ >
33
+ <ArrowLeft className="h-4 w-4" />
34
+ </button>
35
+ <span className="text-sm text-muted-foreground">Processing...</span>
36
+ </div>
37
+ )
38
+ }
39
+
40
+ // Show chatting/confirming/executing header
41
+ return (
42
+ <div className="flex items-center gap-2 px-3 py-2 border-b bg-muted/30">
43
+ <button
44
+ type="button"
45
+ onClick={onBack}
46
+ className={cn(
47
+ 'flex items-center justify-center h-6 w-6 rounded-md',
48
+ 'hover:bg-muted transition-colors',
49
+ 'text-muted-foreground hover:text-foreground'
50
+ )}
51
+ >
52
+ <ArrowLeft className="h-4 w-4" />
53
+ </button>
54
+
55
+ {selectedTool ? (
56
+ <div className="flex items-center gap-2 flex-1 min-w-0">
57
+ <div className="flex items-center justify-center h-6 w-6 rounded bg-primary/10 text-primary">
58
+ <Wrench className="h-3 w-3" />
59
+ </div>
60
+ <div className="flex-1 min-w-0">
61
+ <p className="text-sm font-medium truncate">{selectedTool.name}</p>
62
+ </div>
63
+ </div>
64
+ ) : (
65
+ <div className="flex items-center gap-2 flex-1 min-w-0">
66
+ <div className="flex items-center justify-center h-6 w-6 rounded bg-primary/10 text-primary">
67
+ <MessageSquare className="h-3 w-3" />
68
+ </div>
69
+ <div className="flex-1 min-w-0">
70
+ <p className="text-sm font-medium truncate">Chat</p>
71
+ </div>
72
+ </div>
73
+ )}
74
+ </div>
75
+ )
76
+ }
@@ -0,0 +1,50 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Command } from 'cmdk'
5
+ import { Search, MessageSquare, Loader2 } from 'lucide-react'
6
+ import { cn } from '@open-mercato/shared/lib/utils'
7
+ import type { CommandPaletteMode } from '../../types'
8
+
9
+ interface CommandInputProps {
10
+ value: string
11
+ onValueChange: (value: string) => void
12
+ mode: CommandPaletteMode
13
+ isLoading?: boolean
14
+ placeholder?: string
15
+ }
16
+
17
+ export function CommandInput({ value, onValueChange, mode, isLoading, placeholder }: CommandInputProps) {
18
+ const defaultPlaceholder = mode === 'chat' ? 'Ask AI...' : 'Search commands or ask AI...'
19
+
20
+ return (
21
+ <div className="flex items-center gap-2 border-b px-4 py-3">
22
+ <div className="flex items-center justify-center w-5 h-5 text-muted-foreground">
23
+ {isLoading ? (
24
+ <Loader2 className="h-4 w-4 animate-spin" />
25
+ ) : mode === 'chat' ? (
26
+ <MessageSquare className="h-4 w-4" />
27
+ ) : (
28
+ <Search className="h-4 w-4" />
29
+ )}
30
+ </div>
31
+
32
+ <Command.Input
33
+ value={value}
34
+ onValueChange={onValueChange}
35
+ placeholder={placeholder || defaultPlaceholder}
36
+ className={cn(
37
+ 'flex-1 bg-transparent text-sm outline-none',
38
+ 'placeholder:text-muted-foreground'
39
+ )}
40
+ autoFocus
41
+ />
42
+
43
+ {mode === 'chat' && (
44
+ <span className="text-xs text-muted-foreground bg-muted px-2 py-0.5 rounded">
45
+ AI
46
+ </span>
47
+ )}
48
+ </div>
49
+ )
50
+ }
@@ -0,0 +1,111 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Command } from 'cmdk'
5
+ import {
6
+ Plus,
7
+ Edit,
8
+ Trash,
9
+ Search,
10
+ Eye,
11
+ List,
12
+ Package,
13
+ Users,
14
+ ShoppingCart,
15
+ Calendar,
16
+ Lock,
17
+ BookOpen,
18
+ Folder,
19
+ DollarSign,
20
+ ToggleLeft,
21
+ Zap,
22
+ } from 'lucide-react'
23
+ import type { LucideIcon } from 'lucide-react'
24
+ import { cn } from '@open-mercato/shared/lib/utils'
25
+ import type { ToolInfo } from '../../types'
26
+ import { humanizeToolName } from '../../utils/toolMatcher'
27
+
28
+ interface CommandItemProps {
29
+ tool: ToolInfo
30
+ isSelected: boolean
31
+ onSelect: () => void
32
+ }
33
+
34
+ const MODULE_ICONS: Record<string, LucideIcon> = {
35
+ customers: Users,
36
+ catalog: Package,
37
+ sales: ShoppingCart,
38
+ search: Search,
39
+ auth: Lock,
40
+ dictionaries: BookOpen,
41
+ directory: Folder,
42
+ currencies: DollarSign,
43
+ feature_toggles: ToggleLeft,
44
+ }
45
+
46
+ const ACTION_ICONS: Record<string, LucideIcon> = {
47
+ create: Plus,
48
+ update: Edit,
49
+ delete: Trash,
50
+ search: Search,
51
+ query: Search,
52
+ get: Eye,
53
+ list: List,
54
+ }
55
+
56
+ function getIcon(tool: ToolInfo): LucideIcon {
57
+ // First try to match action
58
+ const nameParts = tool.name.split('.')
59
+ const action = nameParts[nameParts.length - 1]
60
+ if (ACTION_ICONS[action]) {
61
+ return ACTION_ICONS[action]
62
+ }
63
+
64
+ // Then try module
65
+ const module = tool.module || nameParts[0]
66
+ if (MODULE_ICONS[module]) {
67
+ return MODULE_ICONS[module]
68
+ }
69
+
70
+ return Zap
71
+ }
72
+
73
+ export function CommandItem({ tool, isSelected, onSelect }: CommandItemProps) {
74
+ const Icon = getIcon(tool)
75
+ const displayName = humanizeToolName(tool.name)
76
+ const module = tool.module || tool.name.split('.')[0]
77
+
78
+ return (
79
+ <Command.Item
80
+ value={tool.name}
81
+ onSelect={onSelect}
82
+ className={cn(
83
+ 'flex items-center gap-3 px-3 py-2 cursor-pointer rounded-md',
84
+ 'text-sm text-foreground',
85
+ isSelected
86
+ ? 'bg-accent text-accent-foreground'
87
+ : 'hover:bg-accent/50'
88
+ )}
89
+ >
90
+ <div
91
+ className={cn(
92
+ 'flex items-center justify-center w-8 h-8 rounded-md',
93
+ 'bg-muted text-muted-foreground'
94
+ )}
95
+ >
96
+ <Icon className="h-4 w-4" />
97
+ </div>
98
+
99
+ <div className="flex-1 min-w-0">
100
+ <div className="font-medium truncate">{displayName}</div>
101
+ <div className="text-xs text-muted-foreground truncate">
102
+ {tool.description}
103
+ </div>
104
+ </div>
105
+
106
+ <span className="text-xs text-muted-foreground capitalize">
107
+ {module}
108
+ </span>
109
+ </Command.Item>
110
+ )
111
+ }