buddy-workbench 0.1.6 → 0.1.8
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 +1 -1
- package/server/repositories/settings.js +10 -1
- package/server/routes/pr-review.js +55 -0
- package/server/routes/settings.js +6 -1
- package/server/services/clipboard-history.js +2 -0
- package/ui/dist/assets/index-BHs_wPig.css +1 -0
- package/ui/dist/assets/index-CkXRrM63.js +500 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-d11DtBlK.css +0 -1
- package/ui/dist/assets/index-yvU_XBk9.js +0 -496
package/package.json
CHANGED
|
@@ -13,7 +13,8 @@ export function settingsStatus() {
|
|
|
13
13
|
domain: typeof settings.domain === 'string' ? settings.domain : '',
|
|
14
14
|
bitbucketTokenConfigured: Boolean(settings.bitbucketAccessToken),
|
|
15
15
|
jiraTokenConfigured: Boolean(settings.jiraAccessToken),
|
|
16
|
-
confluenceTokenConfigured: Boolean(settings.confluenceAccessToken)
|
|
16
|
+
confluenceTokenConfigured: Boolean(settings.confluenceAccessToken),
|
|
17
|
+
clipboardEnabled: settings.clipboardEnabled !== false
|
|
17
18
|
};
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -26,6 +27,14 @@ export function saveDomain(domain) {
|
|
|
26
27
|
return settingsStatus();
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
export function saveClipboardEnabled(enabled) {
|
|
31
|
+
const settings = readSettings();
|
|
32
|
+
settings.clipboardEnabled = Boolean(enabled);
|
|
33
|
+
mkdirSync(dirname(paths.settings), { recursive: true });
|
|
34
|
+
writeFileSync(paths.settings, JSON.stringify(settings, null, 2), { mode: 0o600 });
|
|
35
|
+
return settingsStatus();
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
const accessTokenFields = {
|
|
30
39
|
bitbucket: 'bitbucketAccessToken',
|
|
31
40
|
jira: 'jiraAccessToken',
|
|
@@ -375,4 +375,59 @@ router.get('/review-prs', async (req, res) => {
|
|
|
375
375
|
}
|
|
376
376
|
});
|
|
377
377
|
|
|
378
|
+
router.post('/comment', async (req, res) => {
|
|
379
|
+
const { projectKey, repositorySlug, pullRequestId, filePath, line, commentText } = req.body || {};
|
|
380
|
+
if (!projectKey || !repositorySlug || !pullRequestId || !commentText) {
|
|
381
|
+
return res.status(400).json({ error: 'Missing required parameters.' });
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const host = getBitbucketHost();
|
|
385
|
+
const settings = readSettings();
|
|
386
|
+
const token = settings.bitbucketAccessToken;
|
|
387
|
+
|
|
388
|
+
if (!host || !token) {
|
|
389
|
+
return res.status(400).json({ error: 'Bitbucket Access Token or Host not configured.' });
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const url = `https://${host}/rest/api/1.0/projects/${projectKey}/repos/${repositorySlug}/pull-requests/${pullRequestId}/comments`;
|
|
393
|
+
const headers = {
|
|
394
|
+
'Content-Type': 'application/json',
|
|
395
|
+
'Accept': 'application/json',
|
|
396
|
+
'Authorization': `Bearer ${token}`
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const payload = {
|
|
400
|
+
text: commentText
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
if (filePath && line) {
|
|
404
|
+
payload.anchor = {
|
|
405
|
+
line: parseInt(line, 10),
|
|
406
|
+
lineType: 'ADDED',
|
|
407
|
+
fileType: 'TO',
|
|
408
|
+
path: filePath
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
try {
|
|
413
|
+
const response = await fetch(url, {
|
|
414
|
+
method: 'POST',
|
|
415
|
+
headers,
|
|
416
|
+
body: JSON.stringify(payload)
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
if (!response.ok) {
|
|
420
|
+
const errJson = await response.json().catch(() => ({}));
|
|
421
|
+
return res.status(response.status).json({
|
|
422
|
+
error: errJson.errors?.[0]?.message || errJson.message || `Bitbucket API error: ${response.statusText}`
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const data = await response.json();
|
|
427
|
+
res.json({ success: true, data });
|
|
428
|
+
} catch (error) {
|
|
429
|
+
res.status(500).json({ error: error.message });
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
|
|
378
433
|
export default router;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { saveAccessToken, saveDomain, settingsStatus } from '../repositories/settings.js';
|
|
2
|
+
import { saveAccessToken, saveClipboardEnabled, saveDomain, settingsStatus } from '../repositories/settings.js';
|
|
3
3
|
|
|
4
4
|
const router = Router();
|
|
5
5
|
|
|
@@ -9,6 +9,11 @@ router.put('/domain', (req, res) => {
|
|
|
9
9
|
if (typeof domain !== 'string') return res.status(400).json({ error: 'Domain must be a string.' });
|
|
10
10
|
res.json(saveDomain(domain.trim()));
|
|
11
11
|
});
|
|
12
|
+
router.put('/clipboard-enabled', (req, res) => {
|
|
13
|
+
const { enabled } = req.body || {};
|
|
14
|
+
if (typeof enabled !== 'boolean') return res.status(400).json({ error: 'Enabled must be a boolean.' });
|
|
15
|
+
res.json(saveClipboardEnabled(enabled));
|
|
16
|
+
});
|
|
12
17
|
router.put('/:service-access-token', (req, res) => {
|
|
13
18
|
const { token } = req.body || {};
|
|
14
19
|
if (typeof token !== 'string') return res.status(400).json({ error: 'Token must be a string.' });
|
|
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFile
|
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
5
|
import { paths } from '../config.js';
|
|
6
|
+
import { readSettings } from '../repositories/settings.js';
|
|
6
7
|
|
|
7
8
|
const execFileAsync = promisify(execFile);
|
|
8
9
|
const previewLimit = 2000;
|
|
@@ -38,6 +39,7 @@ export function deleteClipboardItem(date, id) {
|
|
|
38
39
|
|
|
39
40
|
export async function captureClipboard() {
|
|
40
41
|
if (process.platform !== 'darwin') return;
|
|
42
|
+
if (readSettings().clipboardEnabled === false) return;
|
|
41
43
|
try {
|
|
42
44
|
const { stdout } = await execFileAsync('pbpaste'); const text = stdout.trim();
|
|
43
45
|
if (!text || text === lastValue) return;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
html,body{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,*:before,*:after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}body{margin:0}[tabindex="-1"]:focus{outline:none}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[title],abbr[data-original-title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=text],input[type=password],input[type=number],textarea{-webkit-appearance:none}ol,ul,dl{margin-top:0;margin-bottom:1em}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}pre,code,kbd,samp{font-size:1em;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle;border-style:none}a,area,button,[role=button],input:not([type=range]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;text-align:left;caption-side:bottom}input,button,select,optgroup,textarea{margin:0;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{padding:0;border-style:none}input[type=radio],input[type=checkbox]{box-sizing:border-box;padding:0}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;max-width:100%;margin-bottom:.5em;padding:0;color:inherit;font-size:1.5em;line-height:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}:root{font-family:Inter,ui-sans-serif,system-ui,-apple-system,PingFang SC,sans-serif;color:#172033;background:#f7f8fc}html,body{height:100vh;overflow:hidden}body{margin:0;background:#f7f8fc}.workbench{height:100vh;overflow:hidden;background:#f7f8fc}.sidebar{position:sticky!important;top:0;height:100vh;background:#171c2b!important;padding:28px 14px}.sidebar .ant-menu-title-content{-webkit-user-select:none;user-select:none}.brand{padding:0 12px 30px;color:#fff;font-size:21px;font-weight:750;letter-spacing:-.4px}.brand span{color:#9589ff}.sidebar .ant-menu{background:transparent;border-inline-end:0}.sidebar-bottom{position:absolute;right:14px;bottom:28px;left:14px}.sidebar-footer{padding:14px 12px 0;color:#727b94;font-size:12px}.page{height:100vh;overflow-y:auto;padding:46px clamp(24px,5vw,72px)}.page-header{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:30px}.page-header .ant-typography{margin:0}.launcher-grid{display:grid;gap:7px}.launcher-card{cursor:pointer;border-color:#e3e6ef}.launcher-card .ant-card-body{padding:10px 14px}.service-card{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:46px}.service-card .ant-typography{display:block;margin:0}.service-card h4.ant-typography{margin:0 0 1px;font-size:15px;line-height:20px}.service-info{min-width:0;flex:1}.service-info>.ant-typography{font-size:12px;line-height:16px}.service-action{display:flex;flex-direction:column;align-items:flex-end;gap:3px;white-space:nowrap}.service-action .ant-badge{font-size:11px;line-height:14px}.launcher-table .ant-table-tbody>tr{cursor:pointer}.launcher-folder{display:block;max-width:620px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.start-script-icon{color:#8c8c8c;font-size:12px}.script-add{margin-bottom:10px}.service-config{margin-bottom:10px;margin-top:10px}.service-config .ant-collapse-content-box{padding-bottom:0!important}.service-config .ant-form-item{margin-bottom:14px}.clipboard-picker{min-width:190px}.squoosh-page{position:relative;min-height:calc(100vh - 92px);margin:-20px clamp(-24px,-5vw,-72px);padding:24px clamp(24px,5vw,72px);color:#172033}.squoosh-page.is-file-dragging{box-shadow:inset 0 0 0 3px #7667e8}.squoosh-page.is-file-dragging:after{position:absolute;z-index:20;top:12px;right:12px;bottom:12px;left:12px;display:grid;place-items:center;border:2px dashed #7667e8;border-radius:12px;background:#f8f7ffc7;color:#5b4cc4;content:"Drop image to compress";font-size:20px;font-weight:700;pointer-events:none}.squoosh-header{display:flex;align-items:center;justify-content:space-between;gap:20px;padding-bottom:20px;border-bottom:1px solid #e4e7ef}.squoosh-header .ant-typography{margin:0;color:inherit}.squoosh-header>div>.ant-typography:first-child,.settings-heading>.ant-typography:first-child{color:#6d5ce7;font-size:11px;font-weight:750;letter-spacing:.12em}.squoosh-header h2.ant-typography{margin-top:4px;font-size:25px}.squoosh-studio{display:grid;grid-template-columns:minmax(0,1fr) 380px;margin-top:16px;border:1px solid #e1e5ed;border-radius:10px;overflow:hidden;background:#fff;box-shadow:0 12px 32px #1f2a4412}.squoosh-preview-area{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));min-width:0;background:#fbfcfe}.preview-pane{display:grid;grid-template-rows:auto minmax(0,1fr);min-width:0;min-height:570px}.preview-pane+.preview-pane{border-left:1px solid #e1e5ed}.preview-pane>header{display:flex;justify-content:space-between;align-items:center;gap:12px;min-height:58px;padding:0 16px;border-bottom:1px solid #e1e5ed;background:#fff}.preview-pane>header>div{display:grid;gap:1px;min-width:0}.preview-pane>header .ant-typography{color:#27344c;font-weight:650}.preview-pane>header span{overflow:hidden;color:#7d8799;font-size:12px;text-overflow:ellipsis;white-space:nowrap}.preview-canvas{position:relative;display:grid;min-width:0;min-height:0;place-items:center;padding:22px;background-color:#f3f5f9;background-image:linear-gradient(45deg,#e9edf4 25%,transparent 25%),linear-gradient(-45deg,#e9edf4 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#e9edf4 75%),linear-gradient(-45deg,transparent 75%,#e9edf4 75%);background-position:0 0,0 12px,12px -12px,-12px 0;background-size:24px 24px}.image-dropzone{width:100%;max-width:420px}.image-dropzone.ant-upload-wrapper .ant-upload-drag{border-color:#cfd6e4;background:#ffffffe0}.image-dropzone.ant-upload-wrapper .ant-upload-drag:hover{border-color:#7667e8}.image-dropzone .ant-upload{padding:76px 18px!important}.image-dropzone .ant-upload-drag-icon .anticon{color:#6d5ce7}.image-dropzone .ant-upload-text{color:#27344c!important}.image-dropzone .ant-upload-hint{color:#7d8799!important}.image-panel{display:flex;align-items:center;justify-content:center;width:100%;height:100%;min-width:0;min-height:0}.image-panel img{display:block;width:auto;max-width:100%;max-height:min(65vh,650px);object-fit:contain;border-radius:5px;box-shadow:0 10px 30px #00000052}.image-panel-meta{display:grid;gap:3px;min-width:0;text-align:center}.image-panel-meta .ant-typography{min-width:0;color:#46516a}.squoosh-settings{overflow-y:auto;padding:22px 20px;background:#fff}.settings-heading{margin-bottom:21px;padding-bottom:17px;border-bottom:1px solid #e7eaf0}.settings-heading .ant-typography{margin:0;color:#27344c}.settings-heading h4.ant-typography{margin-top:5px}.settings-heading .ant-typography-secondary{margin-top:4px;color:#7d8799;font-size:13px}.option-row,.option-switch,.option-select{display:flex;justify-content:space-between;align-items:center;gap:16px}.option-row{margin-bottom:4px}.option-row .ant-typography,.option-switch .ant-typography,.option-select .ant-typography{color:#27344c}.option-row .ant-typography-secondary,.option-switch .ant-typography-secondary,.option-select .ant-typography-secondary{color:#7d8799;font-size:12px}.option-switch{padding:15px 0;border-top:1px solid #e7eaf0}.option-select{padding:14px 0;border-top:1px solid #e7eaf0}.option-select .ant-select,.option-select .ant-input-number{flex:0 0 170px;width:170px}.advanced-options{margin:6px -12px 16px}.advanced-options .ant-collapse-header,.advanced-options .ant-collapse-content{color:#46516a!important}.advanced-options .ant-collapse-content{background:transparent}.advanced-options .ant-collapse-content-box{padding-top:0!important}.image-loading{display:grid;min-height:330px;place-items:center}.image-loading .ant-spin-text{color:#46516a}.preview-pane>header button.ant-btn.ant-btn-color-primary{min-width:116px;border-color:#5f50d8!important;background:#6657dc!important;color:#fff!important;font-weight:650;text-shadow:none}.preview-pane>header button.ant-btn.ant-btn-color-primary>span,.preview-pane>header button.ant-btn.ant-btn-color-primary .anticon{color:#fff!important}.preview-pane>header button.ant-btn.ant-btn-color-primary:hover{border-color:#5143c2!important;background:#5143c2!important;color:#fff!important}.compression-saving{position:absolute;bottom:24px;left:50%;z-index:1;margin:0;padding:9px 12px;border-radius:4px;background:#fff7e6;color:#ad6800;font-weight:600;text-align:center;transform:translate(-50%);white-space:nowrap}.compression-saving.is-saving{background:#f6ffed;color:#389e0d}.clipboard-tabs{margin:-12px 0 16px}.clipboard-tabs .ant-tabs-nav{margin-bottom:0}.clipboard-list{display:grid;gap:8px}.clipboard-item .ant-card-body{position:relative;display:block;padding:12px 14px}.clipboard-item .ant-card-body>div{width:100%;min-width:0}.clipboard-actions{position:absolute;top:8px;right:8px;display:flex}.clipboard-item pre{width:100%;max-height:160px;overflow:auto;margin:5px 0 0;white-space:pre-wrap;overflow-wrap:anywhere;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace}.clipboard-original{display:flex;gap:12px;margin-top:8px;font-size:12px}.port-manual-query{margin:-12px 0 16px}.port-query-result{margin-top:12px}.group-task-list{display:grid;gap:8px}.group-task-header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:16px}.group-task-empty{margin:16px 0}.group-task-card{display:flex;align-items:center;justify-content:space-between;gap:16px}.group-task-card>div:first-child{display:grid;gap:2px}.group-task-card .ant-space{flex-wrap:nowrap}.group-task-card .ant-btn{width:72px}.group-task-selector{display:grid;gap:8px;width:100%}.group-task-selector .ant-card-body{padding:10px 14px}.group-task-projects{display:grid;gap:8px}.settings-page{width:100%;max-width:none}.settings-page>.ant-typography{margin:0}.settings-page-header{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-page-header .ant-typography{margin:0}.settings-page-header>.ant-btn{min-width:96px}.settings-card{width:100%;margin-top:20px;border-radius:14px;border:1px solid #e4e8f1;box-shadow:0 2px 12px #1f2a440d}.settings-card h4.ant-typography{margin:0}.settings-icon-wrap{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex-shrink:0;border-radius:10px;background:linear-gradient(135deg,#ece9fc,#ddd6fe)}.settings-icon{color:#6d5ce7;font-size:18px}.settings-title{display:flex;align-items:center;gap:14px;margin-bottom:24px;padding-bottom:20px;border-bottom:1px solid #eef0f6}.settings-title .ant-typography{margin:0}.settings-title .ant-typography-secondary{font-size:13px;margin-top:2px}.token-settings-form{display:grid;gap:0}.token-row{display:grid;grid-template-columns:200px 1fr;align-items:center;gap:20px;padding:16px 18px;margin:0 -6px;border-radius:10px;border:1px solid transparent;transition:background .18s,border-color .18s}.token-row:hover{background:#f8f9fc;border-color:#eef0f6}.token-row+.token-row{margin-top:2px}.token-row.is-configured{background:#fafbfe}.token-row-info{display:grid;gap:2px;min-width:0}.token-row-name-line{display:flex;align-items:center;gap:8px}.token-row-name{font-size:14px;white-space:nowrap}.token-row-hint{font-size:12px;line-height:1.4}.token-row-tag.ant-tag{margin:0;font-size:11px;line-height:18px;padding-inline:6px;border-radius:4px}.token-row .ant-form-item{margin:0;min-width:0}.token-row .ant-input,.token-row .ant-input-password{border-radius:8px}.script-header{display:flex;align-items:center;gap:16px}.script-header .ant-divider{flex:1;min-width:0;margin:16px 0}.script-header>.ant-btn{flex-shrink:0}.script-editor{margin-bottom:10px}.script-fields{display:grid;grid-template-columns:1fr 1.5fr;gap:12px}.script-fields .ant-form-item{margin-bottom:12px}.log-output{min-height:360px;max-height:58vh;overflow:auto;margin:0;padding:12px 0;border-radius:4px;background:#111827;color:#d1fae5;font:12px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace}.log-line{min-height:19px}.log-line:hover{background:#ffffff0a}.log-line code{padding:0 15px;overflow-wrap:anywhere;color:inherit;white-space:pre-wrap;font:inherit}.log-link{color:#7dd3fc;text-decoration:underline;text-underline-offset:2px}.log-link:hover{color:#bae6fd}.ansi-black{color:#475569}.ansi-red,.log-error{color:#fb7185}.ansi-green,.log-success{color:#86efac}.ansi-yellow,.log-warning{color:#fcd34d}.ansi-blue{color:#93c5fd}.ansi-magenta{color:#f0abfc}.ansi-cyan{color:#67e8f9}.ansi-gray{color:#94a3b8}.ansi-white{color:#f8fafc}@media(max-width:1100px){.squoosh-studio{grid-template-columns:1fr}.squoosh-settings{border-top:1px solid #e1e5ed}.preview-pane{min-height:440px}}@media(max-width:650px){.sidebar{width:64px!important;min-width:64px!important;padding:20px 8px}.brand{padding:0 10px 25px;font-size:0}.brand span{font-size:20px}.sidebar .ant-menu-title-content,.sidebar-footer{display:none}.sidebar-bottom{right:8px;bottom:20px;left:8px}.page{padding:32px 20px}.service-card,.page-header{align-items:flex-start;flex-direction:column}.script-fields{grid-template-columns:1fr}.token-row{grid-template-columns:1fr;gap:10px;padding:14px 12px}.squoosh-page{min-height:calc(100vh - 64px);margin:-12px -20px -32px;padding:18px 20px 28px}.squoosh-header{align-items:flex-start;flex-direction:column}.squoosh-preview-area{grid-template-columns:1fr}.preview-pane{min-height:360px}.preview-pane+.preview-pane{border-top:1px solid #e1e5ed;border-left:0}.preview-canvas{min-height:300px}}.standalone-log-container{display:flex;flex-direction:column;height:100vh;background:#111827;overflow:hidden}.standalone-log-header{display:flex;justify-content:space-between;align-items:center;padding:12px 24px;background:#1f2937;border-bottom:1px solid #374151;color:#f3f4f6;flex-shrink:0}.standalone-log-body{flex:1;min-height:0;display:flex;flex-direction:column;background:#111827}.standalone-log-body .log-output{flex:1;min-height:0;max-height:none!important;border-radius:0!important;margin:0!important;padding:16px 0}
|