@vibe-forge/client 0.2.0-alpha.9 → 0.4.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 (166) hide show
  1. package/cli.cjs +1 -1
  2. package/dist/assets/{arc-CybT1Fs2.js → arc-DgIxeTMg.js} +1 -1
  3. package/dist/assets/{blockDiagram-c4efeb88-BY5Aoa-D.js → blockDiagram-c4efeb88-CEAob3X9.js} +1 -1
  4. package/dist/assets/{c4Diagram-c83219d4-F42hTbzS.js → c4Diagram-c83219d4-DwIxpDKd.js} +1 -1
  5. package/dist/assets/channel-DhtnrNJ6.js +1 -0
  6. package/dist/assets/{classDiagram-beda092f-D-tIPp-3.js → classDiagram-beda092f-Cz1q8u_0.js} +1 -1
  7. package/dist/assets/{classDiagram-v2-2358418a-J57aCe6u.js → classDiagram-v2-2358418a-CImgTuwd.js} +1 -1
  8. package/dist/assets/clone-7bHB6YkC.js +1 -0
  9. package/dist/assets/{createText-1719965b-ByfEqOF-.js → createText-1719965b-C1_HJcCc.js} +1 -1
  10. package/dist/assets/devicon-BWlTeAUU.woff +0 -0
  11. package/dist/assets/devicon-CirD-cQx.ttf +0 -0
  12. package/dist/assets/devicon-Dg8iWy0i.svg +1211 -0
  13. package/dist/assets/devicon-TqfHp33-.eot +0 -0
  14. package/dist/assets/{edges-96097737-CMEArkOa.js → edges-96097737-BU8qStzd.js} +1 -1
  15. package/dist/assets/{erDiagram-0228fc6a-Cf8mX2aj.js → erDiagram-0228fc6a-DNA1Fz2L.js} +1 -1
  16. package/dist/assets/{flowDb-c6c81e3f-DG6WKyo7.js → flowDb-c6c81e3f-DjiCStMN.js} +1 -1
  17. package/dist/assets/{flowDiagram-50d868cf-CstUxz-w.js → flowDiagram-50d868cf-CSDi0-RD.js} +1 -1
  18. package/dist/assets/flowDiagram-v2-4f6560a1-_13Sz5Wh.js +1 -0
  19. package/dist/assets/{flowchart-elk-definition-6af322e1--4CRoQ-H.js → flowchart-elk-definition-6af322e1-DrhIMas7.js} +1 -1
  20. package/dist/assets/{ganttDiagram-a2739b55-DYgHcKd-.js → ganttDiagram-a2739b55-CTZnUP5z.js} +1 -1
  21. package/dist/assets/{gitGraphDiagram-82fe8481-DDSVpfsd.js → gitGraphDiagram-82fe8481-COOW7jTi.js} +1 -1
  22. package/dist/assets/{graph-CRWF39gX.js → graph-CIkpD4Kx.js} +1 -1
  23. package/dist/assets/{index-5325376f-W1hft795.js → index-5325376f-aVVRRTIu.js} +1 -1
  24. package/dist/assets/index-D1giUI7r.css +1 -0
  25. package/dist/assets/index-DRSI_ZIL.js +514 -0
  26. package/dist/assets/{infoDiagram-8eee0895-D4SHcix6.js → infoDiagram-8eee0895-DQpZ1LVD.js} +1 -1
  27. package/dist/assets/{journeyDiagram-c64418c1-MWgCkVoE.js → journeyDiagram-c64418c1-DoKguIuk.js} +1 -1
  28. package/dist/assets/{layout-C88ObkCf.js → layout-Tnmha8Nh.js} +1 -1
  29. package/dist/assets/{line-C7WAYMt5.js → line-BQR2SOyl.js} +1 -1
  30. package/dist/assets/{linear-C4msxfcU.js → linear-DlG0eemV.js} +1 -1
  31. package/dist/assets/{mermaid.core-Cabag9SZ.js → mermaid.core-BnwYO0He.js} +6 -6
  32. package/dist/assets/{mindmap-definition-8da855dc-CeS8ETXx.js → mindmap-definition-8da855dc-BllYwDID.js} +1 -1
  33. package/dist/assets/{pieDiagram-a8764435-BvjyKnq5.js → pieDiagram-a8764435-DwCkhPVc.js} +1 -1
  34. package/dist/assets/{quadrantDiagram-1e28029f-DzYvpbNM.js → quadrantDiagram-1e28029f-c40GKTU0.js} +1 -1
  35. package/dist/assets/{requirementDiagram-08caed73-DHIoDbyo.js → requirementDiagram-08caed73-DnQp2Tk6.js} +1 -1
  36. package/dist/assets/{sankeyDiagram-a04cb91d-BFSGnQGs.js → sankeyDiagram-a04cb91d-CnJrs13b.js} +1 -1
  37. package/dist/assets/{sequenceDiagram-c5b8d532-_LM3BJ5-.js → sequenceDiagram-c5b8d532-1YBwnpKu.js} +1 -1
  38. package/dist/assets/{stateDiagram-1ecb1508-DwORjOzl.js → stateDiagram-1ecb1508-BFBxQ6Fh.js} +1 -1
  39. package/dist/assets/{stateDiagram-v2-c2b004d7-B4cAWWz1.js → stateDiagram-v2-c2b004d7-Dmechvv2.js} +1 -1
  40. package/dist/assets/{styles-b4e223ce-D_rmV3B_.js → styles-b4e223ce-DWWfWX8O.js} +1 -1
  41. package/dist/assets/{styles-ca3715f6-BFx4VuFc.js → styles-ca3715f6-CKKvZxaU.js} +1 -1
  42. package/dist/assets/{styles-d45a18b0-BE3106vL.js → styles-d45a18b0-dKMOUh9p.js} +1 -1
  43. package/dist/assets/{svgDrawCommon-b86b1483-DwDTO1op.js → svgDrawCommon-b86b1483-CBgjChPM.js} +1 -1
  44. package/dist/assets/{timeline-definition-faaaa080-C4b8qUQZ.js → timeline-definition-faaaa080-NCt-HHmb.js} +1 -1
  45. package/dist/assets/{xychartDiagram-f5964ef8-BRJ9Z4u-.js → xychartDiagram-f5964ef8-BJhXS4dG.js} +1 -1
  46. package/dist/index.html +2 -7
  47. package/index.html +0 -5
  48. package/package.json +11 -6
  49. package/src/App.tsx +2 -0
  50. package/src/api/README.md +26 -0
  51. package/src/api/automation.ts +88 -0
  52. package/src/api/base.ts +54 -0
  53. package/src/api/benchmark.ts +45 -0
  54. package/src/api/config.ts +24 -0
  55. package/src/api/knowledge.ts +72 -0
  56. package/src/api/projects.ts +15 -0
  57. package/src/api/sessions.ts +82 -0
  58. package/src/api/types.ts +20 -0
  59. package/src/api.ts +44 -241
  60. package/src/components/AutomationView/AutomationView.scss +5 -1
  61. package/src/components/AutomationView/RuleFormPanel.tsx +3 -2
  62. package/src/components/AutomationView/TaskList.scss +4 -6
  63. package/src/components/AutomationView/TaskList.tsx +2 -1
  64. package/src/components/AutomationView/TriggerList.scss +4 -1
  65. package/src/components/BenchmarkView/BenchmarkCasePanel.scss +267 -0
  66. package/src/components/BenchmarkView/BenchmarkCasePanel.tsx +309 -0
  67. package/src/components/BenchmarkView/BenchmarkSidebar.scss +182 -0
  68. package/src/components/BenchmarkView/BenchmarkSidebar.tsx +262 -0
  69. package/src/components/BenchmarkView/BenchmarkView.scss +78 -0
  70. package/src/components/BenchmarkView/index.tsx +197 -0
  71. package/src/components/BenchmarkView/types.ts +10 -0
  72. package/src/components/BenchmarkView/utils.ts +21 -0
  73. package/src/components/Chat.tsx +37 -29
  74. package/src/components/{chat/CodeBlock.tsx → CodeBlock.tsx} +3 -1
  75. package/src/components/ConfigView.tsx +13 -1
  76. package/src/components/{chat/MarkdownContent.tsx → MarkdownContent.tsx} +1 -1
  77. package/src/components/NavRail.tsx +7 -0
  78. package/src/components/chat/ChatHeader.scss +37 -19
  79. package/src/components/chat/ChatHeader.tsx +6 -9
  80. package/src/components/chat/ChatHistoryView.tsx +89 -45
  81. package/src/components/chat/CurrentTodoList.tsx +10 -9
  82. package/src/components/chat/{MessageItem.scss → Messages/MessageItem.scss} +14 -0
  83. package/src/components/chat/{MessageItem.tsx → Messages/MessageItem.tsx} +30 -8
  84. package/src/components/chat/{messageUtils.ts → Messages/message-utils.ts} +1 -1
  85. package/src/components/chat/NewSessionGuide.scss +35 -13
  86. package/src/components/chat/NewSessionGuide.tsx +20 -10
  87. package/src/components/chat/{Sender.scss → Sender/Sender.scss} +80 -0
  88. package/src/components/chat/{Sender.tsx → Sender/Sender.tsx} +161 -5
  89. package/src/components/chat/tools/DefaultTool.tsx +184 -21
  90. package/src/components/chat/tools/adapter-claude/BashTool.scss +67 -51
  91. package/src/components/chat/tools/adapter-claude/BashTool.tsx +83 -49
  92. package/src/components/chat/tools/adapter-claude/GlobTool.scss +0 -79
  93. package/src/components/chat/tools/adapter-claude/GlobTool.tsx +16 -36
  94. package/src/components/chat/tools/adapter-claude/GrepTool.scss +0 -87
  95. package/src/components/chat/tools/adapter-claude/GrepTool.tsx +22 -41
  96. package/src/components/chat/tools/adapter-claude/LSTool.scss +0 -79
  97. package/src/components/chat/tools/adapter-claude/LSTool.tsx +15 -15
  98. package/src/components/chat/tools/adapter-claude/ReadTool.scss +0 -55
  99. package/src/components/chat/tools/adapter-claude/ReadTool.tsx +20 -42
  100. package/src/components/chat/tools/adapter-claude/TodoTool.scss +8 -23
  101. package/src/components/chat/tools/adapter-claude/TodoTool.tsx +24 -11
  102. package/src/components/chat/tools/adapter-claude/WriteTool.scss +21 -69
  103. package/src/components/chat/tools/adapter-claude/WriteTool.tsx +22 -58
  104. package/src/components/chat/tools/adapter-claude/index.ts +4 -10
  105. package/src/components/chat/tools/adapter-claude/utils.ts +54 -0
  106. package/src/components/chat/tools/core/ToolCallBox.scss +356 -0
  107. package/src/components/chat/{ToolGroup.tsx → tools/core/ToolGroup.tsx} +26 -7
  108. package/src/components/chat/{ToolRenderer.tsx → tools/core/ToolRenderer.tsx} +6 -4
  109. package/src/components/chat/tools/plugin-chrome-devtools/ChromeDevtoolsTool.scss +11 -0
  110. package/src/components/chat/tools/plugin-chrome-devtools/ChromeDevtoolsTool.tsx +75 -0
  111. package/src/components/chat/tools/plugin-chrome-devtools/index.ts +45 -0
  112. package/src/components/chat/tools/task/GetTaskInfoTool.scss +2 -27
  113. package/src/components/chat/tools/task/GetTaskInfoTool.tsx +48 -38
  114. package/src/components/chat/tools/task/ListTasksTool.scss +3 -28
  115. package/src/components/chat/tools/task/ListTasksTool.tsx +11 -8
  116. package/src/components/chat/tools/task/StartTasksTool.scss +3 -28
  117. package/src/components/chat/tools/task/StartTasksTool.tsx +14 -17
  118. package/src/components/chat/tools/task/components/TaskRow.scss +105 -0
  119. package/src/components/chat/tools/task/components/TaskRow.tsx +163 -0
  120. package/src/components/chat/tools/task/components/TaskToolCard.scss +15 -15
  121. package/src/components/chat/tools/task/components/TaskToolCard.tsx +8 -6
  122. package/src/components/config/AppSettingsPanel.tsx +33 -0
  123. package/src/components/config/ConfigSectionForm.tsx +12 -1
  124. package/src/components/config/channelDefinitions.ts +6 -0
  125. package/src/components/config/configSchema.ts +10 -1
  126. package/src/components/config/recordEditors/ChannelRecordEditor.scss +1 -0
  127. package/src/components/config/recordEditors/ChannelRecordEditor.tsx +397 -0
  128. package/src/components/config/recordEditors/index.tsx +1 -0
  129. package/src/components/knowledge-base/KnowledgeBaseView.tsx +51 -3
  130. package/src/components/knowledge-base/components/RuleItem.tsx +79 -0
  131. package/src/components/knowledge-base/components/RuleList.scss +5 -0
  132. package/src/components/knowledge-base/components/RuleList.tsx +70 -0
  133. package/src/components/knowledge-base/components/RulesTab.tsx +32 -7
  134. package/src/components/knowledge-base/components/SpecItem.tsx +1 -1
  135. package/src/hooks/chat/use-chat-interaction.ts +26 -0
  136. package/src/{components/chat/useChatModels.tsx → hooks/chat/use-chat-models.tsx} +65 -16
  137. package/src/hooks/chat/use-chat-permission-mode.ts +47 -0
  138. package/src/hooks/chat/use-chat-scroll.ts +51 -0
  139. package/src/hooks/chat/use-chat-session-actions.ts +147 -0
  140. package/src/hooks/chat/use-chat-session-messages.ts +250 -0
  141. package/src/hooks/chat/use-chat-session.ts +57 -0
  142. package/src/hooks/chat/use-chat-view.ts +39 -0
  143. package/src/main.tsx +10 -13
  144. package/src/resources/locales/en.json +73 -0
  145. package/src/resources/locales/zh.json +73 -0
  146. package/src/runtime-config.ts +52 -0
  147. package/src/store/index.ts +2 -0
  148. package/src/vite-env.d.ts +11 -0
  149. package/src/ws.ts +5 -3
  150. package/vite.config.ts +12 -4
  151. package/dist/assets/channel-DrWdSpqV.js +0 -1
  152. package/dist/assets/clone-D0cC8LLB.js +0 -1
  153. package/dist/assets/flowDiagram-v2-4f6560a1-Bf_DH7dp.js +0 -1
  154. package/dist/assets/index-CNMzWvKV.js +0 -497
  155. package/dist/assets/index-PEmISxiy.css +0 -1
  156. package/src/components/chat/ToolCallBox.scss +0 -137
  157. package/src/components/chat/useChatSession.ts +0 -370
  158. /package/src/components/{chat/CodeBlock.scss → CodeBlock.scss} +0 -0
  159. /package/src/components/chat/{MessageFooter.tsx → Messages/MessageFooter.tsx} +0 -0
  160. /package/src/components/chat/{CompletionMenu.scss → Sender/CompletionMenu.scss} +0 -0
  161. /package/src/components/chat/{CompletionMenu.tsx → Sender/CompletionMenu.tsx} +0 -0
  162. /package/src/components/chat/{ThinkingStatus.scss → Sender/ThinkingStatus.scss} +0 -0
  163. /package/src/components/chat/{ThinkingStatus.tsx → Sender/ThinkingStatus.tsx} +0 -0
  164. /package/src/components/chat/{ToolCallBox.tsx → tools/core/ToolCallBox.tsx} +0 -0
  165. /package/src/components/chat/{ToolGroup.scss → tools/core/ToolGroup.scss} +0 -0
  166. /package/src/{components/chat/safeSerialize.ts → utils/safe-serialize.ts} +0 -0
