@nine-lab/nine-mu 0.1.172 → 0.1.174

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nine-lab/nine-mu",
3
- "version": "0.1.172",
3
+ "version": "0.1.174",
4
4
  "description": "AI-Driven Full-Stack Code Fabrication Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/nine-mu.umd.js",
@@ -979,4 +979,221 @@
979
979
  box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.15);
980
980
  }
981
981
  }
982
+
983
+ nine-chat-ing {
984
+ display: flex;
985
+ justify-content: flex-start;
986
+ padding: 0;
987
+
988
+ .chat-message {
989
+ padding: 0px 8px;
990
+ color: #999;
991
+ align-self: flex-start;
992
+ text-align: left;
993
+ position: relative;
994
+ font-size: 32px;
995
+ font-weight: bold;
996
+ }
997
+ }
998
+
999
+ nine-chat-ai {
1000
+ display: flex;
1001
+ justify-content: flex-start;
1002
+ padding: 5px;
1003
+ flex-direction: column;
1004
+
1005
+ .chat-message {
1006
+ max-width: 70%;
1007
+ border-radius: 8px;
1008
+ font-size: 14px;
1009
+ background-color: #fff;
1010
+ color: black;
1011
+ align-self: flex-start;
1012
+ text-align: left;
1013
+ position: relative;
1014
+ box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.15);
1015
+ text-overflow: ellipsis;
1016
+ padding: 8px 16px;
1017
+ display: flex;
1018
+ align-items: center;
1019
+
1020
+ div.message {
1021
+ display: -webkit-box;
1022
+ -webkit-line-clamp: 3;
1023
+ -webkit-box-orient: vertical;
1024
+ overflow: hidden;
1025
+ padding: 0;
1026
+ flex-grow: 1;
1027
+ /* 줄바꿈 강제 적용 */
1028
+ /**word-wrap: break-word;*/ /* 긴 단어를 줄바꿈 */
1029
+ overflow-wrap: anywhere; /* 텍스트 길이에 따라 자동 줄바꿈 */
1030
+ white-space: normal; /* 공백 처리 */
1031
+ }
1032
+
1033
+ span.more {
1034
+ right: 4px;
1035
+ bottom: 0px;
1036
+ font-size: 9px;
1037
+ font-weight: 700;
1038
+
1039
+ a {
1040
+ position: relative;
1041
+ color: green;
1042
+ text-decoration: none;
1043
+ }
1044
+
1045
+ a::after {
1046
+ content: "";
1047
+ position: absolute;
1048
+ left: 0;
1049
+ bottom: -2px;
1050
+ width: 100%;
1051
+ height: 2px;
1052
+ background-color: green;
1053
+ transform: scaleX(0);
1054
+ transition: transform 0.3s ease-in-out;
1055
+ }
1056
+
1057
+ a:hover::after {
1058
+ transform: scaleX(1);
1059
+ }
1060
+ }
1061
+ }
1062
+
1063
+ .grid {
1064
+ margin-top: 8px;
1065
+ }
1066
+
1067
+ .chat-menu {
1068
+ display: flex;
1069
+ justify-content: space-between; /* 좌우 정렬 */
1070
+ align-items: center; /* 세로 중앙 정렬 */
1071
+ width: 100%;
1072
+ margin-top: 2px;
1073
+
1074
+ .left-menu{
1075
+ display: flex;
1076
+ gap: 4px;
1077
+
1078
+ .filter.disabled, .database.disabled {
1079
+ pointer-events: none;
1080
+ color: #ccc;
1081
+ }
1082
+
1083
+ .filter, .database, .excel, .maximize {
1084
+ margin-left: 0;
1085
+ cursor: pointer;
1086
+ color: #999;
1087
+ width: 16px;
1088
+ height: 16px;
1089
+ background-repeat: no-repeat;
1090
+ background-position: center;
1091
+ background-size: auto;
1092
+ }
1093
+
1094
+ .filter svg {
1095
+ color: #999;
1096
+ }
1097
+
1098
+ .filter:hover, .database:hover, .excel:hover, .maximize:hover {
1099
+ color: green;
1100
+ }
1101
+
1102
+ .filter {
1103
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="gray" viewBox="0 0 16 16"><path d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5zm1 .5v1.308l4.372 4.858A.5.5 0 0 1 7 8.5v5.306l2-.666V8.5a.5.5 0 0 1 .128-.334L13.5 3.308V2z"/></svg>');
1104
+ }
1105
+ .database {
1106
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="gray" viewBox="0 0 16 16"><path d="M4.318 2.687C5.234 2.271 6.536 2 8 2s2.766.27 3.682.687C12.644 3.125 13 3.627 13 4c0 .374-.356.875-1.318 1.313C10.766 5.729 9.464 6 8 6s-2.766-.27-3.682-.687C3.356 4.875 3 4.373 3 4c0-.374.356-.875 1.318-1.313M13 5.698V7c0 .374-.356.875-1.318 1.313C10.766 8.729 9.464 9 8 9s-2.766-.27-3.682-.687C3.356 7.875 3 7.373 3 7V5.698c.271.202.58.378.904.525C4.978 6.711 6.427 7 8 7s3.022-.289 4.096-.777A5 5 0 0 0 13 5.698M14 4c0-1.007-.875-1.755-1.904-2.223C11.022 1.289 9.573 1 8 1s-3.022.289-4.096.777C2.875 2.245 2 2.993 2 4v9c0 1.007.875 1.755 1.904 2.223C4.978 15.71 6.427 16 8 16s3.022-.289 4.096-.777C13.125 14.755 14 14.007 14 13zm-1 4.698V10c0 .374-.356.875-1.318 1.313C10.766 11.729 9.464 12 8 12s-2.766-.27-3.682-.687C3.356 10.875 3 10.373 3 10V8.698c.271.202.58.378.904.525C4.978 9.71 6.427 10 8 10s3.022-.289 4.096-.777A5 5 0 0 0 13 8.698m0 3V13c0 .374-.356.875-1.318 1.313C10.766 14.729 9.464 15 8 15s-2.766-.27-3.682-.687C3.356 13.875 3 13.373 3 13v-1.302c.271.202.58.378.904.525C4.978 12.71 6.427 13 8 13s3.022-.289 4.096-.777c.324-.147.633-.323.904-.525"/></svg>');
1107
+ }
1108
+ .excel {
1109
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="gray" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M14 4.5V14a2 2 0 0 1-2 2h-1v-1h1a1 1 0 0 0 1-1V4.5h-2A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v9H2V2a2 2 0 0 1 2-2h5.5zM6.472 15.29a1.2 1.2 0 0 1-.111-.449h.765a.58.58 0 0 0 .254.384q.106.073.25.114.143.041.319.041.246 0 .413-.07a.56.56 0 0 0 .255-.193.5.5 0 0 0 .085-.29.39.39 0 0 0-.153-.326q-.152-.12-.462-.193l-.619-.143a1.7 1.7 0 0 1-.539-.214 1 1 0 0 1-.351-.367 1.1 1.1 0 0 1-.123-.524q0-.366.19-.639.19-.272.527-.422.338-.15.777-.149.457 0 .78.152.324.153.5.41.18.255.2.566h-.75a.56.56 0 0 0-.12-.258.6.6 0 0 0-.247-.181.9.9 0 0 0-.369-.068q-.325 0-.513.152a.47.47 0 0 0-.184.384q0 .18.143.3a1 1 0 0 0 .405.175l.62.143q.326.075.566.211a1 1 0 0 1 .375.358q.135.222.135.56 0 .37-.188.656a1.2 1.2 0 0 1-.539.439q-.351.158-.858.158-.381 0-.665-.09a1.4 1.4 0 0 1-.478-.252 1.1 1.1 0 0 1-.29-.375m-2.945-3.358h-.893L1.81 13.37h-.036l-.832-1.438h-.93l1.227 1.983L0 15.931h.861l.853-1.415h.035l.85 1.415h.908L2.253 13.94zm2.727 3.325H4.557v-3.325h-.79v4h2.487z"/></svg>');
1110
+ }
1111
+ .maximize {
1112
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="gray" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M5.828 10.172a.5.5 0 0 0-.707 0l-4.096 4.096V11.5a.5.5 0 0 0-1 0v3.975a.5.5 0 0 0 .5.5H4.5a.5.5 0 0 0 0-1H1.732l4.096-4.096a.5.5 0 0 0 0-.707m4.344 0a.5.5 0 0 1 .707 0l4.096 4.096V11.5a.5.5 0 1 1 1 0v3.975a.5.5 0 0 1-.5.5H11.5a.5.5 0 0 1 0-1h2.768l-4.096-4.096a.5.5 0 0 1 0-.707m0-4.344a.5.5 0 0 0 .707 0l4.096-4.096V4.5a.5.5 0 1 0 1 0V.525a.5.5 0 0 0-.5-.5H11.5a.5.5 0 0 0 0 1h2.768l-4.096 4.096a.5.5 0 0 0 0 .707m-4.344 0a.5.5 0 0 1-.707 0L1.025 1.732V4.5a.5.5 0 0 1-1 0V.525a.5.5 0 0 1 .5-.5H4.5a.5.5 0 0 1 0 1H1.732l4.096 4.096a.5.5 0 0 1 0 .707"/></svg>');
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+
1118
+ nine-chat-progress {
1119
+ display: flex;
1120
+ justify-content: flex-start;
1121
+ padding: 5px;
1122
+ flex-direction: column;
1123
+
1124
+ .chat-message.progress-message {
1125
+ max-width: 80%;
1126
+ border-radius: 8px;
1127
+ font-size: 14px;
1128
+ background-color: #fff;
1129
+ color: black;
1130
+ align-self: flex-start;
1131
+ text-align: left;
1132
+ position: relative;
1133
+ box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.15);
1134
+ padding: 8px 16px; /* 버블 자체의 패딩 */
1135
+ }
1136
+
1137
+ .progress-list {
1138
+ list-style: none;
1139
+ padding: 0;
1140
+ margin: 0;
1141
+ --font-size: 12px;
1142
+ }
1143
+
1144
+ .progress-item {
1145
+ display: flex;
1146
+ align-items: center; /* 번호, 텍스트, 점을 세로 중앙 정렬 */
1147
+ margin-bottom: 5px;
1148
+ color: #999; /* 기본 텍스트 색상 */
1149
+ font-size: 1em; /* 부모 폰트 사이즈(14px)를 따르도록 */
1150
+ line-height: 1.4; /* 가독성을 위해 줄 간격 추가 */
1151
+ }
1152
+
1153
+ .progress-item:last-child {
1154
+ margin-bottom: 0;
1155
+ }
1156
+
1157
+ /* 번호 스타일 */
1158
+ .progress-item .step-number {
1159
+ --font-weight: bold;
1160
+ margin-right: 5px; /* 번호와 텍스트 사이 간격 */
1161
+ color: #999; /* 번호 색상 */
1162
+ }
1163
+
1164
+ /* 텍스트 내용 */
1165
+ .progress-item .text {
1166
+ --flex-grow: 1; /* 텍스트가 공간을 채우도록 */
1167
+ white-space: nowrap; /* 텍스트가 줄바꿈되지 않도록 */
1168
+ }
1169
+
1170
+ /* 진행 중 점 애니메이션 */
1171
+ .progress-item .animated-dots {
1172
+ width: 20px; /* 점 공간 확보 */
1173
+ text-align: left; /* 점이 왼쪽에서 시작되도록 */
1174
+ font-weight: bold;
1175
+ }
1176
+
1177
+ /* completed 상태 */
1178
+ .progress-item.completed {
1179
+ color: #333; /* 완료된 텍스트 색상 */
1180
+ --font-weight: bold; /* 완료 시 굵게 */
1181
+ }
1182
+ .progress-item.completed .animated-dots::after {
1183
+ content: '✓'; /* 체크마크 */
1184
+ margin-left: 5px; /* 체크마크와 텍스트 사이 간격 */
1185
+ color: #28a745;
1186
+ font-size: 1.0em; /* 체크마크 크기 */
1187
+ font-weight: bold;
1188
+ }
1189
+
1190
+ .progress-item.completed .step-number {
1191
+ color: #333; /* 번호 색상 */
1192
+ }
1193
+
1194
+ /* pending 상태에만 애니메이션 점 표시 */
1195
+ .progress-item.pending .animated-dots {
1196
+ /* JS로 내용이 채워지므로 별도의 CSS 애니메이션은 필요 없음 */
1197
+ }
1198
+ }
982
1199
  }
@@ -1,4 +1,4 @@
1
- class aiMessage extends HTMLElement
1
+ class AiMessage extends HTMLElement
2
2
  {
3
3
  #message;
4
4
  #data;
@@ -163,7 +163,7 @@ class aiMessage extends HTMLElement
163
163
  };
164
164
  }
