@things-factory/board-ai 10.0.0-beta.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/components/board-ai-chat.test.ts +120 -0
- package/client/components/board-ai-chat.ts +1502 -0
- package/client/components/chat-input-builder.ts +40 -0
- package/client/components/markdown.test.ts +220 -0
- package/client/components/markdown.ts +184 -0
- package/client/index.ts +11 -0
- package/client/tsconfig.json +13 -0
- package/client/utils/board-edit-patch.ts +200 -0
- package/config/config.development.js +43 -0
- package/config/config.production.js +15 -0
- package/dist-client/components/board-ai-chat.d.ts +127 -0
- package/dist-client/components/board-ai-chat.js +1455 -0
- package/dist-client/components/board-ai-chat.js.map +1 -0
- package/dist-client/components/board-ai-chat.test.d.ts +1 -0
- package/dist-client/components/board-ai-chat.test.js +112 -0
- package/dist-client/components/board-ai-chat.test.js.map +1 -0
- package/dist-client/components/chat-input-builder.d.ts +30 -0
- package/dist-client/components/chat-input-builder.js +25 -0
- package/dist-client/components/chat-input-builder.js.map +1 -0
- package/dist-client/components/markdown.d.ts +16 -0
- package/dist-client/components/markdown.js +167 -0
- package/dist-client/components/markdown.js.map +1 -0
- package/dist-client/components/markdown.test.d.ts +1 -0
- package/dist-client/components/markdown.test.js +187 -0
- package/dist-client/components/markdown.test.js.map +1 -0
- package/dist-client/index.d.ts +11 -0
- package/dist-client/index.js +12 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-client/utils/board-edit-patch.d.ts +73 -0
- package/dist-client/utils/board-edit-patch.js +159 -0
- package/dist-client/utils/board-edit-patch.js.map +1 -0
- package/dist-server/index.d.ts +21 -0
- package/dist-server/index.js +25 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/service/apply-patch.d.ts +46 -0
- package/dist-server/service/apply-patch.js +211 -0
- package/dist-server/service/apply-patch.js.map +1 -0
- package/dist-server/service/assistant.d.ts +75 -0
- package/dist-server/service/assistant.js +1298 -0
- package/dist-server/service/assistant.js.map +1 -0
- package/dist-server/service/board-ai-resolver.d.ts +40 -0
- package/dist-server/service/board-ai-resolver.js +260 -0
- package/dist-server/service/board-ai-resolver.js.map +1 -0
- package/dist-server/service/chat-message/chat-message.d.ts +24 -0
- package/dist-server/service/chat-message/chat-message.js +108 -0
- package/dist-server/service/chat-message/chat-message.js.map +1 -0
- package/dist-server/service/chat-message/index.d.ts +3 -0
- package/dist-server/service/chat-message/index.js +7 -0
- package/dist-server/service/chat-message/index.js.map +1 -0
- package/dist-server/service/chat-session/chat-session.d.ts +22 -0
- package/dist-server/service/chat-session/chat-session.js +109 -0
- package/dist-server/service/chat-session/chat-session.js.map +1 -0
- package/dist-server/service/chat-session/index.d.ts +3 -0
- package/dist-server/service/chat-session/index.js +7 -0
- package/dist-server/service/chat-session/index.js.map +1 -0
- package/dist-server/service/chat-session-resolver.d.ts +13 -0
- package/dist-server/service/chat-session-resolver.js +178 -0
- package/dist-server/service/chat-session-resolver.js.map +1 -0
- package/dist-server/service/index.d.ts +14 -0
- package/dist-server/service/index.js +26 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/patch-entry/index.d.ts +3 -0
- package/dist-server/service/patch-entry/index.js +7 -0
- package/dist-server/service/patch-entry/index.js.map +1 -0
- package/dist-server/service/patch-entry/patch-entry.d.ts +16 -0
- package/dist-server/service/patch-entry/patch-entry.js +96 -0
- package/dist-server/service/patch-entry/patch-entry.js.map +1 -0
- package/dist-server/service/types.d.ts +137 -0
- package/dist-server/service/types.js +3 -0
- package/dist-server/service/types.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/package.json +47 -0
- package/server/index.ts +21 -0
- package/server/service/apply-patch.test.ts +640 -0
- package/server/service/apply-patch.ts +250 -0
- package/server/service/assistant.test.ts +1317 -0
- package/server/service/assistant.ts +1431 -0
- package/server/service/board-ai-resolver.ts +239 -0
- package/server/service/chat-message/chat-message.ts +110 -0
- package/server/service/chat-message/index.ts +5 -0
- package/server/service/chat-session/chat-session.ts +103 -0
- package/server/service/chat-session/index.ts +5 -0
- package/server/service/chat-session-resolver.ts +154 -0
- package/server/service/index.ts +24 -0
- package/server/service/patch-entry/index.ts +5 -0
- package/server/service/patch-entry/patch-entry.ts +89 -0
- package/server/service/types.ts +138 -0
- package/things-factory.config.js +1 -0
- package/translations/en.json +39 -0
- package/translations/ja.json +39 -0
- package/translations/ko.json +40 -0
- package/translations/ms.json +39 -0
- package/translations/zh.json +39 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PatchEntry — 보드의 한 변경 단위 (영구 이력).
|
|
3
|
+
*
|
|
4
|
+
* source 별:
|
|
5
|
+
* - 'ai': AI 가 chat 응답에서 생성
|
|
6
|
+
* - 'user-direct': 사용자가 모델러에서 직접 편집 — 변경 이벤트로 자동 기록
|
|
7
|
+
* - 'import': ImportSession 결과 (도면 → 보드)
|
|
8
|
+
*
|
|
9
|
+
* AI 컨텍스트 유지의 핵심: 사용자 직접 편집도 PatchEntry 로 기록되어
|
|
10
|
+
* 다음 chat 호출 시 system 메시지로 자동 합류 → AI 가 모든 변경을 인지.
|
|
11
|
+
*/
|
|
12
|
+
import {
|
|
13
|
+
Column,
|
|
14
|
+
CreateDateColumn,
|
|
15
|
+
Entity,
|
|
16
|
+
Index,
|
|
17
|
+
ManyToOne,
|
|
18
|
+
PrimaryGeneratedColumn,
|
|
19
|
+
RelationId
|
|
20
|
+
} from 'typeorm'
|
|
21
|
+
import { Field, ID, Float, ObjectType } from 'type-graphql'
|
|
22
|
+
import { GraphQLJSON } from 'graphql-scalars'
|
|
23
|
+
|
|
24
|
+
import { config } from '@things-factory/env'
|
|
25
|
+
|
|
26
|
+
import { ChatSession } from '../chat-session/chat-session.js'
|
|
27
|
+
|
|
28
|
+
const ORMCONFIG = config.get('ormconfig', {})
|
|
29
|
+
const DATABASE_TYPE = ORMCONFIG.type
|
|
30
|
+
|
|
31
|
+
@Entity()
|
|
32
|
+
@Index('ix_patch_entry_1', (patch: PatchEntry) => [patch.session, patch.createdAt])
|
|
33
|
+
@ObjectType({ description: 'One board edit operation history (cascade-deleted with ChatSession).' })
|
|
34
|
+
export class PatchEntry {
|
|
35
|
+
@PrimaryGeneratedColumn('uuid')
|
|
36
|
+
@Field(type => ID, { nullable: true })
|
|
37
|
+
readonly id?: string
|
|
38
|
+
|
|
39
|
+
@ManyToOne(type => ChatSession, session => session.patches, { onDelete: 'CASCADE' })
|
|
40
|
+
session?: ChatSession
|
|
41
|
+
|
|
42
|
+
@RelationId((patch: PatchEntry) => patch.session)
|
|
43
|
+
sessionId?: string
|
|
44
|
+
|
|
45
|
+
/** 'ai' | 'user-direct' | 'import' */
|
|
46
|
+
@Column({ type: 'varchar', length: 32 })
|
|
47
|
+
@Field({ description: "'ai' | 'user-direct' | 'import'" })
|
|
48
|
+
source!: string
|
|
49
|
+
|
|
50
|
+
/** BoardEditOp[] JSON-stringified — column 으로는 long text. */
|
|
51
|
+
@Column({
|
|
52
|
+
type:
|
|
53
|
+
DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
|
|
54
|
+
? 'longtext'
|
|
55
|
+
: DATABASE_TYPE == 'oracle'
|
|
56
|
+
? 'clob'
|
|
57
|
+
: DATABASE_TYPE == 'mssql'
|
|
58
|
+
? 'nvarchar'
|
|
59
|
+
: 'text',
|
|
60
|
+
length: DATABASE_TYPE == 'mssql' ? 'MAX' : undefined
|
|
61
|
+
})
|
|
62
|
+
ops!: string
|
|
63
|
+
|
|
64
|
+
/** GraphQL 노출용 — JSON 객체로 변환. */
|
|
65
|
+
@Field(type => GraphQLJSON, { description: 'BoardEditOp[] (parsed JSON array).' })
|
|
66
|
+
get opsJson(): any {
|
|
67
|
+
try {
|
|
68
|
+
return JSON.parse(this.ops || '[]')
|
|
69
|
+
} catch {
|
|
70
|
+
return []
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@Column({ type: 'text', nullable: true })
|
|
75
|
+
@Field({ nullable: true, description: 'Short human summary of this patch.' })
|
|
76
|
+
summary?: string
|
|
77
|
+
|
|
78
|
+
@Column({ type: 'float', nullable: true })
|
|
79
|
+
@Field(type => Float, { nullable: true, description: 'AI confidence 0..1 (null for user-direct).' })
|
|
80
|
+
confidence?: number
|
|
81
|
+
|
|
82
|
+
@Column({ default: false })
|
|
83
|
+
@Field({ description: 'Whether this patch was reverted.' })
|
|
84
|
+
reverted!: boolean
|
|
85
|
+
|
|
86
|
+
@CreateDateColumn()
|
|
87
|
+
@Field({ nullable: true })
|
|
88
|
+
createdAt?: Date
|
|
89
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Board AI — 자연어 채팅 인터페이스 타입 정의.
|
|
3
|
+
*
|
|
4
|
+
* 핵심 개념:
|
|
5
|
+
* - 단일 진입점 `chat()`. 의도 분류(생성/편집/스타일/질문)는 AI 의 일.
|
|
6
|
+
* - 출력은 항상 `ChatResponse`. 보드 변경이 있으면 `patch` 동봉.
|
|
7
|
+
* - patch 의 op 는 직교 4 종 (add / remove / modify / replace).
|
|
8
|
+
* style/move 등은 modify.patch 안에 흡수.
|
|
9
|
+
*/
|
|
10
|
+
import type { BoardComponent, BoardModel } from '@things-factory/board-import'
|
|
11
|
+
|
|
12
|
+
export interface LLMMessage {
|
|
13
|
+
role: 'user' | 'assistant'
|
|
14
|
+
content: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ChatOptions {
|
|
18
|
+
/** board-import 의 registry scope — 등록된 ImportRule 에서 type/category 후보 추출 */
|
|
19
|
+
scopes?: string[]
|
|
20
|
+
/** 사용 가능한 도메인 type (override). 미지정 시 scopes 에서 자동 추출 */
|
|
21
|
+
knownTypes?: string[]
|
|
22
|
+
/** 사용 가능한 카테고리 (override). 미지정 시 scopes 에서 자동 추출 */
|
|
23
|
+
categories?: string[]
|
|
24
|
+
/**
|
|
25
|
+
* 컴포넌트 type 별 유효 속성 스킴.
|
|
26
|
+
* LLM 이 정확한 컴포넌트 생성을 하도록 type 의 description, group, default model 키 전달.
|
|
27
|
+
*
|
|
28
|
+
* 예:
|
|
29
|
+
* [{ type: 'rect', description: 'Rectangle', group: 'shape',
|
|
30
|
+
* properties: { fillStyle: '#fff', strokeStyle: '#000' } }, ...]
|
|
31
|
+
*/
|
|
32
|
+
componentSchemas?: ComponentSchema[]
|
|
33
|
+
/**
|
|
34
|
+
* 사용자가 모델러에서 현재 선택한 컴포넌트의 `refid` 목록.
|
|
35
|
+
*
|
|
36
|
+
* refid 는 things-scene 이 모든 컴포넌트에 자동 발급하는 universal numeric handle.
|
|
37
|
+
* id (데이터 바인딩 이름, unique 아님) 와는 다른 개념 — 선택은 항상 refid 로 표현.
|
|
38
|
+
*/
|
|
39
|
+
selectedRefids?: number[]
|
|
40
|
+
/** LLM 모델 override */
|
|
41
|
+
model?: string
|
|
42
|
+
/** LLM 옵션 */
|
|
43
|
+
temperature?: number
|
|
44
|
+
maxTokens?: number
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface ComponentSchema {
|
|
48
|
+
type: string
|
|
49
|
+
description?: string
|
|
50
|
+
group?: string
|
|
51
|
+
/**
|
|
52
|
+
* 좌표/크기/경로 관련 키들 — type 마다 다름.
|
|
53
|
+
* 예) ['left', 'top', 'width', 'height'] vs ['cx', 'cy', 'radius'] vs ['points']
|
|
54
|
+
* LLM 이 type 별 정확한 좌표 키를 사용하도록 명시.
|
|
55
|
+
*/
|
|
56
|
+
geometryKeys?: string[]
|
|
57
|
+
/**
|
|
58
|
+
* 좌표 외 type 특화 속성 (style, value, min/max 등).
|
|
59
|
+
* default 값 또는 keys 만 — LLM 의 token 절감을 위해 호출자가 적절히 압축.
|
|
60
|
+
*/
|
|
61
|
+
properties?: Record<string, any>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* AI 가 응답을 만드는 동안 호출한 도구의 시간순 trace.
|
|
66
|
+
*
|
|
67
|
+
* UX 목적 — 사용자가 "왜 이렇게 답했지" 의문 가질 때 fold-able 박스에서 확인.
|
|
68
|
+
* 디버그용 + 신뢰도 향상.
|
|
69
|
+
*/
|
|
70
|
+
export interface ToolUsage {
|
|
71
|
+
/** 도구 이름 (예: 'getSelection', 'modifyBoard', 'addComponent') */
|
|
72
|
+
name: string
|
|
73
|
+
/** 호출 인자 JSON */
|
|
74
|
+
arguments: any
|
|
75
|
+
/** 도구 결과 — read tool 은 실제 값 (truncated 가능), write tool 은 queued 마커 */
|
|
76
|
+
result: any
|
|
77
|
+
/** read tool / write tool 분류 */
|
|
78
|
+
kind: 'read' | 'write' | 'unknown'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface ChatResponse {
|
|
82
|
+
/** 사용자에게 보여줄 텍스트 응답 */
|
|
83
|
+
reply: string
|
|
84
|
+
/** 보드 변경이 있으면 patch */
|
|
85
|
+
patch?: BoardEditPatch
|
|
86
|
+
/** 모호한 입력 시 명확화 질문 (patch 없음) */
|
|
87
|
+
followUp?: string
|
|
88
|
+
/** AI 가 응답 만드는 과정에서 호출한 도구들 (시간순). UI fold-able 박스용. */
|
|
89
|
+
toolUsages?: ToolUsage[]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface BoardEditPatch {
|
|
93
|
+
ops: BoardEditOp[]
|
|
94
|
+
/** 사용자 검수용 1-2 문장 요약 */
|
|
95
|
+
summary: string
|
|
96
|
+
/** 0..1 신뢰도 */
|
|
97
|
+
confidence: number
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 보드 변경 op.
|
|
102
|
+
*
|
|
103
|
+
* 식별자 정책 — 기존 컴포넌트 타깃팅은 `refid` (number) 만 사용.
|
|
104
|
+
* things-scene 의 모든 컴포넌트는 `refid` 를 자동 발급받는다 (universal).
|
|
105
|
+
* `model.id` 는 optional metadata 일 뿐 — 항상 존재하지 않으므로 targeting 에는
|
|
106
|
+
* 부적합. 별개 개념이므로 BoardEditOp / tool 인자에서도 별개 식별자로 분리하지
|
|
107
|
+
* 않고 refid 단일 채널로 일원화.
|
|
108
|
+
*
|
|
109
|
+
* 계층 — 보드는 **최상위 부모** 이고 그 자체로 자기 속성 (fillStyle, width, height,
|
|
110
|
+
* name 등) 을 갖는다. 자식 컴포넌트와 별개. 보드 속성 변경은 `modifyBoard`,
|
|
111
|
+
* 자식 변경은 `modify` (refid 기반).
|
|
112
|
+
*
|
|
113
|
+
* style 변경 / 이동 / 크기 변경 등 자식 컴포넌트의 변경은 모두 `modify.patch` 안에
|
|
114
|
+
* 흡수. 보드 root 속성 변경은 `modifyBoard.patch` 로.
|
|
115
|
+
*/
|
|
116
|
+
export type BoardEditOp =
|
|
117
|
+
| { op: 'add'; component: BoardComponent }
|
|
118
|
+
| { op: 'remove'; refid: number }
|
|
119
|
+
| { op: 'modify'; refid: number; patch: Partial<BoardComponent> }
|
|
120
|
+
| { op: 'modifyBoard'; patch: Partial<BoardModel> }
|
|
121
|
+
| { op: 'replace'; board: BoardModel }
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* BoardAIAssistant — 자연어 채팅으로 보드를 다루는 단일 인터페이스.
|
|
125
|
+
*
|
|
126
|
+
* 사용:
|
|
127
|
+
* const ai = new DefaultBoardAIAssistant(baseClient, { scopes: ['fmsim'] })
|
|
128
|
+
* const r = await ai.chat([{ role: 'user', content: 'AGV 3대 추가' }], currentBoard)
|
|
129
|
+
* if (r.patch) currentBoard = applyBoardEditPatch(currentBoard, r.patch)
|
|
130
|
+
*/
|
|
131
|
+
export interface BoardAIAssistant {
|
|
132
|
+
readonly id: string
|
|
133
|
+
chat(
|
|
134
|
+
messages: LLMMessage[],
|
|
135
|
+
currentBoard: BoardModel | undefined,
|
|
136
|
+
options?: ChatOptions
|
|
137
|
+
): Promise<ChatResponse>
|
|
138
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"board-ai.label.ai": "operato",
|
|
3
|
+
"board-ai.label.create": "Create",
|
|
4
|
+
"board-ai.label.edit": "Edit",
|
|
5
|
+
"board-ai.label.style": "Style",
|
|
6
|
+
"board-ai.label.korean-supported": "Korean / English",
|
|
7
|
+
"board-ai.label.multi-command": "Batch commands",
|
|
8
|
+
"board-ai.label.review-able": "Reviewable",
|
|
9
|
+
|
|
10
|
+
"board-ai.text.empty-title": "Design a board together with AI",
|
|
11
|
+
"board-ai.text.empty-subtitle": "Describe in natural language and AI will create, edit, and style the board. Click an example below to begin.",
|
|
12
|
+
"board-ai.text.empty-footer-notice": "AI responses are previewed on the board and can be reverted before final apply.",
|
|
13
|
+
"board-ai.text.input-placeholder": "Describe what you want (Shift+Enter newline, Enter to send)",
|
|
14
|
+
"board-ai.text.send-tooltip": "Send (Enter)",
|
|
15
|
+
"board-ai.text.clear-chat-tooltip": "Clear chat (server history kept)",
|
|
16
|
+
"board-ai.text.show-examples-tooltip": "Show common command examples",
|
|
17
|
+
"board-ai.text.applied-changes": "Applied.",
|
|
18
|
+
"board-ai.text.reverted": "Reverted",
|
|
19
|
+
"board-ai.text.failed-to-load-history": "Failed to load history",
|
|
20
|
+
"board-ai.text.empty-response": "Empty response.",
|
|
21
|
+
|
|
22
|
+
"board-ai.example.create-monitoring-dashboard": "Monitoring dashboard with 3 gauges (utilization, temperature, pressure) and a 24-hour line chart",
|
|
23
|
+
"board-ai.example.create-welcome-screen": "Welcome screen with a large 'OPERATO' title, a clock, and a subtitle",
|
|
24
|
+
"board-ai.example.edit-align-distribute": "Center-align the selected components and distribute evenly",
|
|
25
|
+
"board-ai.example.edit-resize-board": "Resize the board to 1920x1080 and center the components",
|
|
26
|
+
"board-ai.example.style-dark-mode": "Dark mode — deep navy background, white text, teal accents",
|
|
27
|
+
"board-ai.example.style-rounded-shadow": "Round all shape corners and add a soft card shadow",
|
|
28
|
+
|
|
29
|
+
"board-ai.button.new-conversation": "New chat",
|
|
30
|
+
"board-ai.button.examples": "Examples",
|
|
31
|
+
"board-ai.button.close": "Close",
|
|
32
|
+
"board-ai.button.revert": "Revert",
|
|
33
|
+
"board-ai.button.retry": "Retry",
|
|
34
|
+
"board-ai.button.copy": "Copy",
|
|
35
|
+
"board-ai.button.regenerate": "Regenerate",
|
|
36
|
+
"board-ai.button.edit": "Edit",
|
|
37
|
+
|
|
38
|
+
"board-ai.text.copied": "Copied"
|
|
39
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"board-ai.label.ai": "operato",
|
|
3
|
+
"board-ai.label.create": "作成",
|
|
4
|
+
"board-ai.label.edit": "編集",
|
|
5
|
+
"board-ai.label.style": "スタイル",
|
|
6
|
+
"board-ai.label.korean-supported": "多言語対応",
|
|
7
|
+
"board-ai.label.multi-command": "複数命令",
|
|
8
|
+
"board-ai.label.review-able": "レビュー可能",
|
|
9
|
+
|
|
10
|
+
"board-ai.text.empty-title": "AI と一緒にボードを作成しましょう",
|
|
11
|
+
"board-ai.text.empty-subtitle": "自然言語で指示すると AI がボードを作成・編集・スタイリングします。下の例をクリックして始めてください。",
|
|
12
|
+
"board-ai.text.empty-footer-notice": "AI の応答は適用前にプレビューで確認でき、元に戻すこともできます。",
|
|
13
|
+
"board-ai.text.input-placeholder": "自然言語で指示してください (Shift+Enter で改行、Enter で送信)",
|
|
14
|
+
"board-ai.text.send-tooltip": "送信 (Enter)",
|
|
15
|
+
"board-ai.text.clear-chat-tooltip": "会話をクリア (サーバー履歴は保持)",
|
|
16
|
+
"board-ai.text.show-examples-tooltip": "よく使う指示の例を表示",
|
|
17
|
+
"board-ai.text.applied-changes": "変更しました。",
|
|
18
|
+
"board-ai.text.reverted": "戻しました",
|
|
19
|
+
"board-ai.text.failed-to-load-history": "履歴の読み込みに失敗",
|
|
20
|
+
"board-ai.text.empty-response": "応答が空です。",
|
|
21
|
+
|
|
22
|
+
"board-ai.example.create-monitoring-dashboard": "稼働率・温度・圧力の 3 ゲージと 24 時間のラインチャートで監視ダッシュボード",
|
|
23
|
+
"board-ai.example.create-welcome-screen": "大きな「OPERATO」タイトルと時計、サブタイトルでウェルカム画面",
|
|
24
|
+
"board-ai.example.edit-align-distribute": "選択したコンポーネントを中央揃えし均等配置",
|
|
25
|
+
"board-ai.example.edit-resize-board": "ボードを 1920x1080 にしてコンポーネントを中央寄せ",
|
|
26
|
+
"board-ai.example.style-dark-mode": "ダークモード — 濃紺の背景、白文字、ティール アクセント",
|
|
27
|
+
"board-ai.example.style-rounded-shadow": "すべての図形を角丸にしてカード風の柔らかい影を追加",
|
|
28
|
+
|
|
29
|
+
"board-ai.button.new-conversation": "新しい会話",
|
|
30
|
+
"board-ai.button.examples": "例",
|
|
31
|
+
"board-ai.button.close": "閉じる",
|
|
32
|
+
"board-ai.button.revert": "元に戻す",
|
|
33
|
+
"board-ai.button.retry": "再試行",
|
|
34
|
+
"board-ai.button.copy": "コピー",
|
|
35
|
+
"board-ai.button.regenerate": "再生成",
|
|
36
|
+
"board-ai.button.edit": "編集",
|
|
37
|
+
|
|
38
|
+
"board-ai.text.copied": "コピーしました"
|
|
39
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"board-ai.label.ai": "operato",
|
|
3
|
+
"board-ai.label.create": "생성",
|
|
4
|
+
"board-ai.label.edit": "편집",
|
|
5
|
+
"board-ai.label.style": "스타일",
|
|
6
|
+
"board-ai.label.korean-supported": "한국어 자유",
|
|
7
|
+
"board-ai.label.multi-command": "다중 명령",
|
|
8
|
+
"board-ai.label.review-able": "검수 가능",
|
|
9
|
+
|
|
10
|
+
"board-ai.text.empty-title": "AI 와 함께 보드를 만들어보세요",
|
|
11
|
+
"board-ai.text.empty-subtitle": "자연어로 명령하시면 AI 가 보드를 생성·편집·스타일링합니다. 아래 예시를 클릭해 시작해보세요.",
|
|
12
|
+
"board-ai.text.empty-footer-notice": "AI 응답은 항상 보드에 적용 전 미리보기로 확인 가능합니다.",
|
|
13
|
+
"board-ai.text.input-placeholder": "자연어로 명령하세요 (Shift+Enter 줄바꿈, Enter 전송)",
|
|
14
|
+
"board-ai.text.send-tooltip": "전송 (Enter)",
|
|
15
|
+
"board-ai.text.clear-chat-tooltip": "대화 초기화 (서버 이력은 유지)",
|
|
16
|
+
"board-ai.text.show-examples-tooltip": "자주 쓰는 명령 예시 보기",
|
|
17
|
+
"board-ai.text.applied-changes": "변경했습니다.",
|
|
18
|
+
"board-ai.text.reverted": "되돌려짐",
|
|
19
|
+
"board-ai.text.failed-to-load-history": "이력 로드 실패",
|
|
20
|
+
"board-ai.text.empty-response": "응답이 비어있습니다.",
|
|
21
|
+
"board-ai.text.tools-used": "도구 사용",
|
|
22
|
+
|
|
23
|
+
"board-ai.example.create-monitoring-dashboard": "가동률·온도·압력 3개 게이지와 24시간 라인 차트로 모니터링 대시보드",
|
|
24
|
+
"board-ai.example.create-welcome-screen": "큰 'OPERATO' 제목과 시계, 부제로 환영 화면",
|
|
25
|
+
"board-ai.example.edit-align-distribute": "선택한 컴포넌트들을 가운데 정렬하고 일정 간격으로 분산",
|
|
26
|
+
"board-ai.example.edit-resize-board": "보드 크기를 1920x1080 으로 변경하고 컴포넌트 중앙 정렬",
|
|
27
|
+
"board-ai.example.style-dark-mode": "다크 모드 — 짙은 남색 배경, 흰색 텍스트, 청록 강조",
|
|
28
|
+
"board-ai.example.style-rounded-shadow": "모든 도형 모서리 둥글게 + 카드형 옅은 그림자",
|
|
29
|
+
|
|
30
|
+
"board-ai.button.new-conversation": "새 대화",
|
|
31
|
+
"board-ai.button.examples": "예시",
|
|
32
|
+
"board-ai.button.close": "닫기",
|
|
33
|
+
"board-ai.button.revert": "되돌리기",
|
|
34
|
+
"board-ai.button.retry": "다시 시도",
|
|
35
|
+
"board-ai.button.copy": "복사",
|
|
36
|
+
"board-ai.button.regenerate": "재생성",
|
|
37
|
+
"board-ai.button.edit": "편집",
|
|
38
|
+
|
|
39
|
+
"board-ai.text.copied": "복사됨"
|
|
40
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"board-ai.label.ai": "operato",
|
|
3
|
+
"board-ai.label.create": "Cipta",
|
|
4
|
+
"board-ai.label.edit": "Edit",
|
|
5
|
+
"board-ai.label.style": "Gaya",
|
|
6
|
+
"board-ai.label.korean-supported": "Pelbagai bahasa",
|
|
7
|
+
"board-ai.label.multi-command": "Arahan kumpulan",
|
|
8
|
+
"board-ai.label.review-able": "Boleh disemak",
|
|
9
|
+
|
|
10
|
+
"board-ai.text.empty-title": "Reka papan bersama AI",
|
|
11
|
+
"board-ai.text.empty-subtitle": "Terangkan dalam bahasa biasa dan AI akan mencipta, mengedit dan menggayakan papan. Klik contoh di bawah untuk bermula.",
|
|
12
|
+
"board-ai.text.empty-footer-notice": "Respons AI dipratonton sebelum diterapkan dan boleh dibatalkan.",
|
|
13
|
+
"board-ai.text.input-placeholder": "Terangkan dalam bahasa biasa (Shift+Enter baris baharu, Enter hantar)",
|
|
14
|
+
"board-ai.text.send-tooltip": "Hantar (Enter)",
|
|
15
|
+
"board-ai.text.clear-chat-tooltip": "Kosongkan sembang (sejarah pelayan kekal)",
|
|
16
|
+
"board-ai.text.show-examples-tooltip": "Tunjuk contoh arahan biasa",
|
|
17
|
+
"board-ai.text.applied-changes": "Diterapkan.",
|
|
18
|
+
"board-ai.text.reverted": "Dibatalkan",
|
|
19
|
+
"board-ai.text.failed-to-load-history": "Gagal memuatkan sejarah",
|
|
20
|
+
"board-ai.text.empty-response": "Respons kosong.",
|
|
21
|
+
|
|
22
|
+
"board-ai.example.create-monitoring-dashboard": "Papan pemantauan dengan 3 tolok (penggunaan, suhu, tekanan) dan carta garis 24 jam",
|
|
23
|
+
"board-ai.example.create-welcome-screen": "Skrin selamat datang dengan tajuk besar 'OPERATO', jam dan sari kata",
|
|
24
|
+
"board-ai.example.edit-align-distribute": "Jajarkan komponen terpilih ke tengah dan agih sama rata",
|
|
25
|
+
"board-ai.example.edit-resize-board": "Ubah saiz papan kepada 1920x1080 dan tengahkan komponen",
|
|
26
|
+
"board-ai.example.style-dark-mode": "Mod gelap — latar biru tua, teks putih, aksen teal",
|
|
27
|
+
"board-ai.example.style-rounded-shadow": "Bulatkan sudut semua bentuk + bayang kad lembut",
|
|
28
|
+
|
|
29
|
+
"board-ai.button.new-conversation": "Sembang baharu",
|
|
30
|
+
"board-ai.button.examples": "Contoh",
|
|
31
|
+
"board-ai.button.close": "Tutup",
|
|
32
|
+
"board-ai.button.revert": "Batalkan",
|
|
33
|
+
"board-ai.button.retry": "Cuba lagi",
|
|
34
|
+
"board-ai.button.copy": "Salin",
|
|
35
|
+
"board-ai.button.regenerate": "Jana semula",
|
|
36
|
+
"board-ai.button.edit": "Edit",
|
|
37
|
+
|
|
38
|
+
"board-ai.text.copied": "Disalin"
|
|
39
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"board-ai.label.ai": "operato",
|
|
3
|
+
"board-ai.label.create": "创建",
|
|
4
|
+
"board-ai.label.edit": "编辑",
|
|
5
|
+
"board-ai.label.style": "样式",
|
|
6
|
+
"board-ai.label.korean-supported": "多语言",
|
|
7
|
+
"board-ai.label.multi-command": "批量命令",
|
|
8
|
+
"board-ai.label.review-able": "可审核",
|
|
9
|
+
|
|
10
|
+
"board-ai.text.empty-title": "与 AI 一起设计看板",
|
|
11
|
+
"board-ai.text.empty-subtitle": "用自然语言描述,AI 将创建、编辑和样式化看板。点击下方示例开始。",
|
|
12
|
+
"board-ai.text.empty-footer-notice": "AI 的响应在应用前会先预览,并可以撤销。",
|
|
13
|
+
"board-ai.text.input-placeholder": "用自然语言描述 (Shift+Enter 换行, Enter 发送)",
|
|
14
|
+
"board-ai.text.send-tooltip": "发送 (Enter)",
|
|
15
|
+
"board-ai.text.clear-chat-tooltip": "清除对话 (保留服务器历史)",
|
|
16
|
+
"board-ai.text.show-examples-tooltip": "显示常用命令示例",
|
|
17
|
+
"board-ai.text.applied-changes": "已应用。",
|
|
18
|
+
"board-ai.text.reverted": "已撤销",
|
|
19
|
+
"board-ai.text.failed-to-load-history": "加载历史失败",
|
|
20
|
+
"board-ai.text.empty-response": "响应为空。",
|
|
21
|
+
|
|
22
|
+
"board-ai.example.create-monitoring-dashboard": "用稼动率、温度、压力 3 个仪表 + 24 小时折线图制作监控看板",
|
|
23
|
+
"board-ai.example.create-welcome-screen": "用大号 'OPERATO' 标题、时钟、副标题做欢迎画面",
|
|
24
|
+
"board-ai.example.edit-align-distribute": "将所选组件居中对齐并均匀分布",
|
|
25
|
+
"board-ai.example.edit-resize-board": "看板调整为 1920x1080 并将组件居中",
|
|
26
|
+
"board-ai.example.style-dark-mode": "深色模式 — 深蓝背景、白色文字、青色强调",
|
|
27
|
+
"board-ai.example.style-rounded-shadow": "所有图形圆角 + 柔和卡片阴影",
|
|
28
|
+
|
|
29
|
+
"board-ai.button.new-conversation": "新对话",
|
|
30
|
+
"board-ai.button.examples": "示例",
|
|
31
|
+
"board-ai.button.close": "关闭",
|
|
32
|
+
"board-ai.button.revert": "撤销",
|
|
33
|
+
"board-ai.button.retry": "重试",
|
|
34
|
+
"board-ai.button.copy": "复制",
|
|
35
|
+
"board-ai.button.regenerate": "重新生成",
|
|
36
|
+
"board-ai.button.edit": "编辑",
|
|
37
|
+
|
|
38
|
+
"board-ai.text.copied": "已复制"
|
|
39
|
+
}
|