@@ -0,0 +1,72 @@
1
+ import { createApiUrl, fetchApiJson } from './base'
2
+
3
+ export interface SpecSummary {
4
+ id: string
5
+ name: string
6
+ description: string
7
+ params: { name: string; description?: string }[]
8
+ always: boolean
9
+ tags: string[]
10
+ skills: string[]
11
+ rules: string[]
12
+ }
13
+
14
+ export interface EntitySummary {
15
+ id: string
16
+ name: string
17
+ description: string
18
+ always: boolean
19
+ tags: string[]
20
+ skills: string[]
21
+ rules: string[]
22
+ }
23
+
24
+ export interface RuleSummary {
25
+ id: string
26
+ name: string
27
+ description: string
28
+ always: boolean
29
+ globs?: string[]
30
+ }
31
+
32
+ export interface SpecDetail extends SpecSummary {
33
+ body: string
34
+ }
35
+
36
+ export interface EntityDetail extends EntitySummary {
37
+ body: string
38
+ }
39
+
40
+ export interface RuleDetail extends RuleSummary {
41
+ body: string
42
+ }
43
+
44
+ export async function listSpecs(): Promise<{ specs: SpecSummary[] }> {
45
+ return fetchApiJson<{ specs: SpecSummary[] }>('/api/ai/specs')
46
+ }
47
+
48
+ export async function listEntities(): Promise<{ entities: EntitySummary[] }> {
49
+ return fetchApiJson<{ entities: EntitySummary[] }>('/api/ai/entities')
50
+ }
51
+
52
+ export async function listRules(): Promise<{ rules: RuleSummary[] }> {
53
+ return fetchApiJson<{ rules: RuleSummary[] }>('/api/ai/rules')
54
+ }
55
+
56
+ export async function getSpecDetail(path: string): Promise<{ spec: SpecDetail }> {
57
+ const url = createApiUrl('/api/ai/specs/detail')
58
+ url.searchParams.set('path', path)
59
+ return fetchApiJson<{ spec: SpecDetail }>(url)
60
+ }
61
+
62
+ export async function getEntityDetail(path: string): Promise<{ entity: EntityDetail }> {
63
+ const url = createApiUrl('/api/ai/entities/detail')
64
+ url.searchParams.set('path', path)
65
+ return fetchApiJson<{ entity: EntityDetail }>(url)
66
+ }
67
+
68
+ export async function getRuleDetail(path: string): Promise<{ rule: RuleDetail }> {
69
+ const url = createApiUrl('/api/ai/rules/detail')
70
+ url.searchParams.set('path', path)
71
+ return fetchApiJson<{ rule: RuleDetail }>(url)
72
+ }
@@ -0,0 +1,15 @@
1
+ import type { Project } from '@vibe-forge/core'
2
+
3
+ import { fetchApiJson, jsonHeaders } from './base'
4
+
5
+ export async function listProjects(): Promise<{ projects: Project[] }> {
6
+ return fetchApiJson<{ projects: Project[] }>('/api/projects')
7
+ }
8
+
9
+ export async function createProject(name?: string): Promise<{ project: Project }> {
10
+ return fetchApiJson<{ project: Project }>('/api/projects', {
11
+ method: 'POST',
12
+ headers: jsonHeaders,
13
+ body: JSON.stringify({ name })
14
+ })
15
+ }
@@ -0,0 +1,82 @@
1
+ import type { ChatMessageContent, Session } from '@vibe-forge/core'
2
+
3
+ import { createApiUrl, fetchApiJson, fetchApiJsonOrThrow, jsonHeaders } from './base'
4
+ import type { ApiOkResponse, ApiRemoveResponse, SessionMessagesResponse } from './types'
5
+
6
+ export async function listSessions(
7
+ filter: 'active' | 'archived' | 'all' = 'active'
8
+ ): Promise<{ sessions: Session[] }> {
9
+ const path = filter === 'archived' ? '/api/sessions/archived' : '/api/sessions'
10
+ return fetchApiJson<{ sessions: Session[] }>(path)
11
+ }
12
+
13
+ export async function createSession(
14
+ title?: string,
15
+ initialMessage?: string,
16
+ initialContent?: ChatMessageContent[],
17
+ model?: string,
18
+ options?: {
19
+ start?: boolean
20
+ parentSessionId?: string
21
+ id?: string
22
+ promptType?: 'spec' | 'entity'
23
+ promptName?: string
24
+ permissionMode?: 'default' | 'acceptEdits' | 'plan' | 'dontAsk' | 'bypassPermissions'
25
+ }
26
+ ): Promise<{ session: Session }> {
27
+ return fetchApiJson<{ session: Session }>('/api/sessions', {
28
+ method: 'POST',
29
+ headers: jsonHeaders,
30
+ body: JSON.stringify({
31
+ title,
32
+ initialMessage,
33
+ initialContent,
34
+ model,
35
+ start: options?.start,
36
+ parentSessionId: options?.parentSessionId,
37
+ id: options?.id,
38
+ promptType: options?.promptType,
39
+ promptName: options?.promptName,
40
+ permissionMode: options?.permissionMode
41
+ })
42
+ })
43
+ }
44
+
45
+ export async function forkSession(id: string, title?: string): Promise<{ session: Session }> {
46
+ return fetchApiJson<{ session: Session }>(`/api/sessions/${id}/fork`, {
47
+ method: 'POST',
48
+ headers: jsonHeaders,
49
+ body: JSON.stringify({ title })
50
+ })
51
+ }
52
+
53
+ export async function getSessionMessages(
54
+ id: string,
55
+ limit?: number
56
+ ): Promise<SessionMessagesResponse> {
57
+ const url = createApiUrl(`/api/sessions/${id}/messages`)
58
+ if (limit != null) {
59
+ url.searchParams.set('limit', limit.toString())
60
+ }
61
+ return fetchApiJson<SessionMessagesResponse>(url)
62
+ }
63
+
64
+ export async function deleteSession(id: string): Promise<ApiRemoveResponse> {
65
+ return fetchApiJsonOrThrow<ApiRemoveResponse>(
66
+ `/api/sessions/${id}`,
67
+ { method: 'DELETE' },
68
+ '[api] delete session failed:'
69
+ )
70
+ }
71
+
72
+ export async function updateSession(id: string, data: Partial<Session>): Promise<ApiOkResponse> {
73
+ return fetchApiJson<ApiOkResponse>(`/api/sessions/${id}`, {
74
+ method: 'PATCH',
75
+ headers: jsonHeaders,
76
+ body: JSON.stringify(data)
77
+ })
78
+ }
79
+
80
+ export async function updateSessionTitle(id: string, title: string): Promise<ApiOkResponse> {
81
+ return updateSession(id, { title })
82
+ }
@@ -0,0 +1,20 @@
1
+ import type { AskUserQuestionParams, Session, WSEvent } from '@vibe-forge/core'
2
+
3
+ export interface ApiOkResponse {
4
+ ok: boolean
5
+ }
6
+
7
+ export interface ApiRemoveResponse extends ApiOkResponse {
8
+ removed: boolean
9
+ }
10
+
11
+ export interface SessionInteraction {
12
+ id: string
13
+ payload: AskUserQuestionParams
14
+ }
15
+
16
+ export interface SessionMessagesResponse {
17
+ messages: WSEvent[]
18
+ session?: Session
19
+ interaction?: SessionInteraction
20
+ }
package/src/api.ts CHANGED
@@ -1,241 +1,44 @@
1
- import type { ConfigResponse, ConfigSource, Session } from '@vibe-forge/core'
2
-
3
- export interface SpecSummary {
4
- id: string
5
- name: string
6
- description: string
7
- params: { name: string; description?: string }[]
8
- always: boolean
9
- tags: string[]
10
- skills: string[]
11
- rules: string[]
12
- }
13
-
14
- export interface EntitySummary {
15
- id: string
16
- name: string
17
- description: string
18
- always: boolean
19
- tags: string[]
20
- skills: string[]
21
- rules: string[]
22
- }
23
-
24
- export interface SpecDetail extends SpecSummary {
25
- body: string
26
- }
27
-
28
- export interface EntityDetail extends EntitySummary {
29
- body: string
30
- }
31
-
32
- export interface AutomationTrigger {
33
- id: string
34
- type: 'interval' | 'webhook' | 'cron'
35
- intervalMs?: number | null
36
- cronExpression?: string | null
37
- webhookKey?: string | null
38
- }
39
-
40
- export interface AutomationTask {
41
- id: string
42
- title: string
43
- prompt: string
44
- }
45
-
46
- export interface AutomationRule {
47
- id: string
48
- name: string
49
- description?: string | null
50
- type: 'interval' | 'webhook' | 'cron'
51
- intervalMs?: number | null
52
- webhookKey?: string | null
53
- cronExpression?: string | null
54
- prompt: string
55
- enabled: boolean
56
- createdAt: number
57
- lastRunAt?: number | null
58
- lastSessionId?: string | null
59
- triggers?: AutomationTrigger[]
60
- tasks?: AutomationTask[]
61
- }
62
-
63
- export interface AutomationRun {
64
- id: string
65
- ruleId: string
66
- sessionId: string
67
- runAt: number
68
- taskId?: string | null
69
- taskTitle?: string | null
70
- status?: string
71
- title?: string
72
- lastMessage?: string
73
- lastUserMessage?: string
74
- }
75
-
76
- const SERVER_HOST = (import.meta.env.__VF_PROJECT_AI_SERVER_HOST__ as string | undefined) ?? window.location.hostname
77
- const SERVER_PORT = (import.meta.env.__VF_PROJECT_AI_SERVER_PORT__ as string | undefined) ?? '8787'
78
- const SERVER_URL = `http://${SERVER_HOST}:${SERVER_PORT}`
79
-
80
- export async function listProjects(): Promise<any> {
81
- const res = await fetch(`${SERVER_URL}/api/projects`)
82
- return res.json()
83
- }
84
-
85
- export async function createProject(name?: string): Promise<any> {
86
- const res = await fetch(`${SERVER_URL}/api/projects`, {
87
- method: 'POST',
88
- headers: { 'Content-Type': 'application/json' },
89
- body: JSON.stringify({ name })
90
- })
91
- return res.json()
92
- }
93
-
94
- export async function listSessions(filter: 'active' | 'archived' | 'all' = 'active'): Promise<{ sessions: Session[] }> {
95
- const res = await fetch(`${SERVER_URL}/api/sessions${filter === 'archived' ? '/archived' : ''}`)
96
- return res.json() as Promise<{ sessions: Session[] }>
97
- }
98
-
99
- export async function createSession(title?: string, initialMessage?: string): Promise<{ session: Session }> {
100
- const res = await fetch(`${SERVER_URL}/api/sessions`, {
101
- method: 'POST',
102
- headers: { 'Content-Type': 'application/json' },
103
- body: JSON.stringify({ title, initialMessage })
104
- })
105
- return res.json() as Promise<{ session: Session }>
106
- }
107
-
108
- export async function listSpecs(): Promise<{ specs: SpecSummary[] }> {
109
- const res = await fetch(`${SERVER_URL}/api/ai/specs`)
110
- return res.json() as Promise<{ specs: SpecSummary[] }>
111
- }
112
-
113
- export async function listEntities(): Promise<{ entities: EntitySummary[] }> {
114
- const res = await fetch(`${SERVER_URL}/api/ai/entities`)
115
- return res.json() as Promise<{ entities: EntitySummary[] }>
116
- }
117
-
118
- export async function getSpecDetail(path: string): Promise<{ spec: SpecDetail }> {
119
- const url = new URL(`${SERVER_URL}/api/ai/specs/detail`)
120
- url.searchParams.set('path', path)
121
- const res = await fetch(url.toString())
122
- return res.json() as Promise<{ spec: SpecDetail }>
123
- }
124
-
125
- export async function getEntityDetail(path: string): Promise<{ entity: EntityDetail }> {
126
- const url = new URL(`${SERVER_URL}/api/ai/entities/detail`)
127
- url.searchParams.set('path', path)
128
- const res = await fetch(url.toString())
129
- return res.json() as Promise<{ entity: EntityDetail }>
130
- }
131
-
132
- export async function getConfig(): Promise<ConfigResponse> {
133
- const res = await fetch(`${SERVER_URL}/api/config`)
134
- return res.json() as Promise<ConfigResponse>
135
- }
136
-
137
- export async function listAutomationRules(): Promise<{ rules: AutomationRule[] }> {
138
- const res = await fetch(`${SERVER_URL}/api/automation/rules`)
139
- return res.json() as Promise<{ rules: AutomationRule[] }>
140
- }
141
-
142
- export async function createAutomationRule(rule: Partial<AutomationRule> & { immediateRun?: boolean }): Promise<{ rule: AutomationRule }> {
143
- const res = await fetch(`${SERVER_URL}/api/automation/rules`, {
144
- method: 'POST',
145
- headers: { 'Content-Type': 'application/json' },
146
- body: JSON.stringify(rule)
147
- })
148
- return res.json() as Promise<{ rule: AutomationRule }>
149
- }
150
-
151
- export async function updateAutomationRule(
152
- id: string,
153
- rule: Partial<AutomationRule> & { immediateRun?: boolean }
154
- ): Promise<{ rule: AutomationRule }> {
155
- const res = await fetch(`${SERVER_URL}/api/automation/rules/${id}`, {
156
- method: 'PATCH',
157
- headers: { 'Content-Type': 'application/json' },
158
- body: JSON.stringify(rule)
159
- })
160
- return res.json() as Promise<{ rule: AutomationRule }>
161
- }
162
-
163
- export async function deleteAutomationRule(id: string): Promise<{ ok: boolean; removed: boolean }> {
164
- const res = await fetch(`${SERVER_URL}/api/automation/rules/${id}`, {
165
- method: 'DELETE'
166
- })
167
- return res.json() as Promise<{ ok: boolean; removed: boolean }>
168
- }
169
-
170
- export async function runAutomationRule(id: string): Promise<{ ok: boolean; sessionIds: string[] }> {
171
- const res = await fetch(`${SERVER_URL}/api/automation/rules/${id}/run`, {
172
- method: 'POST'
173
- })
174
- return res.json() as Promise<{ ok: boolean; sessionIds: string[] }>
175
- }
176
-
177
- export async function listAutomationRuns(id: string, limit = 50): Promise<{ runs: AutomationRun[] }> {
178
- const url = new URL(`${SERVER_URL}/api/automation/rules/${id}/runs`)
179
- url.searchParams.set('limit', limit.toString())
180
- const res = await fetch(url.toString())
181
- return res.json() as Promise<{ runs: AutomationRun[] }>
182
- }
183
-
184
- export async function updateConfig(
185
- source: ConfigSource,
186
- section: string,
187
- value: unknown
188
- ): Promise<{ ok: boolean }> {
189
- const res = await fetch(`${SERVER_URL}/api/config`, {
190
- method: 'PATCH',
191
- headers: { 'Content-Type': 'application/json' },
192
- body: JSON.stringify({ source, section, value })
193
- })
194
- if (!res.ok) {
195
- const text = await res.text()
196
- console.error('[api] update config failed:', res.status, text)
197
- throw new Error(`Update config failed: ${res.status} ${text}`)
198
- }
199
- return res.json() as Promise<{ ok: boolean }>
200
- }
201
-
202
- export async function deleteSession(id: string): Promise<{ success: boolean }> {
203
- const url = `${SERVER_URL}/api/sessions/${id}`
204
- const res = await fetch(url, { method: 'DELETE' })
205
- if (!res.ok) {
206
- const text = await res.text()
207
- console.error('[api] delete failed:', res.status, text)
208
- throw new Error(`Delete failed: ${res.status} ${text}`)
209
- }
210
- return res.json() as Promise<{ success: boolean }>
211
- }
212
-
213
- export async function updateSession(id: string, data: Partial<Session>): Promise<{ ok: boolean }> {
214
- const res = await fetch(`${SERVER_URL}/api/sessions/${id}`, {
215
- method: 'PATCH',
216
- headers: { 'Content-Type': 'application/json' },
217
- body: JSON.stringify(data)
218
- })
219
- return res.json() as Promise<{ ok: boolean }>
220
- }
221
-
222
- export async function updateSessionTitle(id: string, title: string): Promise<{ session: Session }> {
223
- const res = await fetch(`${SERVER_URL}/api/sessions/${id}`, {
224
- method: 'PATCH',
225
- headers: { 'Content-Type': 'application/json' },
226
- body: JSON.stringify({ title })
227
- })
228
- return res.json() as Promise<{ session: Session }>
229
- }
230
-
231
- export async function getSessionMessages(
232
- id: string,
233
- limit?: number
234
- ): Promise<{ messages: any[]; session?: Session; interaction?: { id: string; payload: any } }> {
235
- const url = new URL(`${SERVER_URL}/api/sessions/${id}/messages`)
236
- if (limit != null) {
237
- url.searchParams.set('limit', limit.toString())
238
- }
239
- const res = await fetch(url.toString())
240
- return res.json() as Promise<{ messages: any[]; session?: Session; interaction?: { id: string; payload: any } }>
241
- }
1
+ // 自动化规则与执行记录 API
2
+ export type { AutomationRule, AutomationRun, AutomationTask, AutomationTrigger } from './api/automation'
3
+ export {
4
+ createAutomationRule,
5
+ deleteAutomationRule,
6
+ listAutomationRules,
7
+ listAutomationRuns,
8
+ runAutomationRule,
9
+ updateAutomationRule
10
+ } from './api/automation'
11
+
12
+ export {
13
+ getBenchmarkCase,
14
+ getBenchmarkResult,
15
+ getBenchmarkRun,
16
+ listBenchmarkCases,
17
+ listBenchmarkCategories,
18
+ startBenchmarkRun
19
+ } from './api/benchmark'
20
+ // 配置读取与更新 API
21
+ export { getConfig, updateConfig } from './api/config'
22
+
23
+ // 知识库与规则说明 API
24
+ export type { EntityDetail, EntitySummary, RuleDetail, RuleSummary, SpecDetail, SpecSummary } from './api/knowledge'
25
+
26
+ export { getEntityDetail, getRuleDetail, getSpecDetail, listEntities, listRules, listSpecs } from './api/knowledge'
27
+ // 项目与工程 API
28
+ export { createProject, listProjects } from './api/projects'
29
+
30
+ // 会话与消息 API
31
+ export {
32
+ createSession,
33
+ deleteSession,
34
+ forkSession,
35
+ getSessionMessages,
36
+ listSessions,
37
+ updateSession,
38
+ updateSessionTitle
39
+ } from './api/sessions'
40
+
41
+ // 基础响应类型与会话交互类型
42
+ export type { ApiOkResponse, ApiRemoveResponse, SessionInteraction, SessionMessagesResponse } from './api/types'
43
+
44
+ export type { BenchmarkCase, BenchmarkCategory, BenchmarkResult, BenchmarkRunSummary } from '@vibe-forge/core'
@@ -4,6 +4,10 @@
4
4
  padding: 24px;
