|
<!DOCTYPE html>
|
|
<html lang="ja">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>LINE風 AI WebUI</title>
|
|
<style>
|
|
/* リセットとベーススタイル */
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
}
|
|
|
|
body {
|
|
background-color: #f9f9f9;
|
|
color: #333;
|
|
font-size: 14px;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* LINE風カラースキーム */
|
|
:root {
|
|
--line-green: #06C755;
|
|
--line-green-dark: #05b14c;
|
|
--text-primary: #333333;
|
|
--text-secondary: #8c8c8c;
|
|
--bg-default: #f9f9f9;
|
|
--bg-paper: #ffffff;
|
|
--bg-chat-user: #ffffff;
|
|
--bg-chat-ai: #f5f5f5;
|
|
--divider: #e6e6e6;
|
|
}
|
|
|
|
/* レイアウト */
|
|
.app-container {
|
|
display: flex;
|
|
height: 100vh;
|
|
}
|
|
|
|
/* サイドバー */
|
|
.sidebar {
|
|
width: 240px;
|
|
background-color: var(--bg-paper);
|
|
border-right: 1px solid var(--divider);
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.sidebar-header {
|
|
padding: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
border-bottom: 1px solid var(--divider);
|
|
}
|
|
|
|
.sidebar-content {
|
|
flex-grow: 1;
|
|
overflow-y: auto;
|
|
padding: 8px;
|
|
}
|
|
|
|
.sidebar-footer {
|
|
padding: 16px;
|
|
text-align: center;
|
|
border-top: 1px solid var(--divider);
|
|
color: var(--text-secondary);
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* メインコンテンツ */
|
|
.main-content {
|
|
flex-grow: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
.top-bar {
|
|
height: 48px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 16px;
|
|
background-color: var(--bg-paper);
|
|
border-bottom: 1px solid var(--divider);
|
|
}
|
|
|
|
.content-area {
|
|
flex-grow: 1;
|
|
overflow-y: auto;
|
|
padding: 16px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* 右サイドバー */
|
|
.right-sidebar {
|
|
width: 340px;
|
|
background-color: var(--bg-paper);
|
|
border-left: 1px solid var(--divider);
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.right-sidebar-header {
|
|
height: 48px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-bottom: 1px solid var(--divider);
|
|
}
|
|
|
|
.right-sidebar-content {
|
|
flex-grow: 1;
|
|
padding: 16px;
|
|
overflow-y: auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* ナビゲーションメニュー */
|
|
.nav-menu {
|
|
list-style-type: none;
|
|
}
|
|
|
|
.nav-menu-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 12px 16px;
|
|
border-radius: 8px;
|
|
margin: 4px 0;
|
|
cursor: pointer;
|
|
color: var(--text-primary);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.nav-menu-item:hover {
|
|
background-color: rgba(6, 199, 85, 0.1);
|
|
}
|
|
|
|
.nav-menu-item.active {
|
|
background-color: var(--line-green);
|
|
color: white;
|
|
}
|
|
|
|
.nav-menu-item svg {
|
|
margin-right: 12px;
|
|
}
|
|
|
|
/* チャットUI */
|
|
.chat-container {
|
|
flex-grow: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
}
|
|
|
|
.chat-messages {
|
|
flex-grow: 1;
|
|
overflow-y: auto;
|
|
padding: 16px;
|
|
}
|
|
|
|
.message {
|
|
display: flex;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.message.user {
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
.avatar {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: white;
|
|
margin: 0 8px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.avatar.user {
|
|
background-color: var(--line-green);
|
|
}
|
|
|
|
.avatar.ai {
|
|
background-color: var(--text-secondary);
|
|
}
|
|
|
|
.message-bubble {
|
|
max-width: 70%;
|
|
padding: 12px 16px;
|
|
border-radius: 12px;
|
|
position: relative;
|
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.user .message-bubble {
|
|
background-color: var(--bg-chat-user);
|
|
margin-right: 12px;
|
|
border: 1px solid var(--divider);
|
|
}
|
|
|
|
.ai .message-bubble {
|
|
background-color: var(--bg-chat-ai);
|
|
margin-left: 12px;
|
|
}
|
|
|
|
.message-time {
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
margin-top: 4px;
|
|
text-align: right;
|
|
}
|
|
|
|
.ai .message-time {
|
|
text-align: left;
|
|
}
|
|
|
|
.chat-input {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 12px 16px;
|
|
background-color: var(--bg-paper);
|
|
border-radius: 24px;
|
|
margin: 16px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.chat-input input {
|
|
flex-grow: 1;
|
|
border: none;
|
|
outline: none;
|
|
background: transparent;
|
|
font-size: 14px;
|
|
padding: 0 12px;
|
|
}
|
|
|
|
.btn-icon {
|
|
width: 36px;
|
|
height: 36px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.btn-icon:hover {
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.btn-icon.primary {
|
|
color: var(--line-green);
|
|
}
|
|
|
|
/* コードエディタエリア */
|
|
.code-editor {
|
|
background-color: #1e1e1e;
|
|
color: #d4d4d4;
|
|
padding: 16px;
|
|
border-radius: 8px;
|
|
font-family: 'Fira Code', monospace;
|
|
margin-bottom: 16px;
|
|
white-space: pre-wrap;
|
|
height: 60%;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/* タブ */
|
|
.tabs {
|
|
display: flex;
|
|
border-bottom: 1px solid var(--divider);
|
|
}
|
|
|
|
.tab {
|
|
padding: 12px 16px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
border-bottom: 2px solid transparent;
|
|
flex-grow: 1;
|
|
text-align: center;
|
|
}
|
|
|
|
.tab.active {
|
|
border-bottom-color: var(--line-green);
|
|
color: var(--line-green);
|
|
}
|
|
|
|
/* コンソール */
|
|
.console {
|
|
background-color: #1e1e1e;
|
|
color: #d4d4d4;
|
|
padding: 16px;
|
|
border-radius: 8px;
|
|
font-family: 'Fira Code', monospace;
|
|
margin-top: 16px;
|
|
height: 30%;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.console-line {
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.console-command {
|
|
color: #61dafb;
|
|
}
|
|
|
|
.console-output {
|
|
color: #f1f1f1;
|
|
}
|
|
|
|
.console-error {
|
|
color: #ff6b6b;
|
|
}
|
|
|
|
.console-info {
|
|
color: #ffa726;
|
|
}
|
|
|
|
/* ユーティリティ */
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 8px 16px;
|
|
border-radius: 8px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
border: none;
|
|
outline: none;
|
|
font-size: 14px;
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.btn-primary {
|
|
background-color: var(--line-green);
|
|
color: white;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background-color: var(--line-green-dark);
|
|
}
|
|
|
|
.btn-outlined {
|
|
background-color: transparent;
|
|
border: 1px solid var(--line-green);
|
|
color: var(--line-green);
|
|
}
|
|
|
|
.btn-outlined:hover {
|
|
background-color: rgba(6, 199, 85, 0.04);
|
|
}
|
|
|
|
.icon {
|
|
height: 24px;
|
|
width: 24px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.typing-indicator {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.typing-indicator span {
|
|
width: 8px;
|
|
height: 8px;
|
|
background-color: var(--text-secondary);
|
|
border-radius: 50%;
|
|
display: inline-block;
|
|
margin-right: 4px;
|
|
animation: bounce 1.5s infinite ease-in-out;
|
|
}
|
|
|
|
.typing-indicator span:nth-child(2) {
|
|
animation-delay: 0.2s;
|
|
}
|
|
|
|
.typing-indicator span:nth-child(3) {
|
|
animation-delay: 0.4s;
|
|
}
|
|
|
|
@keyframes bounce {
|
|
0%, 80%, 100% { transform: translateY(0); }
|
|
40% { transform: translateY(-8px); }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="app-container">
|
|
<!-- 左サイドバー -->
|
|
<aside class="sidebar">
|
|
<div class="sidebar-header">
|
|
<div style="font-weight: 600; font-size: 16px;">AI WebUI</div>
|
|
</div>
|
|
<div class="sidebar-content">
|
|
<ul class="nav-menu">
|
|
<li class="nav-menu-item active">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path>
|
|
</svg>
|
|
チャット
|
|
</li>
|
|
<li class="nav-menu-item">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"></path>
|
|
</svg>
|
|
ファイルエクスプローラー
|
|
</li>
|
|
<li class="nav-menu-item">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M20 4H4c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V8h16v10z"></path>
|
|
</svg>
|
|
コンソール
|
|
</li>
|
|
<li class="nav-menu-item">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"></path>
|
|
</svg>
|
|
API設定
|
|
</li>
|
|
<li class="nav-menu-item">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"></path>
|
|
</svg>
|
|
設定
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="sidebar-footer">
|
|
© 2025 AI WebUI - v0.1.0
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- メインコンテンツ -->
|
|
<main class="main-content">
|
|
<div class="top-bar">
|
|
<div style="display: flex; align-items: center;">
|
|
<button class="btn-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path>
|
|
</svg>
|
|
</button>
|
|
<div style="font-weight: 600; margin-left: 8px;">チャット</div>
|
|
</div>
|
|
<div style="display: flex; align-items: center;">
|
|
<button class="btn-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path>
|
|
</svg>
|
|
</button>
|
|
<button class="btn-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z"></path>
|
|
</svg>
|
|
</button>
|
|
<button class="btn-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34-.46-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.87 1.52 2.34 1.07 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.92 0-1.11.38-2 1.03-2.71-.1-.25-.45-1.29.1-2.64 0 0 .84-.27 2.75 1.02.79-.22 1.65-.33 2.5-.33.85 0 1.71.11 2.5.33 1.91-1.29 2.75-1.02 2.75-1.02.55 1.35.2 2.39.1 2.64.65.71 1.03 1.6 1.03 2.71 0 3.82-2.34 4.66-4.57 4.91.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2z"></path>
|
|
</svg>
|
|
</button>
|
|
<button class="btn-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="content-area">
|
|
<div class="chat-container">
|
|
<div class="chat-messages">
|
|
<!-- AIメッセージ -->
|
|
<div class="message ai">
|
|
<div class="avatar ai">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zm-2 10H6V7h12v12zm-9-6c-.83 0-1.5-.67-1.5-1.5S8.17 10 9 10s1.5.67 1.5 1.5S9.83 13 9 13zm7.5-1.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5zM8 15h8v2H8v-2z"></path>
|
|
</svg>
|
|
</div>
|
|
<div class="message-bubble">
|
|
<div>こんにちは!AIアシスタントです。何かお手伝いできることはありますか?</div>
|
|
<div class="message-time">14:30</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ユーザーメッセージ -->
|
|
<div class="message user">
|
|
<div class="avatar user">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path>
|
|
</svg>
|
|
</div>
|
|
<div class="message-bubble">
|
|
<div>このアプリではどのような機能が使えますか?</div>
|
|
<div class="message-time">14:31</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- AIメッセージ -->
|
|
<div class="message ai">
|
|
<div class="avatar ai">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zm-2 10H6V7h12v12zm-9-6c-.83 0-1.5-.67-1.5-1.5S8.17 10 9 10s1.5.67 1.5 1.5S9.83 13 9 13zm7.5-1.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5zM8 15h8v2H8v-2z"></path>
|
|
</svg>
|
|
</div>
|
|
<div class="message-bubble">
|
|
<div>
|
|
このアプリでは以下の機能が利用できます:<br><br>
|
|
1. AIとのチャット機能<br>
|
|
2. ファイルエクスプローラー(ローカルファイル操作)<br>
|
|
3. SSH/FTPによるリモートサーバー接続<br>
|
|
4. コードエディタとプレビュー<br>
|
|
5. コンソールコマンド実行<br>
|
|
6. API設定管理(OpenAI、Anthropicなど)<br><br>
|
|
|
|
右側のサイドバーにはコードエディタやコンソール出力が表示されます。何か特定の機能について詳しく知りたいことはありますか?
|
|
</div>
|
|
<div class="message-time">14:32</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ユーザーメッセージ -->
|
|
<div class="message user">
|
|
<div class="avatar user">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path>
|
|
</svg>
|
|
</div>
|
|
<div class="message-bubble">
|
|
<div>SSH接続してみたいです。シンプルなNode.jsアプリのコード例を教えてください。</div>
|
|
<div class="message-time">14:33</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- AI応答中... -->
|
|
<div class="message ai">
|
|
<div class="avatar ai">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3zm-2 10H6V7h12v12zm-9-6c-.83 0-1.5-.67-1.5-1.5S8.17 10 9 10s1.5.67 1.5 1.5S9.83 13 9 13zm7.5-1.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5zM8 15h8v2H8v-2z"></path>
|
|
</svg>
|
|
</div>
|
|
<div class="typing-indicator">
|
|
<span></span>
|
|
<span></span>
|
|
<span></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="chat-input">
|
|
<button class="btn-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"></path>
|
|
</svg>
|
|
</button>
|
|
<input type="text" placeholder="メッセージを入力..." />
|
|
<button class="btn-icon primary">
|
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24" fill="currentColor">
|
|
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- 右サイドバー -->
|
|
<aside class="right-sidebar">
|
|
<div class="tabs">
|
|
<div class="tab active">コード</div>
|
|
<div class="tab">コンソール</div>
|
|
<div class="tab">プレビュー</div>
|
|
</div>
|
|
<div class="right-sidebar-content">
|
|
<div class="code-editor">
|
|
<span style="color: #569cd6;">const</span> { <span style="color: #9cdcfe;">NodeSSH</span> } = <span style="color: #569cd6;">require</span>(<span style="color: #ce9178;">'node-ssh'</span>);
|
|
<span style="color: #569cd6;">const</span> <span style="color: #9cdcfe;">ssh</span> = <span style="color: #569cd6;">new</span> <span style="color: #4ec9b0;">NodeSSH</span>();
|
|
|
|
<span style="color: #6a9955;">// SSHサーバーに接続</span>
|
|
<span style="color: #569cd6;">async</span> <span style="color: #569cd6;">function</span> <span style="color: #dcdcaa;">connectToServer</span>() {
|
|
<span style="color: #c586c0;">try</span> {
|
|
<span style="color: #c586c0;">await</span> ssh.<span style="color: #dcdcaa;">connect</span>({
|
|
<span style="color: #9cdcfe;">host</span>: <span style="color: #ce9178;">'example.com'</span>,
|
|
<span style="color: #9cdcfe;">username</span>: <span style="color: #ce9178;">'username'</span>,
|
|
<span style="color: #9cdcfe;">password</span>: <span style="color: #ce9178;">'password'</span>,
|
|
<span style="color: #9cdcfe;">port</span>: <span style="color: #b5cea8;">22</span>,
|
|
});
|
|
|
|
console.<span style="color: #dcdcaa;">log</span>(<span style="color: #ce9178;">'SSH接続に成功しました'</span>);
|
|
|
|
<span style="color: #6a9955;">// コマンド実行</span>
|
|
<span style="color: #569cd6;">const</span> <span style="color: #9cdcfe;">result</span> = <span style="color: #c586c0;">await</span> ssh.<span style="color: #dcdcaa;">execCommand</span>(<span style="color: #ce9178;">'ls -la'</span>);
|
|
console.<span style="color: #dcdcaa;">log</span>(<span style="color: #ce9178;">'STDOUT: '</span> + result.stdout);
|
|
console.<span style="color: #dcdcaa;">log</span>(<span style="color: #ce9178;">'STDERR: '</span> + result.stderr);
|
|
|
|
<span style="color: #6a9955;">// 接続を閉じる</span>
|
|
ssh.<span style="color: #dcdcaa;">dispose</span>();
|
|
} <span style="color: #c586c0;">catch</span> (error) {
|
|
console.<span style="color: #dcdcaa;">error</span>(<span style="color: #ce9178;">'SSH接続エラー:'</span>, error);
|
|
}
|
|
}
|
|
|
|
<span style="color: #dcdcaa;">connectToServer</span>();
|
|
</div>
|
|
|
|
<div class="console">
|
|
<div class="console-line console-info">$ node ssh-example.js</div>
|
|
<div class="console-line console-output">SSH接続中...</div>
|
|
<div class="console-line console-output">SSH接続に成功しました</div>
|
|
<div class="console-line console-output">STDOUT: total 120</div>
|
|
<div class="console-line console-output">drwxr-xr-x 12 user staff 384 May 10 14:30 .</div>
|
|
<div class="console-line console-output">drwxr-xr-x 5 user staff 160 May 9 09:15 ..</div>
|
|
<div class="console-line console-output">-rw-r--r-- 1 user staff 386 May 10 14:28 package.json</div>
|
|
<div class="console-line console-output">-rw-r--r-- 1 user staff 4.2K May 10 13:45 server.js</div>
|
|
<div class="console-line console-output">drwxr-xr-x 11 user staff 352 May 10 12:30 node_modules</div>
|
|
<div class="console-line console-output">-rw-r--r-- 1 user staff 1.8K May 10 11:22 README.md</div>
|
|
<div class="console-line console-output">STDERR: </div>
|
|
<div class="console-line console-output">SSH接続を切断しました</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</body>
|
|
</html>
|