loadtoagent 1.1.0 → 1.3.2
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/README.ko.md +14 -5
- package/README.md +7 -0
- package/README.zh-CN.md +7 -0
- package/docs/PROVIDER-CONTRACTS.md +25 -1
- package/docs/UI-AUDIT-100.md +118 -0
- package/docs/UI-AUDIT-101-200.md +120 -0
- package/docs/UI-AUDIT-201-300.md +120 -0
- package/main.js +157 -38
- package/package.json +13 -4
- package/preload.js +13 -2
- package/renderer/app-agent-actions.js +125 -53
- package/renderer/app-bootstrap.js +54 -19
- package/renderer/app-dashboard.js +196 -55
- package/renderer/app-drawer-content.js +48 -44
- package/renderer/app-drawer-data.js +26 -13
- package/renderer/app-drawer.js +72 -54
- package/renderer/app-events-dialogs.js +146 -37
- package/renderer/app-events-filters.js +172 -13
- package/renderer/app-events-navigation.js +77 -30
- package/renderer/app-events-sessions.js +156 -9
- package/renderer/app-events.js +2 -1
- package/renderer/app-graph-model.js +20 -38
- package/renderer/app-graph-orchestration.js +15 -13
- package/renderer/app-graph-view.js +228 -113
- package/renderer/app-management.js +257 -0
- package/renderer/app-provider-visibility.js +124 -0
- package/renderer/app-quality.js +568 -0
- package/renderer/app-run-modal.js +104 -34
- package/renderer/app-runtime-overview.js +312 -0
- package/renderer/app-session-render.js +94 -37
- package/renderer/app-tmux-render.js +52 -44
- package/renderer/app.js +153 -75
- package/renderer/i18n-messages.js +867 -37
- package/renderer/i18n.js +104 -0
- package/renderer/index.html +154 -67
- package/renderer/shared.js +17 -0
- package/renderer/styles-agent-map.css +16 -10
- package/renderer/styles-cards.css +44 -18
- package/renderer/styles-collaboration.css +23 -23
- package/renderer/styles-components.css +122 -45
- package/renderer/styles-management.css +364 -0
- package/renderer/styles-onboarding.css +8 -8
- package/renderer/styles-overlays.css +13 -7
- package/renderer/styles-product.css +48 -40
- package/renderer/styles-quality.css +312 -0
- package/renderer/styles-readability.css +1040 -0
- package/renderer/styles-responsive-product.css +84 -12
- package/renderer/styles-responsive-runtime.css +25 -17
- package/renderer/styles-responsive-shell.css +44 -48
- package/renderer/styles-responsive-workflows.css +39 -5
- package/renderer/styles-run-composer.css +28 -23
- package/renderer/styles-runtime-overview.css +285 -0
- package/renderer/styles-settings.css +176 -16
- package/renderer/styles-terminal.css +374 -37
- package/renderer/styles-tmux.css +49 -49
- package/renderer/styles-workflow-map.css +362 -15
- package/renderer/styles-workflows.css +116 -49
- package/renderer/styles.css +34 -19
- package/renderer/terminal-agent.js +17 -13
- package/renderer/terminal-events.js +253 -37
- package/renderer/terminal-workbench.js +208 -89
- package/renderer/terminal.js +350 -35
- package/src/agentMonitor/claudeParser.js +96 -7
- package/src/agentMonitor/codexParser.js +59 -4
- package/src/agentMonitor/executionActivity.js +282 -0
- package/src/agentMonitor/genericParser.js +56 -13
- package/src/agentMonitor/hierarchy.js +17 -0
- package/src/agentMonitor/responseIntent.js +51 -0
- package/src/agentMonitor.js +21 -3
- package/src/agentRunner.js +66 -1
- package/src/attentionNotifier.js +14 -10
- package/src/automationMonitor.js +258 -0
- package/src/contracts.js +10 -1
- package/src/ipc/registerAgentIpc.js +9 -3
- package/src/ipc/registerAppIpc.js +4 -1
- package/src/ipc/registerTerminalIpc.js +12 -14
- package/src/macUpdateHelper.js +210 -0
- package/src/monitorWorker.js +65 -6
- package/src/platformPath.js +80 -0
- package/src/processMonitor.js +80 -22
- package/src/providerVisibilityStore.js +45 -0
- package/src/sessionIntelligence.js +261 -0
- package/src/terminalHost.js +453 -0
- package/src/terminalHostDaemon.js +61 -0
- package/src/terminalManager.js +218 -6
- package/src/updateInstaller.js +175 -0
package/renderer/index.html
CHANGED
|
@@ -17,17 +17,21 @@
|
|
|
17
17
|
<link rel="stylesheet" href="styles-terminal.css" />
|
|
18
18
|
<link rel="stylesheet" href="styles-run-composer.css" />
|
|
19
19
|
<link rel="stylesheet" href="styles-product.css" />
|
|
20
|
+
<link rel="stylesheet" href="styles-management.css" />
|
|
21
|
+
<link rel="stylesheet" href="styles-runtime-overview.css" />
|
|
20
22
|
<link rel="stylesheet" href="styles-onboarding.css" />
|
|
21
23
|
<link rel="stylesheet" href="styles-settings.css" />
|
|
24
|
+
<link rel="stylesheet" href="styles-quality.css" />
|
|
22
25
|
<link rel="stylesheet" href="styles-responsive-shell.css" />
|
|
23
26
|
<link rel="stylesheet" href="styles-responsive-workflows.css" />
|
|
24
27
|
<link rel="stylesheet" href="styles-responsive-runtime.css" />
|
|
25
28
|
<link rel="stylesheet" href="styles-responsive-product.css" />
|
|
26
29
|
<link rel="stylesheet" href="../node_modules/@xterm/xterm/css/xterm.css" />
|
|
30
|
+
<link rel="stylesheet" href="styles-readability.css" />
|
|
27
31
|
</head>
|
|
28
32
|
<body>
|
|
29
|
-
<
|
|
30
|
-
|
|
33
|
+
<div id="appShell" class="app-shell">
|
|
34
|
+
<a class="skip-link" href="#mainContent" data-i18n="app.accessibility.skip_to_content">본문으로 바로가기</a>
|
|
31
35
|
<aside class="sidebar">
|
|
32
36
|
<div class="brand">
|
|
33
37
|
<div class="brand-orbit" aria-hidden="true"><span></span></div>
|
|
@@ -35,26 +39,30 @@
|
|
|
35
39
|
</div>
|
|
36
40
|
|
|
37
41
|
<nav class="view-nav" aria-label="화면 선택" data-i18n-aria-label="app.nav.label">
|
|
38
|
-
<button class="nav-item active" type="button" data-view="all"><span class="nav-icon">⌂</span><span data-i18n="app.nav.home">홈</span><b id="navAllCount">0</b></button>
|
|
39
|
-
<button class="nav-item" type="button" data-view="active"><span class="nav-icon live-dot"></span><span data-i18n="app.nav.active">진행 중</span><b id="navActiveCount">0</b></button>
|
|
40
|
-
<button class="nav-item" type="button" data-view="waiting"><span class="nav-icon">!</span><span data-i18n="app.nav.needs_review"
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
<button class="nav-item active" type="button" data-view="all" aria-label="홈" data-i18n-aria-label="app.nav.home" aria-keyshortcuts="Meta+1 Control+1" aria-controls="operationsOverview liveSection globalStats sessionSection beginnerGuide providerOverview" title="홈" data-i18n-title="app.nav.home"><span class="nav-icon">⌂</span><span data-i18n="app.nav.home">홈</span><b><span id="navAllCount">0</span><small data-i18n="quality.unit.tasks">작업</small></b></button>
|
|
43
|
+
<button class="nav-item" type="button" data-view="active" aria-label="진행 중" data-i18n-aria-label="app.nav.active" aria-keyshortcuts="Meta+2 Control+2" aria-controls="operationsOverview liveSection activeEmptyState" title="진행 중" data-i18n-title="app.nav.active"><span class="nav-icon live-dot"></span><span data-i18n="app.nav.active">진행 중</span><b><span id="navActiveCount">0</span><small data-i18n="quality.unit.tasks">작업</small></b></button>
|
|
44
|
+
<button class="nav-item" type="button" data-view="waiting" aria-label="확인할 일" data-i18n-aria-label="app.nav.needs_review" aria-keyshortcuts="Meta+3 Control+3" aria-controls="attentionInbox" title="확인할 일" data-i18n-title="app.nav.needs_review"><span class="nav-icon">!</span><span data-i18n="app.nav.needs_review">확인할 일</span><b><span id="navWaitingCount">0</span><small data-i18n="quality.unit.items">항목</small></b></button>
|
|
45
|
+
<details id="advancedToolsNav" class="advanced-tools-nav">
|
|
46
|
+
<summary><span class="nav-icon">⌁</span><span data-i18n="management.advanced_tools">고급 도구</span><b><span id="advancedToolsCount">0</span><small data-i18n="quality.unit.items">항목</small></b><i aria-hidden="true">⌄</i></summary>
|
|
47
|
+
<div class="advanced-tools-list">
|
|
48
|
+
<button class="nav-item runtime-nav-item" type="button" data-view="runtime" aria-label="예약·실행 단계" data-i18n-aria-label="app.nav.runtime" aria-keyshortcuts="Meta+4 Control+4" aria-controls="automationOverview" title="예약·실행 단계" data-i18n-title="app.nav.runtime"><span class="nav-icon runtime-nav-icon">↻</span><span data-i18n="app.nav.runtime">예약·실행 단계</span><b><span id="navRuntimeCount">0</span><small data-i18n="quality.unit.runs">실행</small></b></button>
|
|
49
|
+
<button class="nav-item" type="button" data-view="terminal" aria-label="AI 세션 터미널" data-i18n-aria-label="app.nav.session_terminal" aria-keyshortcuts="Meta+5 Control+5" aria-controls="terminalSection" title="AI 세션 터미널" data-i18n-title="app.nav.session_terminal"><span class="nav-icon">›_</span><span data-i18n="app.nav.session_terminal">AI 세션 터미널</span><b><span id="navTerminalCount">0</span><small data-i18n="quality.unit.sessions">세션</small></b></button>
|
|
50
|
+
<button class="nav-item tmux-nav-item" type="button" data-view="tmux" aria-label="tmux 터미널 관리" data-i18n-aria-label="app.nav.tmux" aria-keyshortcuts="Meta+6 Control+6" aria-controls="tmuxSection" title="tmux 터미널 관리" data-i18n-title="app.nav.tmux"><span class="nav-icon">▦</span><span data-i18n="app.nav.tmux">tmux 터미널 관리</span><b><span id="navTmuxCount">0</span><small data-i18n="quality.unit.sessions">세션</small></b></button>
|
|
51
|
+
</div>
|
|
52
|
+
</details>
|
|
45
53
|
<div class="nav-group-label" data-i18n="app.nav.application">프로그램</div>
|
|
46
|
-
<button class="nav-item settings-nav-item" type="button" data-view="settings"><span class="nav-icon">⚙</span><span data-i18n="app.nav.settings">설정</span><b id="navUpdateBadge" class="hidden">NEW</b></button>
|
|
47
|
-
<button id="mobileMoreBtn" class="nav-item mobile-more-nav" type="button" aria-
|
|
54
|
+
<button class="nav-item settings-nav-item" type="button" data-view="settings" aria-label="설정" data-i18n-aria-label="app.nav.settings" aria-keyshortcuts="Meta+7 Control+7" aria-controls="settingsSection" title="설정" data-i18n-title="app.nav.settings"><span class="nav-icon">⚙</span><span data-i18n="app.nav.settings">설정</span><b id="navUpdateBadge" class="hidden">NEW</b></button>
|
|
55
|
+
<button id="mobileMoreBtn" class="nav-item mobile-more-nav" type="button" aria-label="더보기" data-i18n-aria-label="app.nav.more" title="더보기" data-i18n-title="app.nav.more" aria-expanded="false" aria-controls="mobileToolsMenu"><span class="nav-icon">•••</span><span data-i18n="app.nav.more">더보기</span></button>
|
|
48
56
|
</nav>
|
|
49
57
|
|
|
50
58
|
<section class="sidebar-section">
|
|
51
|
-
<div class="section-title"><span data-i18n="ui.available_ai"
|
|
59
|
+
<div class="section-title"><span data-i18n="ui.available_ai">설치가 감지된 AI CLI</span><button id="probeBtn" class="icon-button" type="button" title="AI CLI 설치 상태 다시 확인" data-i18n-title="ui.check_ai_connections_again" aria-label="AI CLI 설치 상태 다시 확인" data-i18n-aria-label="ui.check_ai_connections_again" aria-controls="providerRail">↻</button></div>
|
|
52
60
|
<div id="providerRail" class="provider-rail"></div>
|
|
53
61
|
</section>
|
|
54
62
|
|
|
55
63
|
<section class="sidebar-section workspace-section">
|
|
56
|
-
<div class="section-title"><span data-i18n="ui.workspaces"
|
|
57
|
-
<div id="workspaceList" class="workspace-list"></div>
|
|
64
|
+
<div class="section-title"><span data-i18n="ui.workspaces">프로젝트 폴더 필터</span><button id="addWorkspaceBtn" class="icon-button" type="button" title="폴더 필터 추가" data-i18n-title="ui.add_workspace" aria-label="폴더 필터 추가" data-i18n-aria-label="ui.add_workspace" aria-controls="workspaceList">+</button></div>
|
|
65
|
+
<div id="workspaceList" class="workspace-list" role="group" aria-label="작업 시작 폴더별 AI 세션 필터" data-i18n-aria-label="quality.workspace_filter"></div>
|
|
58
66
|
</section>
|
|
59
67
|
|
|
60
68
|
<div class="sidebar-footer">
|
|
@@ -69,15 +77,22 @@
|
|
|
69
77
|
<div>
|
|
70
78
|
<p id="pageEyebrow" class="eyebrow" data-i18n="ui.ai_work_overview">AI 작업 현황</p>
|
|
71
79
|
<h1 id="pageTitle" data-i18n="ui.see_all_ai_work_at_a_glance">AI 작업을 한눈에 확인하세요.</h1>
|
|
72
|
-
<p id="pageSubtitle" class="subtitle" data-i18n="ui.active_work_and_items_needing_your_review_appear_first_find">진행 중인 일과 내 확인이 필요한 일을 먼저 보여주고, 나머지 기록은 아래에서 찾을 수 있습니다.</p>
|
|
80
|
+
<p id="pageSubtitle" class="subtitle" data-i18n="ui.active_work_and_items_needing_your_review_appear_first_find">진행 중인 일과 내 응답·상태 확인이 필요한 일을 먼저 보여주고, 나머지 기록은 아래에서 찾을 수 있습니다.</p>
|
|
73
81
|
</div>
|
|
74
82
|
<div class="top-actions">
|
|
75
|
-
<button id="
|
|
76
|
-
<
|
|
83
|
+
<button id="shortcutHelpBtn" class="top-icon-action" type="button" aria-label="키보드 단축키 보기" data-i18n-aria-label="quality.shortcuts.open" aria-keyshortcuts="?" aria-controls="shortcutHelpModal"><span aria-hidden="true">⌨</span></button>
|
|
84
|
+
<button id="guideBtn" class="guide-toggle" type="button" aria-controls="beginnerGuide" aria-expanded="false"><span aria-hidden="true">?</span><span><b data-i18n="ui.10_minute_quick_start">10분 시작 가이드</b><small id="guideButtonProgress" data-i18n="common.progress" data-i18n-params='{"current":0,"total":4}'>0 / 4 완료</small></span></button>
|
|
85
|
+
<div id="appConnectionState" class="sync-state" role="status" aria-live="polite"><span aria-hidden="true"></span><div><b data-i18n="ui.app_connection">앱 연결</b><small id="lastSync" data-i18n="ui.connecting">연결 중</small></div></div>
|
|
77
86
|
<button id="newRunBtn" class="primary-button new-run-cta" type="button" aria-label="AI에게 새 일 맡기기" data-i18n-aria-label="ui.assign_a_new_task_to_ai" aria-keyshortcuts="Meta+N Control+N"><span class="new-run-cta-icon" aria-hidden="true">+</span><span class="new-run-cta-copy"><b data-i18n="ui.new_ai_task">새 AI 작업</b><small><kbd>⌘N</kbd></small></span></button>
|
|
78
87
|
</div>
|
|
79
88
|
</header>
|
|
80
89
|
|
|
90
|
+
<section id="appErrorBanner" class="app-error-banner hidden" role="alert" aria-labelledby="appErrorTitle">
|
|
91
|
+
<span class="app-error-icon" aria-hidden="true">!</span>
|
|
92
|
+
<div><b id="appErrorTitle" data-i18n="bootstrap.error_title">작업 정보를 불러오지 못했습니다</b><p id="appErrorMessage" data-i18n="bootstrap.error_description">연결을 확인한 뒤 다시 시도하세요. 이 안내는 문제가 해결될 때까지 유지됩니다.</p></div>
|
|
93
|
+
<div class="app-error-actions"><button id="appRetryBtn" type="button" data-i18n="bootstrap.retry">다시 연결</button><button id="appErrorCopyBtn" type="button" data-i18n="bootstrap.copy_error">오류 내용 복사</button></div>
|
|
94
|
+
</section>
|
|
95
|
+
|
|
81
96
|
<section id="beginnerGuide" class="beginner-guide" aria-labelledby="beginnerGuideTitle">
|
|
82
97
|
<div class="beginner-guide-intro">
|
|
83
98
|
<span class="guide-time" data-i18n="ui.first_10_minutes">첫 10분 코스</span>
|
|
@@ -88,7 +103,7 @@
|
|
|
88
103
|
<ol>
|
|
89
104
|
<li data-guide-step="create"><button type="button" data-guide-action="create"><i>1</i><span><b data-i18n="ui.assign_work_to_ai">AI에게 일 맡기기</b><small data-i18n="ui.choose_a_task_and_workspace_to_get_started">할 일과 작업 폴더를 고르면 바로 시작돼요.</small><em data-i18n="ui.try_it">직접 해보기 →</em></span></button></li>
|
|
90
105
|
<li data-guide-step="active"><button type="button" data-guide-action="active"><i>2</i><span><b data-i18n="ui.check_progress">진행 상황 확인</b><small data-i18n="ui.ai_with_a_green_indicator_is_working_now">초록 표시가 있는 AI는 지금 일하고 있어요.</small><em data-i18n="ui.view_active_work">진행 중 보기 →</em></span></button></li>
|
|
91
|
-
<li data-guide-step="waiting"><button type="button" data-guide-action="waiting"><i>3</i><span><b data-i18n="ui.find_items_to_review"
|
|
106
|
+
<li data-guide-step="waiting"><button type="button" data-guide-action="waiting"><i>3</i><span><b data-i18n="ui.find_items_to_review">내 응답과 상태 신호 확인</b><small data-i18n="ui.items_marked_needs_review_need_a_response_or_choice">내가 답할 요청과 AI 상태 위험 신호를 구분해서 확인해요.</small><em data-i18n="ui.view_review_items">확인할 일 보기 →</em></span></button></li>
|
|
92
107
|
<li data-guide-step="detail"><button type="button" data-guide-action="detail"><i>4</i><span><b data-i18n="drawer.title">작업 자세히 보기</b><small data-i18n="ui.see_conversation_progress_and_usage_in_one_place">대화, 진행 과정, 사용량을 한곳에서 확인해요.</small><em data-i18n="ui.open_a_task">작업 열어보기 →</em></span></button></li>
|
|
93
108
|
</ol>
|
|
94
109
|
<button id="dismissGuideBtn" class="guide-dismiss" type="button" data-i18n="ui.collapse_guide">가이드 접기</button>
|
|
@@ -99,9 +114,15 @@
|
|
|
99
114
|
<section id="updateNotice" class="update-notice hidden" aria-live="polite">
|
|
100
115
|
<span class="update-notice-signal" aria-hidden="true"><i></i></span>
|
|
101
116
|
<div><b id="updateNoticeTitle" data-i18n="ui.a_new_version_is_available">새 버전을 사용할 수 있습니다.</b><small id="updateNoticeText" data-i18n="ui.download_the_update_from_settings">설정에서 업데이트 파일을 받을 수 있습니다.</small></div>
|
|
102
|
-
<button id="updateNoticeBtn" type="button">업데이트
|
|
117
|
+
<button id="updateNoticeBtn" type="button" aria-controls="updatePanel"><span data-i18n="settings.update.view">업데이트 보기</span> <span>→</span></button>
|
|
103
118
|
</section>
|
|
104
119
|
|
|
120
|
+
<section id="automationOverview" class="automation-overview hidden" aria-label="예약 작업과 AI 실행 단계" data-i18n-aria-label="runtime.section_label"></section>
|
|
121
|
+
|
|
122
|
+
<section id="operationsOverview" class="operations-overview hidden" aria-label="에이전트 운영 상태" data-i18n-aria-label="management.operations_label"></section>
|
|
123
|
+
|
|
124
|
+
<section id="attentionInbox" class="attention-inbox hidden" aria-label="확인 또는 주의가 필요한 AI 작업" data-i18n-aria-label="management.inbox_label"></section>
|
|
125
|
+
|
|
105
126
|
<section id="settingsSection" class="settings-section hidden" aria-labelledby="settingsTitle">
|
|
106
127
|
<header class="settings-head">
|
|
107
128
|
<div class="settings-emblem" aria-hidden="true"><span>↟</span><i></i></div>
|
|
@@ -125,6 +146,15 @@
|
|
|
125
146
|
</label>
|
|
126
147
|
</section>
|
|
127
148
|
|
|
149
|
+
<section class="provider-visibility-card" aria-labelledby="providerVisibilityTitle">
|
|
150
|
+
<div class="provider-visibility-copy">
|
|
151
|
+
<span data-i18n="settings.providers.eyebrow">AI 표시 맞춤 설정</span>
|
|
152
|
+
<h3 id="providerVisibilityTitle" data-i18n="settings.providers.title">화면에 표시할 AI</h3>
|
|
153
|
+
<p data-i18n="settings.providers.description">끄면 해당 AI의 현황, 필터, 세션, 작업 실행 항목이 앱 전체에서 숨겨집니다. 언제든 다시 켤 수 있습니다.</p>
|
|
154
|
+
</div>
|
|
155
|
+
<div id="providerVisibilityList" class="provider-visibility-list"></div>
|
|
156
|
+
</section>
|
|
157
|
+
|
|
128
158
|
<div id="updatePanel" class="update-panel" data-update-status="idle">
|
|
129
159
|
<div class="version-route" aria-label="설치 버전과 최신 버전 비교" data-i18n-aria-label="ui.compare_installed_and_latest_versions">
|
|
130
160
|
<article class="version-node local-version-node">
|
|
@@ -166,19 +196,19 @@
|
|
|
166
196
|
</div>
|
|
167
197
|
</section>
|
|
168
198
|
|
|
169
|
-
<section id="terminalSection" class="terminal-section hidden" aria-label="명령창 직접 다루기">
|
|
199
|
+
<section id="terminalSection" class="terminal-section hidden" aria-label="명령창 직접 다루기" data-i18n-aria-label="terminal.direct_control">
|
|
170
200
|
<div class="terminal-section-head">
|
|
171
|
-
<div><span class="terminal-logo">›_</span><div><p class="eyebrow" data-i18n="ui.conversation_and_execution_together">대화와 실행 화면을 한곳에서</p><h2 data-i18n="app.nav.session_terminal"
|
|
201
|
+
<div><span class="terminal-logo">›_</span><div><p class="eyebrow" data-i18n="ui.conversation_and_execution_together">대화와 실행 화면을 한곳에서</p><h2 data-i18n="app.nav.session_terminal">AI 세션 터미널</h2><p id="terminalPlatformExplain" class="section-explain" data-i18n="ui.choose_a_session_on_the_left_to_continue_with_its">왼쪽에서 세션을 고르면 이전 AI 대화와 실시간 터미널을 나란히 보며 그대로 이어서 작업할 수 있습니다.</p></div></div>
|
|
172
202
|
<div class="terminal-create-actions">
|
|
173
203
|
<button id="newPowerShellBtn" class="accent" type="button" data-i18n="ui.windows_session">+ Windows 세션</button>
|
|
174
204
|
<button id="newWslBtn" type="button" data-i18n="ui.linux_session">+ Linux 세션</button>
|
|
175
205
|
</div>
|
|
176
206
|
</div>
|
|
177
207
|
<div class="terminal-layout">
|
|
178
|
-
<aside class="terminal-resource-panel">
|
|
208
|
+
<aside id="terminalResourcePanel" class="terminal-resource-panel">
|
|
179
209
|
<div class="terminal-resource-head"><div><b data-i18n="ui.my_terminal_sessions">내 터미널 세션</b><span id="terminalSessionSummary" data-i18n="common.running" data-i18n-params='{"count":0}'>0개 실행 중</span></div><span class="terminal-resource-live"><i></i>LIVE</span></div>
|
|
180
210
|
<p id="terminalReorderHelp" class="sr-only" data-i18n="terminal.reorder_help">세션 옆의 위아래 버튼을 누르거나, 세션에 초점을 둔 뒤 Alt와 위아래 화살표 키를 눌러 순서를 바꿀 수 있습니다.</p>
|
|
181
|
-
<div id="terminalSessionList" class="terminal-session-list"></div>
|
|
211
|
+
<div id="terminalSessionList" class="terminal-session-list" role="listbox" aria-label="터미널 세션" data-i18n-aria-label="quality.terminal_sessions"></div>
|
|
182
212
|
<div class="terminal-resource-tip"><span>⌘</span><p><b data-i18n="ui.sessions_stay_open_when_you_change_views">세션은 화면을 옮겨도 유지됩니다.</b><small data-i18n="ui.output_and_draft_commands_remain_when_you_return_from_another">다른 작업을 보고 돌아와도 출력과 작성 중인 명령이 그대로 남아 있어요.</small></p></div>
|
|
183
213
|
</aside>
|
|
184
214
|
|
|
@@ -187,24 +217,28 @@
|
|
|
187
217
|
<div class="terminal-target-cluster"><span id="terminalTargetIcon" class="terminal-target-icon">›_</span><div id="terminalTargetMeta" class="terminal-target-meta"><b data-i18n="ui.select_a_session">세션을 선택해 주세요</b><span data-i18n="ui.choose_a_session_on_the_left_or_create_a_new">왼쪽 목록에서 이어갈 세션을 고르거나 새 세션을 만드세요.</span></div></div>
|
|
188
218
|
<div class="terminal-workspace-actions">
|
|
189
219
|
<div id="terminalConnectionState" class="terminal-connection-state"><i></i><span data-i18n="ui.waiting_for_selection">선택 대기</span></div>
|
|
220
|
+
<details class="terminal-session-tools">
|
|
221
|
+
<summary><span data-i18n="terminal.session_controls">세션 관리</span><i aria-hidden="true">⌄</i></summary>
|
|
190
222
|
<div class="terminal-key-actions">
|
|
191
|
-
<button type="button" data-terminal-signal="interrupt" title="현재 실행 중인 명령 중단" data-i18n-title="ui.interrupt_the_running_command"><span data-i18n="ui.interrupt">실행 중단</span><kbd>Ctrl C</kbd></button>
|
|
192
|
-
<button type="button" data-terminal-signal="clear" title="터미널 화면 정리" data-i18n-title="ui.clear_terminal_screen"><span data-i18n="ui.clear">화면 정리</span><kbd>Ctrl L</kbd></button>
|
|
223
|
+
<button type="button" data-terminal-signal="interrupt" title="현재 실행 중인 명령 중단" data-i18n-title="ui.interrupt_the_running_command" aria-keyshortcuts="Control+C"><span data-i18n="ui.interrupt">실행 중단</span><kbd>Ctrl C</kbd></button>
|
|
224
|
+
<button type="button" data-terminal-signal="clear" title="터미널 화면 정리" data-i18n-title="ui.clear_terminal_screen" aria-keyshortcuts="Control+L"><span data-i18n="ui.clear">화면 정리</span><kbd>Ctrl L</kbd></button>
|
|
193
225
|
<button id="terminalRestartBtn" type="button" data-i18n="ui.restart">다시 시작</button>
|
|
194
226
|
<button id="terminalAttachBtn" class="hidden" type="button" data-i18n="ui.control_directly">직접 조작하기</button>
|
|
195
227
|
<button id="terminalCloseBtn" class="terminal-danger-button" type="button" data-i18n="ui.end_session">세션 종료</button>
|
|
228
|
+
<button id="terminalEndSessionBtn" class="terminal-danger-button hidden" type="button" data-i18n="terminal.end_ai_session">AI 세션 종료</button>
|
|
196
229
|
</div>
|
|
230
|
+
</details>
|
|
197
231
|
</div>
|
|
198
232
|
</div>
|
|
199
233
|
<div id="terminalTmuxTools" class="terminal-tmux-tools hidden">
|
|
200
|
-
<button type="button" data-tmux-manage="rename-session" data-i18n="ui.rename_workspace"
|
|
234
|
+
<button type="button" data-tmux-manage="rename-session" data-i18n="ui.rename_workspace">tmux 세션 이름 바꾸기</button>
|
|
201
235
|
<button type="button" data-tmux-manage="new-window" data-i18n="ui.add_window">창 추가</button>
|
|
202
236
|
<button type="button" data-tmux-manage="split-horizontal" data-i18n="ui.split_left_right">좌우로 나누기</button>
|
|
203
237
|
<button type="button" data-tmux-manage="split-vertical" data-i18n="ui.split_top_bottom">상하로 나누기</button>
|
|
204
|
-
<label>창
|
|
238
|
+
<label><span data-i18n="terminal.window_layout">창 배치</span> <select id="terminalTmuxLayout"><option value="tiled" data-i18n="ui.tiled">바둑판</option><option value="even-horizontal" data-i18n="ui.equal_width">같은 너비</option><option value="even-vertical" data-i18n="ui.equal_height">같은 높이</option><option value="main-horizontal" data-i18n="ui.main_window_on_top">중요 창 위쪽</option><option value="main-vertical" data-i18n="ui.main_window_on_left">중요 창 왼쪽</option></select></label>
|
|
205
239
|
<button type="button" class="danger" data-tmux-manage="kill-pane" data-i18n="ui.close_selected_pane">선택한 칸 닫기</button>
|
|
206
240
|
<button type="button" class="danger" data-tmux-manage="kill-window" data-i18n="ui.close_entire_window">창 전체 닫기</button>
|
|
207
|
-
<button type="button" class="danger" data-tmux-manage="kill-session" data-i18n="ui.end_workspace"
|
|
241
|
+
<button type="button" class="danger" data-tmux-manage="kill-session" data-i18n="ui.end_workspace">tmux 세션 종료</button>
|
|
208
242
|
</div>
|
|
209
243
|
<div id="terminalStage" class="terminal-stage">
|
|
210
244
|
<aside id="terminalHistoryPanel" class="terminal-history-panel hidden" aria-label="선택한 AI의 이전 대화" data-i18n-aria-label="ui.previous_conversation_for_selected_ai">
|
|
@@ -216,23 +250,34 @@
|
|
|
216
250
|
<footer><span class="session-lock-dot"></span><b data-i18n="ui.this_conversation_is_connected_to_the_terminal_on_the_right">이 대화가 오른쪽 터미널과 연결되어 있습니다</b></footer>
|
|
217
251
|
</aside>
|
|
218
252
|
<section class="terminal-console-pane" aria-label="실시간 터미널과 명령 입력" data-i18n-aria-label="ui.live_terminal_and_command_input">
|
|
219
|
-
<header class="terminal-console-head"
|
|
253
|
+
<header class="terminal-console-head">
|
|
254
|
+
<div class="terminal-console-title"><span class="terminal-console-pulse"></span><div><b data-i18n="ui.live_terminal">실시간 터미널</b><small id="terminalConsoleCaption" data-i18n="ui.select_a_session_to_show_its_output_here">세션을 선택하면 출력이 여기에 표시됩니다</small></div></div>
|
|
255
|
+
<div class="terminal-console-tools">
|
|
256
|
+
<span id="terminalConsoleState" class="terminal-console-state" data-i18n="ui.waiting_for_selection">선택 대기</span>
|
|
257
|
+
<div class="terminal-font-controls" role="group" aria-label="터미널 글자 크기" data-i18n-aria-label="terminal.view.font_size">
|
|
258
|
+
<button id="terminalFontDecreaseBtn" type="button" aria-label="터미널 글자 작게" data-i18n-aria-label="terminal.view.font_decrease" title="터미널 글자 작게" data-i18n-title="terminal.view.font_decrease">−</button>
|
|
259
|
+
<output id="terminalFontSizeLabel" aria-live="polite">15px</output>
|
|
260
|
+
<button id="terminalFontIncreaseBtn" type="button" aria-label="터미널 글자 크게" data-i18n-aria-label="terminal.view.font_increase" title="터미널 글자 크게" data-i18n-title="terminal.view.font_increase">+</button>
|
|
261
|
+
</div>
|
|
262
|
+
<button id="terminalFocusBtn" class="terminal-focus-button" type="button" aria-pressed="false" title="터미널만 크게 보기" data-i18n-title="terminal.view.focus"><span data-i18n="terminal.view.focus">집중 보기</span><b aria-hidden="true">⛶</b></button>
|
|
263
|
+
</div>
|
|
264
|
+
</header>
|
|
220
265
|
<div id="terminalViewport" class="terminal-viewport"><div id="terminalEmpty" class="terminal-empty"><span>›_</span><h3 data-i18n="ui.choose_a_session_to_continue">이어갈 세션을 선택하세요</h3><p data-i18n="ui.choose_a_session_on_the_left_or_create_one_to">왼쪽 세션을 고르거나 새 세션을 만들면 실시간 출력과 명령 입력창이 열립니다.</p></div></div>
|
|
221
266
|
<form id="terminalCommandForm" class="terminal-command-form">
|
|
222
267
|
<div class="terminal-command-label"><label id="terminalCommandLabel" for="terminalCommandInput" data-i18n="ui.send_command_to_terminal">터미널에 명령 보내기</label><span data-i18n="ui.enter_to_send_shift_enter_for_newline">Enter 전송 · Shift+Enter 줄바꿈</span></div>
|
|
223
|
-
<div class="terminal-command-composer"><textarea id="terminalCommandInput" rows="2" placeholder="먼저 왼쪽에서 세션을 선택하세요" data-i18n-placeholder="ui.select_a_session_on_the_left_first" spellcheck="false"></textarea><button type="submit"><span data-i18n="common.send">보내기</span><b>↵</b></button></div>
|
|
268
|
+
<div class="terminal-command-composer"><textarea id="terminalCommandInput" rows="2" maxlength="8000" aria-describedby="terminalCommandCount" placeholder="먼저 왼쪽에서 세션을 선택하세요" data-i18n-placeholder="ui.select_a_session_on_the_left_first" spellcheck="false"></textarea><button id="terminalCommandClearBtn" class="terminal-command-clear hidden" type="button" aria-label="작성 중인 명령 지우기" data-i18n-aria-label="quality.terminal_clear_draft">×</button><button type="submit"><span data-i18n="common.send">보내기</span><b>↵</b></button><small id="terminalCommandCount" class="terminal-command-count">0 / 8,000</small></div>
|
|
224
269
|
</form>
|
|
225
|
-
<div id="terminalNotice" class="terminal-notice" role="status" aria-live="polite" aria-atomic="true"><span class="terminal-notice-dot"></span><span data-i18n="ui.select_a_session_to_start_typing">세션을 선택하면 바로 입력할 수 있습니다.</span></div>
|
|
270
|
+
<div id="terminalNotice" class="terminal-notice" role="status" aria-live="polite" aria-atomic="true" tabindex="-1"><span class="terminal-notice-dot"></span><span data-i18n="ui.select_a_session_to_start_typing">세션을 선택하면 바로 입력할 수 있습니다.</span></div>
|
|
226
271
|
</section>
|
|
227
272
|
</div>
|
|
228
273
|
</div></div>
|
|
229
274
|
</div>
|
|
230
275
|
</section>
|
|
231
276
|
|
|
232
|
-
<section id="tmuxSection" class="tmux-section hidden" aria-label="
|
|
277
|
+
<section id="tmuxSection" class="tmux-section hidden" aria-label="tmux 터미널 관리 보기" data-i18n-aria-label="ui.view_multi_terminal_work">
|
|
233
278
|
<div class="tmux-section-head">
|
|
234
|
-
<div><span class="tmux-logo">tmux</span><div><p class="eyebrow" data-i18n="ui.tmux_workspace">tmux 전용 공간</p><h2 data-i18n="ui.work_grouped_with_tmux">tmux
|
|
235
|
-
<div class="tmux-section-actions"><button id="refreshTmuxTerminalBtn" type="button" data-i18n="ui.refresh">↻ 새로고침</button><button id="newTmuxSessionBtn" class="accent" type="button" data-i18n="ui.create_tmux_workspace">+ tmux
|
|
279
|
+
<div><span class="tmux-logo">tmux</span><div><p class="eyebrow" data-i18n="ui.tmux_workspace">tmux 전용 공간</p><h2 data-i18n="ui.work_grouped_with_tmux">tmux 세션과 분할 터미널</h2><p class="section-explain" data-i18n="ui.only_work_using_tmux_appears_here_regular_terminals_are_kept">tmux를 사용하는 작업만 모아 봅니다. 일반 명령창은 이 화면에 섞이지 않습니다.</p></div></div>
|
|
280
|
+
<div class="tmux-section-actions"><button id="refreshTmuxTerminalBtn" type="button" data-i18n="ui.refresh">↻ 새로고침</button><button id="newTmuxSessionBtn" class="accent" type="button" data-i18n="ui.create_tmux_workspace">+ tmux 세션 만들기</button></div>
|
|
236
281
|
</div>
|
|
237
282
|
<div id="tmuxStats" class="tmux-stats"></div>
|
|
238
283
|
<div class="tmux-map-toolbar">
|
|
@@ -245,7 +290,7 @@
|
|
|
245
290
|
<div class="terminal-layout tmux-control-layout">
|
|
246
291
|
<aside class="terminal-resource-panel tmux-resource-panel">
|
|
247
292
|
<div class="terminal-resource-head tmux-resources"><div><b data-i18n="ui.tmux_terminals_only">tmux 안의 명령창만</b><span data-i18n="ui.regular_terminals_are_hidden">일반 명령창은 표시하지 않음</span></div></div>
|
|
248
|
-
<div id="terminalTmuxList" class="terminal-tmux-list"></div>
|
|
293
|
+
<div id="terminalTmuxList" class="terminal-tmux-list" role="listbox" aria-label="tmux 칸" data-i18n-aria-label="quality.tmux_panes"></div>
|
|
249
294
|
</aside>
|
|
250
295
|
<div id="tmuxWorkbenchMount" class="terminal-workbench-mount"></div>
|
|
251
296
|
</div>
|
|
@@ -254,14 +299,27 @@
|
|
|
254
299
|
|
|
255
300
|
<section id="liveSection" class="live-section hidden" aria-label="현재 진행 중인 AI 작업" data-i18n-aria-label="ui.ai_work_currently_in_progress">
|
|
256
301
|
<div class="live-section-head">
|
|
257
|
-
<div><span class="live-beacon"></span><div><p class="eyebrow" data-i18n="ui.active_now">지금 진행 중</p><h2 data-i18n="ui.work_assigned_to_ai">AI들이 맡은 일</h2></div></div>
|
|
258
|
-
<
|
|
302
|
+
<div class="live-section-title"><span class="live-beacon"></span><div><p class="eyebrow" data-i18n="ui.active_now">지금 진행 중</p><h2 data-i18n="ui.work_assigned_to_ai">AI들이 맡은 일</h2></div></div>
|
|
303
|
+
<div class="live-section-tools">
|
|
304
|
+
<p class="live-section-description" data-i18n="ui.open_a_task_to_see_who_started_it_and_what">일을 누르면 누가 시작했고, 다른 AI에게 어떤 도움을 맡겼는지 쉽게 볼 수 있습니다.</p>
|
|
305
|
+
<button id="openTmuxFromAgentWork" class="live-tmux-shortcut" type="button" aria-label="tmux 터미널 관리 · 세션 0개" data-i18n-aria-label="graph.open_tmux_workspace_count" data-i18n-params='{"count":0}' title="tmux 터미널 관리" data-i18n-title="graph.open_tmux_workspace">
|
|
306
|
+
<span class="live-tmux-shortcut-icon" aria-hidden="true">▦</span>
|
|
307
|
+
<span data-i18n="graph.open_tmux_workspace">tmux 터미널 관리</span>
|
|
308
|
+
<b id="agentWorkTmuxCount">0</b>
|
|
309
|
+
</button>
|
|
310
|
+
</div>
|
|
259
311
|
</div>
|
|
260
312
|
<div class="agent-map-toolbar">
|
|
261
313
|
<div id="graphBreadcrumbs" class="graph-breadcrumbs" aria-label="에이전트 탐색 경로" data-i18n-aria-label="ui.agent_navigation_path"></div>
|
|
262
314
|
<button id="graphResetBtn" class="graph-reset hidden" type="button" data-i18n="ui.back_to_task_list">작업 목록으로</button>
|
|
263
315
|
</div>
|
|
264
316
|
<div id="liveSessionGrid" class="live-session-grid"></div>
|
|
317
|
+
<div id="activeEmptyState" class="empty-state hidden">
|
|
318
|
+
<div class="empty-orbit"><span></span></div>
|
|
319
|
+
<h3 data-i18n="ui.no_tasks_are_currently_active">현재 진행 중인 작업이 없습니다</h3>
|
|
320
|
+
<p data-i18n="ui.new_tasks_will_show_their_progress_here_immediately">새 작업을 시작하면 진행 상황이 여기에 바로 표시됩니다.</p>
|
|
321
|
+
<button class="primary-button" type="button" data-open-run data-i18n="ui.assign_a_new_task_to_ai">AI에게 새 일 맡기기</button>
|
|
322
|
+
</div>
|
|
265
323
|
</section>
|
|
266
324
|
|
|
267
325
|
<section id="globalStats" class="global-stats" aria-label="전체 통계" data-i18n-aria-label="ui.overall_statistics"></section>
|
|
@@ -270,48 +328,57 @@
|
|
|
270
328
|
<div class="sessions-heading">
|
|
271
329
|
<div><p class="eyebrow" data-i18n="ui.history">지난 기록</p><h2 id="viewTitle" data-i18n="ui.recent_conversations_and_tasks">최근 대화와 작업</h2></div>
|
|
272
330
|
<div class="session-tools">
|
|
273
|
-
<label class="search-box"><span aria-hidden="true">⌕</span><input id="searchInput" type="search" aria-label="작업 검색" data-i18n-aria-label="ui.search_tasks" placeholder="작업 이름, AI, 폴더 찾기" data-i18n-placeholder="ui.find_task_ai_or_folder" autocomplete="off"
|
|
274
|
-
<div id="providerFilter" class="provider-filter" role="
|
|
331
|
+
<label class="search-box"><span aria-hidden="true">⌕</span><input id="searchInput" type="search" maxlength="240" aria-label="작업 검색" data-i18n-aria-label="ui.search_tasks" aria-keyshortcuts="/" placeholder="작업 이름, AI, 폴더 찾기" data-i18n-placeholder="ui.find_task_ai_or_folder" autocomplete="off" /><button id="searchClearBtn" class="search-clear hidden" type="button" aria-label="검색어 지우기" data-i18n-aria-label="filter.clear_search" title="검색어 지우기" data-i18n-title="filter.clear_search">×</button></label>
|
|
332
|
+
<div id="providerFilter" class="provider-filter" role="toolbar" aria-label="AI 제공사 필터" data-i18n-aria-label="ui.ai_provider_filter"></div>
|
|
275
333
|
<p id="providerFilterStatus" class="sr-only" role="status" aria-live="polite"></p>
|
|
276
334
|
<select id="sortSelect" aria-label="정렬" data-i18n-aria-label="ui.sort"><option value="recent" data-i18n="ui.most_recently_active">최근에 움직인 순서</option><option value="tokens" data-i18n="ui.highest_usage">많이 사용한 순서</option><option value="context" data-i18n="ui.highest_context_usage">기억 공간을 많이 쓴 순서</option></select>
|
|
335
|
+
<button id="resetFiltersBtn" class="filter-reset hidden" type="button" data-i18n="filter.reset_all">필터 초기화</button>
|
|
277
336
|
</div>
|
|
278
337
|
</div>
|
|
338
|
+
<p id="sessionResultSummary" class="session-result-summary" aria-live="polite"></p>
|
|
279
339
|
<div id="sessionGrid" class="session-grid"></div>
|
|
280
340
|
<button id="loadMoreBtn" class="load-more hidden" type="button" data-i18n="ui.show_more_tasks">작업 더 보기</button>
|
|
281
341
|
<div id="emptyState" class="empty-state hidden">
|
|
282
342
|
<div class="empty-orbit"><span></span></div>
|
|
283
343
|
<h3 data-i18n="ui.no_tasks_to_show_yet">아직 보여줄 작업이 없습니다</h3>
|
|
284
344
|
<p data-i18n="ui.change_the_search_filters_or_assign_a_new_task_to">검색 조건을 바꾸거나 AI에게 새 일을 맡겨보세요.</p>
|
|
285
|
-
<button class="
|
|
345
|
+
<button id="emptyClearFiltersBtn" class="ghost-button hidden" type="button" data-i18n="quality.clear_conditions">조건 지우기</button>
|
|
346
|
+
<button class="primary-button" type="button" data-open-run data-i18n="ui.assign_a_new_task_to_ai">AI에게 새 일 맡기기</button>
|
|
286
347
|
</div>
|
|
287
348
|
</section>
|
|
288
349
|
</main>
|
|
289
350
|
</div>
|
|
290
351
|
|
|
291
|
-
<
|
|
292
|
-
<div><b data-i18n="app.nav.more">더보기</b><
|
|
293
|
-
<
|
|
294
|
-
|
|
352
|
+
<aside id="mobileToolsMenu" class="mobile-tools-menu hidden" role="dialog" aria-modal="true" aria-labelledby="mobileToolsTitle" aria-hidden="true" tabindex="-1" inert>
|
|
353
|
+
<div class="mobile-tools-head"><span><b id="mobileToolsTitle" data-i18n="app.nav.more">더보기</b><small data-i18n="ui.advanced_tools_to_open_only_when_needed">필요할 때만 여는 고급 기능이에요.</small></span><button id="mobileToolsCloseBtn" type="button" aria-label="닫기" data-i18n-aria-label="common.close">×</button></div>
|
|
354
|
+
<details class="mobile-project-picker">
|
|
355
|
+
<summary><i aria-hidden="true">□</i><span><b data-i18n="ui.workspaces">프로젝트 폴더 필터</b><small id="mobileWorkspaceSummary" data-i18n="project.all">모든 프로젝트 폴더</small></span><em aria-hidden="true">⌄</em></summary>
|
|
356
|
+
<div class="mobile-project-picker-body"><div id="mobileWorkspaceList" class="workspace-list" role="group" aria-label="작업 시작 폴더별 AI 세션 필터" data-i18n-aria-label="quality.workspace_filter"></div><button id="mobileAddWorkspaceBtn" type="button" data-i18n="ui.add_workspace">폴더 필터 추가</button></div>
|
|
357
|
+
</details>
|
|
358
|
+
<button type="button" data-mobile-view="runtime"><i aria-hidden="true">↻</i><span><b data-i18n="runtime.title">예약·실행 단계</b><small data-i18n="runtime.description">실제 예약 작업과 현재 AI의 추정 실행 단계를 나눠서 확인합니다.</small></span></button>
|
|
359
|
+
<button type="button" data-mobile-view="terminal"><i aria-hidden="true">›_</i><span><b data-i18n="app.nav.session_terminal">AI 세션 터미널</b><small data-i18n="ui.continue_an_existing_ai_conversation_directly">기존 AI 대화를 직접 이어서 입력</small></span></button>
|
|
360
|
+
<button type="button" data-mobile-view="tmux"><i aria-hidden="true">▦</i><span><b data-i18n="app.nav.tmux">tmux 터미널 관리</b><small data-i18n="ui.manage_multiple_terminals_together">tmux 세션·창·분할 칸 관리</small></span></button>
|
|
295
361
|
<button type="button" data-mobile-view="settings"><i aria-hidden="true">⚙</i><span><b data-i18n="settings.title">프로그램 설정</b><small data-i18n="ui.check_version_and_updates">버전과 업데이트 확인</small></span></button>
|
|
296
|
-
</
|
|
362
|
+
</aside>
|
|
297
363
|
|
|
298
364
|
<div id="drawerBackdrop" class="drawer-backdrop hidden"></div>
|
|
299
365
|
<aside id="detailDrawer" class="detail-drawer" role="dialog" aria-modal="true" aria-labelledby="drawerTitle" aria-hidden="true" tabindex="-1" inert>
|
|
300
366
|
<div class="drawer-head">
|
|
301
367
|
<div id="drawerProviderMark" class="provider-mark">AI</div>
|
|
302
368
|
<div class="drawer-title"><span id="drawerProvider" data-i18n="ui.ai_task">AI 작업</span><h2 id="drawerTitle" data-i18n="drawer.title">작업 자세히 보기</h2></div>
|
|
303
|
-
<button id="closeDrawerBtn" class="close-button" aria-label="닫기" data-i18n-aria-label="common.close">×</button>
|
|
369
|
+
<button id="closeDrawerBtn" class="close-button" type="button" aria-label="닫기" data-i18n-aria-label="common.close">×</button>
|
|
304
370
|
</div>
|
|
305
371
|
<div id="drawerMeta" class="drawer-meta"></div>
|
|
306
|
-
<div class="drawer-tabs" role="tablist">
|
|
307
|
-
<button id="
|
|
308
|
-
<button id="
|
|
309
|
-
<button id="
|
|
372
|
+
<div class="drawer-tabs" role="tablist" aria-orientation="horizontal">
|
|
373
|
+
<button id="drawerTabSummary" class="drawer-tab" type="button" role="tab" aria-selected="false" aria-controls="drawerContent" tabindex="-1" data-tab="summary" data-i18n="management.summary">관리 요약</button>
|
|
374
|
+
<button id="drawerTabChat" class="drawer-tab active" type="button" role="tab" aria-selected="true" aria-controls="drawerContent" tabindex="0" data-tab="chat" data-i18n="ui.conversation">대화 내용</button>
|
|
375
|
+
<button id="drawerTabLifecycle" class="drawer-tab" type="button" role="tab" aria-selected="false" aria-controls="drawerContent" tabindex="-1" data-tab="lifecycle" data-i18n="ui.progress">진행 과정</button>
|
|
376
|
+
<button id="drawerTabTokens" class="drawer-tab" type="button" role="tab" aria-selected="false" aria-controls="drawerContent" tabindex="-1" data-tab="tokens" data-i18n="ui.usage">사용량</button>
|
|
310
377
|
</div>
|
|
311
378
|
<div id="drawerContent" class="drawer-content" role="tabpanel" aria-labelledby="drawerTabChat" tabindex="0"></div>
|
|
312
379
|
</aside>
|
|
313
380
|
|
|
314
|
-
<div id="runModal" class="modal-backdrop hidden" role="dialog" aria-modal="true" aria-labelledby="runModalTitle" aria-describedby="runModalDescription">
|
|
381
|
+
<div id="runModal" class="modal-backdrop hidden" role="dialog" aria-modal="true" aria-labelledby="runModalTitle" aria-describedby="runModalDescription" aria-hidden="true" inert>
|
|
315
382
|
<form id="runForm" class="run-modal run-composer">
|
|
316
383
|
<div class="modal-head">
|
|
317
384
|
<div><p class="eyebrow" data-i18n="ui.start_ai_task">AI 작업 시작</p><h2 id="runModalTitle" data-i18n="ui.what_should_the_ai_work_on">무슨 일을 맡길까요?</h2><p id="runModalDescription" class="run-modal-intro" data-i18n="ui.describe_the_task_then_choose_which_ai_will_work_in">할 일을 먼저 적고, 어떤 AI가 어디서 작업할지 선택하세요.</p></div>
|
|
@@ -319,40 +386,56 @@
|
|
|
319
386
|
</div>
|
|
320
387
|
<section class="run-step run-request-step" aria-labelledby="runRequestLabel">
|
|
321
388
|
<div class="run-step-head"><i>1</i><span><b id="runRequestLabel" data-i18n="ui.describe_the_task">할 일 적기</b><small data-i18n="ui.include_the_expected_result_and_constraints_for_better_accuracy">결과와 제약을 함께 적으면 더 정확해요.</small></span></div>
|
|
322
|
-
<label class="run-prompt-field"><span class="sr-only" data-i18n="ui.task_for_ai">AI에게 맡길 일</span><textarea id="runPrompt" required rows="5" maxlength="8000" placeholder="예: 로그인 화면의 오류를 찾아 고치고, 관련 테스트까지 실행해줘" data-i18n-placeholder="ui.example_find_and_fix_the_login_screen_error_then_run"></textarea></label>
|
|
323
|
-
<div class="run-prompt-tools"><div class="run-prompt-examples" aria-label="빠른 요청 예시" data-i18n-aria-label="ui.quick_prompt_examples"><button type="button" data-run-prompt-
|
|
389
|
+
<label class="run-prompt-field"><span class="sr-only" data-i18n="ui.task_for_ai">AI에게 맡길 일</span><textarea id="runPrompt" required rows="5" maxlength="8000" aria-describedby="runPromptCount" placeholder="예: 로그인 화면의 오류를 찾아 고치고, 관련 테스트까지 실행해줘" data-i18n-placeholder="ui.example_find_and_fix_the_login_screen_error_then_run"></textarea></label>
|
|
390
|
+
<div class="run-prompt-tools"><div class="run-prompt-examples" aria-label="빠른 요청 예시" data-i18n-aria-label="ui.quick_prompt_examples"><button type="button" data-run-prompt-key="run.example.fix" data-i18n="ui.fix_a_bug">오류 수정</button><button type="button" data-run-prompt-key="run.example.review" data-i18n="ui.review_code">코드 검토</button><button type="button" data-run-prompt-key="run.example.tests" data-i18n="ui.add_tests">테스트 추가</button></div><span id="runPromptCount" class="run-prompt-count">0 / 8,000</span></div>
|
|
324
391
|
</section>
|
|
325
392
|
<section class="run-step run-setup-step" aria-labelledby="runSetupLabel">
|
|
326
393
|
<div class="run-step-head"><i>2</i><span><b id="runSetupLabel" data-i18n="ui.choose_how_to_run">실행 방법 선택</b><small data-i18n="ui.choose_an_ai_and_workspace_to_finish_setup">AI와 작업 폴더만 고르면 준비가 끝납니다.</small></span></div>
|
|
327
394
|
<div id="runProviderLabel" class="field-label" data-i18n="ui.which_ai_should_handle_it">어떤 AI에게 맡길까요?</div>
|
|
328
|
-
<div id="runProviderPicker" class="run-provider-picker" role="
|
|
395
|
+
<div id="runProviderPicker" class="run-provider-picker" role="radiogroup" aria-labelledby="runProviderLabel"></div>
|
|
329
396
|
<div id="runProviderHelp" class="run-provider-help hidden" role="status"></div>
|
|
330
|
-
<div class="run-folder-field"><label class="field-label" for="runCwd" data-i18n="ui.
|
|
397
|
+
<div class="run-folder-field"><label class="field-label" for="runCwd" data-i18n="ui.work_folder">작업 폴더</label><div class="path-field"><input id="runCwd" required placeholder="프로젝트 폴더를 선택하세요" data-i18n-placeholder="ui.choose_a_project_folder" /><button type="button" id="pickRunCwdBtn" data-i18n="ui.browse">폴더 찾기</button></div></div>
|
|
331
398
|
<div id="runWorkspaceSuggestions" class="run-workspace-suggestions" aria-label="최근 작업 폴더" data-i18n-aria-label="ui.recent_workspaces"></div>
|
|
332
399
|
<label class="permission-toggle"><input id="allowWrites" type="checkbox" /><span class="toggle-track"></span><div><strong data-i18n="ui.allow_ai_to_edit_files">AI가 파일을 고칠 수 있게 허용</strong><small data-i18n="ui.when_enabled_the_ai_can_directly_edit_files_in_the">켜면 선택한 폴더의 파일을 직접 수정합니다.</small></div></label>
|
|
333
400
|
<div id="runPermissionHint" class="run-permission-hint hidden" role="status" data-i18n="ui.this_request_appears_to_need_file_changes_without_edit_permission">이 요청은 파일 수정이 필요해 보여요. 위의 수정 허용을 켜지 않으면 AI가 코드 변경 없이 검토만 합니다.</div>
|
|
334
401
|
</section>
|
|
335
|
-
<details class="run-advanced">
|
|
402
|
+
<details class="run-advanced" data-disclosure-key="run:advanced">
|
|
336
403
|
<summary><span><b data-i18n="ui.advanced_settings">고급 설정</b><small data-i18n="ui.use_only_when_selecting_a_specific_model">특정 모델을 직접 지정할 때만 사용</small></span><i aria-hidden="true">↓</i></summary>
|
|
337
|
-
<label><span>사용
|
|
404
|
+
<label><span><span data-i18n="ui.model">사용 모델</span> <small data-i18n="ui.leave_blank_if_unsure">몰라도 비워두세요</small></span><input id="runModel" autocomplete="off" spellcheck="false" placeholder="비워두면 AI가 알아서 선택합니다" data-i18n-placeholder="ui.leave_blank_to_let_the_ai_choose" /></label>
|
|
338
405
|
</details>
|
|
339
|
-
<div id="runError" class="form-error hidden" role="alert" aria-live="assertive"></div>
|
|
340
|
-
<div class="modal-actions run-modal-actions"><span class="run-shortcut-hint"><kbd>⌘</kbd><kbd>Enter</kbd>
|
|
406
|
+
<div id="runError" class="form-error hidden" role="alert" aria-live="assertive" tabindex="-1"></div>
|
|
407
|
+
<div class="modal-actions run-modal-actions"><span class="run-shortcut-hint"><kbd>⌘</kbd><kbd>Enter</kbd> <span data-i18n="ui.start">시작</span></span><button type="button" id="clearRunDraftBtn" class="ghost-button" data-i18n="quality.clear_draft">초안 지우기</button><button type="button" id="cancelRunBtn" class="ghost-button" data-i18n="common.cancel">취소</button><button type="submit" class="primary-button run-submit-button" aria-keyshortcuts="Meta+Enter Control+Enter"><span class="run-submit-icon" aria-hidden="true">↗</span><span id="runSubmitLabel" data-i18n="ui.assign_to_ai">AI에게 맡기기</span></button></div>
|
|
341
408
|
</form>
|
|
342
409
|
</div>
|
|
343
410
|
|
|
411
|
+
<div id="globalStatus" class="sr-only" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
344
412
|
<div id="toast" class="toast hidden" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
345
|
-
<div id="
|
|
413
|
+
<div id="quickPaletteModal" class="modal-backdrop quality-dialog hidden" role="dialog" aria-modal="true" aria-labelledby="quickPaletteTitle" aria-describedby="quickPaletteDescription" aria-hidden="true" inert>
|
|
414
|
+
<section class="quality-modal command-palette">
|
|
415
|
+
<header class="quality-modal-head"><div><p data-i18n="quality.quick_eyebrow">빠른 이동</p><h2 id="quickPaletteTitle" data-i18n="quality.quick_title">어디로 이동할까요?</h2></div><button id="closeQuickPaletteBtn" class="close-button" type="button" aria-label="빠른 이동 닫기" data-i18n-aria-label="quality.quick_close">×</button></header>
|
|
416
|
+
<p id="quickPaletteDescription" class="sr-only" data-i18n="quality.quick_description">화면이나 작업을 검색한 뒤 방향키와 Enter로 실행하세요.</p>
|
|
417
|
+
<label class="quality-search"><span aria-hidden="true">⌕</span><input id="quickPaletteInput" type="search" autocomplete="off" maxlength="80" role="combobox" aria-label="빠른 이동 검색" data-i18n-aria-label="quality.quick_search" aria-autocomplete="list" aria-controls="quickPaletteList" aria-expanded="true" placeholder="화면 또는 작업 검색" data-i18n-placeholder="quality.quick_placeholder" /></label>
|
|
418
|
+
<div id="quickPaletteList" class="quality-command-list" role="listbox" aria-label="빠른 이동 명령" data-i18n-aria-label="quality.quick_commands"></div>
|
|
419
|
+
<p id="quickPaletteStatus" class="quality-dialog-status" role="status" aria-live="polite"></p>
|
|
420
|
+
</section>
|
|
421
|
+
</div>
|
|
422
|
+
<div id="shortcutHelpModal" class="modal-backdrop quality-dialog hidden" role="dialog" aria-modal="true" aria-labelledby="shortcutHelpTitle" aria-hidden="true" inert>
|
|
423
|
+
<section class="quality-modal shortcut-help-modal">
|
|
424
|
+
<header class="quality-modal-head"><div><p data-i18n="quality.shortcuts.eyebrow">키보드 도움말</p><h2 id="shortcutHelpTitle" data-i18n="quality.shortcuts.title">앱 단축키</h2></div><button id="closeShortcutHelpBtn" class="close-button" type="button" aria-label="단축키 도움말 닫기" data-i18n-aria-label="quality.shortcuts.close">×</button></header>
|
|
425
|
+
<dl class="shortcut-help-list"><div><dt><kbd>⌘/Ctrl</kbd><kbd>K</kbd></dt><dd data-i18n="quality.shortcuts.quick">빠른 이동 열기</dd></div><div><dt><kbd>⌘/Ctrl</kbd><kbd>1–7</kbd></dt><dd data-i18n="quality.shortcuts.views">주요 화면 이동</dd></div><div><dt><kbd>/</kbd></dt><dd data-i18n="quality.shortcuts.search">작업 검색</dd></div><div><dt><kbd>⌘/Ctrl</kbd><kbd>N</kbd></dt><dd data-i18n="quality.shortcuts.new_task">새 AI 작업</dd></div><div><dt><kbd>?</kbd></dt><dd data-i18n="quality.shortcuts.help">이 도움말 열기</dd></div><div><dt><kbd>Esc</kbd></dt><dd data-i18n="quality.shortcuts.close_action">열린 창 닫기</dd></div></dl>
|
|
426
|
+
</section>
|
|
427
|
+
</div>
|
|
428
|
+
<div id="tmuxCreateModal" class="modal-backdrop hidden" role="dialog" aria-modal="true" aria-labelledby="tmuxCreateTitle" aria-hidden="true" inert>
|
|
346
429
|
<form id="tmuxCreateForm" class="run-modal terminal-modal">
|
|
347
|
-
<div class="modal-head"><div><p class="eyebrow" data-i18n="ui.advanced_work">고급 작업</p><h2 id="tmuxCreateTitle" data-i18n="ui.create_multi_window_workspace"
|
|
430
|
+
<div class="modal-head"><div><p class="eyebrow" data-i18n="ui.advanced_work">고급 작업</p><h2 id="tmuxCreateTitle" data-i18n="ui.create_multi_window_workspace">tmux 세션 만들기</h2></div><button type="button" id="closeTmuxCreateBtn" class="close-button" aria-label="tmux 세션 만들기 창 닫기" data-i18n-aria-label="ui.close_multi_window_workspace_dialog">×</button></div>
|
|
348
431
|
<div class="form-grid">
|
|
349
432
|
<label><span id="tmuxEnvironmentLabel" data-i18n="ui.tmux_environment">tmux 환경</span><select id="tmuxCreateDistro" required></select></label>
|
|
350
|
-
<label><span data-i18n="ui.workspace_name"
|
|
433
|
+
<label><span data-i18n="ui.workspace_name">tmux 세션 이름</span><input id="tmuxCreateName" required pattern="[A-Za-z0-9_.\-]+" placeholder="my-work" aria-describedby="tmuxCreateNameHelp" /><small id="tmuxCreateNameHelp" data-i18n="tmux.name_requirements">영문, 숫자, 마침표, 밑줄, 하이픈만 사용할 수 있습니다.</small></label>
|
|
351
434
|
</div>
|
|
352
|
-
<label><span>시작
|
|
353
|
-
<label><span>처음 실행할
|
|
354
|
-
<div id="tmuxCreateError" class="form-error hidden" role="alert" aria-live="assertive"></div>
|
|
355
|
-
<div class="modal-actions"><button type="button" id="cancelTmuxCreateBtn" class="ghost-button" data-i18n="common.cancel">취소</button><button type="submit" class="primary-button" data-i18n="ui.create_workspace"
|
|
435
|
+
<label><span><span data-i18n="terminal.start_folder">시작 폴더</span> <small data-i18n="ui.optional">선택 사항</small></span><span class="path-field"><input id="tmuxCreateCwd" placeholder="프로젝트의 절대 경로" data-i18n-placeholder="ui.absolute_project_path" /><button type="button" id="pickTmuxCwdBtn" data-i18n="ui.browse">폴더 찾기</button></span></label>
|
|
436
|
+
<label><span><span data-i18n="terminal.initial_command">처음 실행할 명령</span> <small data-i18n="ui.optional">선택 사항</small></span><textarea id="tmuxCreateCommand" rows="4" placeholder="예: 실행할 AI 명령" data-i18n-placeholder="ui.example_claude_or_codex"></textarea></label>
|
|
437
|
+
<div id="tmuxCreateError" class="form-error hidden" role="alert" aria-live="assertive" tabindex="-1"></div>
|
|
438
|
+
<div class="modal-actions"><button type="button" id="cancelTmuxCreateBtn" class="ghost-button" data-i18n="common.cancel">취소</button><button type="submit" class="primary-button" data-i18n="ui.create_workspace">tmux 세션 만들기</button></div>
|
|
356
439
|
</form>
|
|
357
440
|
</div>
|
|
358
441
|
<script src="../node_modules/@xterm/xterm/lib/xterm.js"></script>
|
|
@@ -361,18 +444,22 @@
|
|
|
361
444
|
<script src="i18n.js"></script>
|
|
362
445
|
<script src="shared.js"></script>
|
|
363
446
|
<script src="app.js"></script>
|
|
447
|
+
<script src="app-provider-visibility.js"></script>
|
|
364
448
|
<script src="app-dashboard.js"></script>
|
|
449
|
+
<script src="app-runtime-overview.js"></script>
|
|
365
450
|
<script src="app-graph-model.js"></script>
|
|
366
451
|
<script src="app-graph-view.js"></script>
|
|
367
452
|
<script src="app-graph-layout.js"></script>
|
|
368
453
|
<script src="app-graph-orchestration.js"></script>
|
|
369
454
|
<script src="app-tmux-render.js"></script>
|
|
370
|
-
<script src="app-session-render.js"></script>
|
|
371
455
|
<script src="app-agent-actions.js"></script>
|
|
456
|
+
<script src="app-management.js"></script>
|
|
457
|
+
<script src="app-session-render.js"></script>
|
|
372
458
|
<script src="app-drawer-data.js"></script>
|
|
373
459
|
<script src="app-drawer-content.js"></script>
|
|
374
460
|
<script src="app-drawer.js"></script>
|
|
375
461
|
<script src="app-run-modal.js"></script>
|
|
462
|
+
<script src="app-quality.js"></script>
|
|
376
463
|
<script src="app-events-navigation.js"></script>
|
|
377
464
|
<script src="app-events-sessions.js"></script>
|
|
378
465
|
<script src="app-events-filters.js"></script>
|
package/renderer/shared.js
CHANGED
|
@@ -19,6 +19,23 @@ window.LoadToAgentRendererUtils = Object.freeze({
|
|
|
19
19
|
providerLabel(provider) {
|
|
20
20
|
return ({ claude: 'Claude', codex: 'GPT · Codex', gemini: 'Gemini', grok: 'Grok' })[provider] || 'AI';
|
|
21
21
|
},
|
|
22
|
+
preserveScrollPositions(targets) {
|
|
23
|
+
const positions = (Array.isArray(targets) ? targets : [targets]).map(target => {
|
|
24
|
+
const element = typeof target === 'string' ? document.querySelector(target) : target;
|
|
25
|
+
return element ? { element, left: element.scrollLeft, top: element.scrollTop } : null;
|
|
26
|
+
}).filter(Boolean);
|
|
27
|
+
return () => {
|
|
28
|
+
positions.forEach(({ element, left, top }) => {
|
|
29
|
+
if (!element.isConnected) return;
|
|
30
|
+
element.scrollLeft = left;
|
|
31
|
+
element.scrollTop = top;
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
isScrolledToEnd(element, tolerance = 2) {
|
|
36
|
+
if (!element) return true;
|
|
37
|
+
return element.scrollHeight - element.scrollTop - element.clientHeight <= tolerance;
|
|
38
|
+
},
|
|
22
39
|
reportRecoverableError(operation, error) {
|
|
23
40
|
const message = error && error.message ? error.message : String(error || 'unknown error');
|
|
24
41
|
console.warn(`[LoadToAgent:${operation}] ${message}`);
|