5
5
  overflow: hidden;
6
6
 
7
+ .ant-form-item {
8
+ margin-bottom: 12px;
9
+ }
10
+
7
11
  &__left {
8
12
  width: 360px;
9
13
  min-width: 320px;
@@ -15,7 +19,7 @@
15
19
  &__divider {
16
20
  width: 1px;
17
21
  background: var(--border-color);
18
- margin: 0 16px;
22
+ margin: 0 24px;
19
23
  }
20
24
 
21
25
  &__right {
@@ -5,6 +5,7 @@ import React, { useCallback, useEffect } from 'react'
5
5
  import { useTranslation } from 'react-i18next'
6
6
 
7
7
  import type { AutomationRule } from '#~/api.js'
8
+ import { getServerHost, getServerPort } from '#~/api/base.js'
8
9
 
9
10
  import { TaskList } from './TaskList'
10
11
  import { TriggerList } from './TriggerList'
@@ -18,8 +19,8 @@ interface RuleFormPanelProps {
18
19
  onCancel: () => void
19
20
  }
20
21
 
21
- const serverHost = (import.meta.env.__VF_PROJECT_AI_SERVER_HOST__ as string | undefined) ?? window.location.hostname
22
- const serverPort = (import.meta.env.__VF_PROJECT_AI_SERVER_PORT__ as string | undefined) ?? '8787'
22
+ const serverHost = getServerHost()
23
+ const serverPort = getServerPort()
23
24
  const serverUrl = `http://${serverHost}:${serverPort}`
24
25
 
25
26
  export function RuleFormPanel({ mode, rule, submitting, onSubmit, onCancel }: RuleFormPanelProps) {
@@ -33,7 +33,6 @@
33
33
  padding: 12px;
34
34
  display: flex;
35
35
  flex-direction: column;
36
- gap: 12px;
37
36
  background: var(--tag-bg);
38
37
  }
39
38
 
@@ -100,11 +99,6 @@
100
99
  font-size: 18px;
101
100
  }
102
101
 
103
- &__button-icon {
104
- font-size: 16px;
105
- margin-right: 4px;
106
- }
107
-
108
102
  &__remove-button {
109
103
  position: absolute;
110
104
  top: 8px;
@@ -112,6 +106,10 @@
112
106
  width: 32px;
113
107
  height: 32px;
114
108
  padding: 0;
109
+ display: inline-flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ border-radius: 50%;
115
113
  }
116
114
 
117
115
  &__task-index {
@@ -46,11 +46,12 @@ export function TaskList() {
46
46
  <Tooltip title={t('automation.remove')}>
47
47
  <Button
48
48
  className='automation-view__remove-button'
49
+ type='text'
49
50
  danger
50
51
  onClick={() => remove(field.name)}
51
52
  disabled={fields.length <= 1}
52
53
  >
53
- <span className='material-symbols-rounded automation-view__button-icon'>close</span>
54
+ <span className='material-symbols-rounded automation-view__action-icon'>close</span>
54
55
  </Button>
55
56
  </Tooltip>
56
57
  <div className='automation-view__list-header'>
@@ -33,7 +33,6 @@
33
33
  padding: 12px;
34
34
  display: flex;
35
35
  flex-direction: column;
36
- gap: 12px;
37
36
  background: var(--tag-bg);
38
37
  }
39
38
 
@@ -107,6 +106,10 @@
107
106
  width: 32px;
108
107
  height: 32px;
109
108
  padding: 0;
109
+ display: inline-flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ border-radius: 50%;
110
113
  }
111
114
 
112
115
  &__input-number {