165
165
 
166
- class aiIngMessage extends HTMLElement
166
+ class IngMessage extends HTMLElement
167
167
  {
168
168
  #message;
169
169
 
@@ -213,7 +213,7 @@ class MyMessage extends HTMLElement
213
213
 
214
214
  // aiProgressMessage 클래스 정의
215
215
  // aiProgressMessage 클래스 정의 수정
216
- class aiProgressMessage extends HTMLElement {
216
+ class ProgressMessage extends HTMLElement {
217
217
  #progressData = [];
218
218
  #progressElements = new Map();
219
219
  #animationIntervals = new Map();
@@ -224,7 +224,6 @@ class aiProgressMessage extends HTMLElement {
224
224
 
225
225
  connectedCallback() {
226
226
  this.innerHTML = `
227
-
228
227
  <div class="chat-message progress-message">
229
228
  <ul class="progress-list"></ul>
230
229
  </div>
@@ -354,7 +353,7 @@ class aiProgressMessage extends HTMLElement {
354
353
 
355
354
 
356
355
 
357
- class ChatMessage extends HTMLElement
356
+ class ChatMessageBody extends HTMLElement
358
357
  {
359
358
  constructor() {
360
359
  super();
@@ -407,17 +406,17 @@ class ChatMessage extends HTMLElement
407
406
  break;
408
407
 
409
408
  case "ing":
410
- el = document.createElement("nx-ai-ing-message");
409
+ el = document.createElement("nine-chat-ing");
411
410
  //el.setAttribute("message", message);
412
411
  target.appendChild(el);
413
412
  break;
414
413
 
415
414
  case "ai":
416
- this.shadowRoot.querySelectorAll("nx-ai-ing-message").forEach(el => {
415
+ this.shadowRoot.querySelectorAll("nine-chat-ing").forEach(el => {
417
416
  el.remove();
418
417
  });
419
418
 
420
- el = document.createElement("nx-ai-message");
419
+ el = document.createElement("nine-chat-ai");
421
420
  el.setAttribute("message", message);
422
421
  el.setAttribute("row-count", data ? data.length : 0);
423
422
  //el.data = data;
@@ -448,11 +447,11 @@ class ChatMessage extends HTMLElement
448
447
 
449
448
  const target = this.shadowRoot.querySelector(".chat-body");
450
449
 
451
- this.shadowRoot.querySelectorAll("nx-ai-ing-message").forEach(el => {
450
+ this.shadowRoot.querySelectorAll("nine-chat-ing").forEach(el => {
452
451
  el.remove();
453
452
  });
454
453
 
455
- let el = document.createElement("nx-ai-progress-message");
454
+ let el = document.createElement("nine-chat-progress");
456
455
  if (progressData) {
457
456
  el.initialize(progressData); // progressData로 초기화
458
457
  }
@@ -468,24 +467,24 @@ class ChatMessage extends HTMLElement
468
467
  };
469
468
  }
470
469
 
470
+ if (!customElements.get('nine-chat-message')) {
471
+ customElements.define("nine-chat-message", ChatMessageBody);
472
+ }
471
473
 
472
- if (!customElements.get('nx-ai-message')) {
473
- customElements.define("nx-ai-message", aiMessage);
474
+ if (!customElements.get('nine-chat-me')) {
475
+ customElements.define("nine-chat-me", MyMessage);
474
476
  }
475
477
 
476
- if (!customElements.get('nx-ai-ing-message')) {
477
- customElements.define("nx-ai-ing-message", aiIngMessage);
478
+ if (!customElements.get('nine-chat-ai')) {
479
+ customElements.define("nine-chat-ai", AiMessage);
478
480
  }
479
481
 
480
- if (!customElements.get('nx-ai-progress-message')) {
481
- customElements.define("nx-ai-progress-message", aiProgressMessage);
482
+ if (!customElements.get('nine-chat-ing')) {
483
+ customElements.define("nine-chat-ing", IngMessage);
482
484
  }
483
485
 
486
+ if (!customElements.get('nine-chat-progress')) {
487
+ customElements.define("nine-chat-progress", ProgressMessage);
488
+ }
484
489
 
485
490
 
486
- if (!customElements.get('nine-chat-message')) {
487
- customElements.define("nine-chat-message", ChatMessage);
488
- }
489
- if (!customElements.get('nine-chat-me')) {
490
- customElements.define("nine-chat-me", MyMessage);
491
- }
@@ -91,17 +91,16 @@ export class NineChat extends HTMLElement {
91
91
 
92
92
  // 3. nine.safe로 매니저 로직 실행
93
93
  const [result, err] = await nine.safe(this.#manager.handleChatSubmit(target));
94
+
94
95
  target.removeAttribute('disabled');
95
96
  target.focus();
96
97
 
97
98
  if (err) {
98
- console.error("Manager 실행 에러:", err);
99
- // 필요 'ing' 메시지 제거 사용자 알림
100
- this.shadowRoot.querySelectorAll("nx-ai-ing-message").forEach(el => el.remove());
99
+ console.error(err);
100
+ this.#$nineChatMessage.add("ai", err.message || "알 없는 오류가 발생했습니다. 다시 시도해주세요.");
101
101
  } else {
102
102
  console.log(result);
103
- //this.#$nineChatMessage.add("me", userInput);
104
- this.#$nineChatMessage.add("ai", result.message); // 로딩 상태
103
+ this.#$nineChatMessage.add("ai", result.message);
105
104
  }
106
105
  }
107
106
  });