thepopebot 1.2.76-beta.26 → 1.2.76-beta.27

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/api/index.js CHANGED
@@ -116,8 +116,9 @@ async function handleGetAgentSecret(request) {
116
116
  return Response.json({ error: 'Forbidden' }, { status: 403 });
117
117
  }
118
118
 
119
- const key = new URL(request.url).searchParams.get('key');
120
- if (!key) return Response.json({ error: 'Missing key' }, { status: 400 });
119
+ const rawKey = new URL(request.url).searchParams.get('key');
120
+ if (!rawKey) return Response.json({ error: 'Missing key' }, { status: 400 });
121
+ const key = rawKey.toUpperCase();
121
122
 
122
123
  const { getAgentJobSecretRaw, setAgentJobSecret: saveSecret } = await import('../lib/db/config.js');
123
124
  const raw = getAgentJobSecretRaw(key);
@@ -1,10 +1,12 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useRef, useEffect, useCallback, useState } from "react";
4
- import { SendIcon, StopIcon, PaperclipIcon, XIcon, FileTextIcon, MicIcon } from "./icons.js";
4
+ import { SendIcon, StopIcon, PaperclipIcon, XIcon, FileTextIcon, MicIcon, KeyIcon } from "./icons.js";
5
5
  import { useVoiceInput } from "../../voice/use-voice-input.js";
6
6
  const getVoiceTokenFetch = () => fetch("/chat/voice-token").then((r) => r.json()).catch(() => ({ error: "Failed to get voice token" }));
7
7
  import { VoiceBars } from "./voice-bars.jsx";
8
+ import { Dialog } from "./settings-shared.js";
9
+ import { JobSecretsManager } from "./settings-jobs-page.js";
8
10
  import { cn } from "../utils.js";
9
11
  const ACCEPTED_TYPES = [
10
12
  "image/jpeg",
@@ -67,6 +69,7 @@ function ChatInput({ input, setInput, onSubmit, status, stop, files, setFiles, d
67
69
  const [modeDropdownOpen, setModeDropdownOpen] = useState(false);
68
70
  const [agentPickerOpen, setAgentPickerOpen] = useState(false);
69
71
  const [partialText, setPartialText] = useState("");
72
+ const [secretsOpen, setSecretsOpen] = useState(false);
70
73
  const dropdownRef = useRef(null);
71
74
  const agentPickerRef = useRef(null);
72
75
  const isStreaming = status === "streaming" || status === "submitted";
@@ -301,6 +304,18 @@ function ChatInput({ input, setInput, onSubmit, status, stop, files, setFiles, d
301
304
  )
302
305
  ] })
303
306
  ] }),
307
+ !codeMode && /* @__PURE__ */ jsx(
308
+ "button",
309
+ {
310
+ type: "button",
311
+ onClick: () => setSecretsOpen(true),
312
+ className: "inline-flex items-center justify-center rounded-lg p-2.5 text-muted-foreground hover:text-foreground",
313
+ "aria-label": "Manage agent job secrets",
314
+ title: "Manage agent job secrets",
315
+ disabled: isStreaming,
316
+ children: /* @__PURE__ */ jsx(KeyIcon, { size: 16 })
317
+ }
318
+ ),
304
319
  codeModeSettings && !codeModeSettings.isInteractiveActive && /* @__PURE__ */ jsxs("div", { className: "relative", ref: agentPickerRef, children: [
305
320
  agentPickerOpen && codeModeSettings.availableAgents?.length > 1 && /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full left-0 mb-1.5 z-50 min-w-[140px] rounded-md border border-border bg-background shadow-md py-1 overflow-hidden", children: [
306
321
  /* @__PURE__ */ jsx("p", { className: "px-3 pt-0.5 pb-1 text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Launch with" }),
@@ -417,8 +432,24 @@ function ChatInput({ input, setInput, onSubmit, status, stop, files, setFiles, d
417
432
  ]
418
433
  }
419
434
  ) });
420
- if (bare) return formContent;
421
- return /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-4xl px-1.5 pb-[max(1rem,var(--safe-area-bottom))] md:px-6", children: formContent });
435
+ const secretsDialog = !codeMode ? /* @__PURE__ */ jsx(
436
+ Dialog,
437
+ {
438
+ open: secretsOpen,
439
+ onClose: () => setSecretsOpen(false),
440
+ title: "Agent Job Secrets",
441
+ maxWidth: "max-w-2xl",
442
+ children: /* @__PURE__ */ jsx(JobSecretsManager, { showHeader: false })
443
+ }
444
+ ) : null;
445
+ if (bare) return /* @__PURE__ */ jsxs(Fragment, { children: [
446
+ formContent,
447
+ secretsDialog
448
+ ] });
449
+ return /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-4xl px-1.5 pb-[max(1rem,var(--safe-area-bottom))] md:px-6", children: [
450
+ formContent,
451
+ secretsDialog
452
+ ] });
422
453
  }
423
454
  export {
424
455
  ChatInput
@@ -1,11 +1,13 @@
1
1
  'use client';
2
2
 
3
3
  import { useRef, useEffect, useCallback, useState } from 'react';
4
- import { SendIcon, StopIcon, PaperclipIcon, XIcon, FileTextIcon, MicIcon } from './icons.js';
4
+ import { SendIcon, StopIcon, PaperclipIcon, XIcon, FileTextIcon, MicIcon, KeyIcon } from './icons.js';
5
5
  import { useVoiceInput } from '../../voice/use-voice-input.js';
6
6
  const getVoiceTokenFetch = () =>
7
7
  fetch('/chat/voice-token').then(r => r.json()).catch(() => ({ error: 'Failed to get voice token' }));
8
8
  import { VoiceBars } from './voice-bars.jsx';
9
+ import { Dialog } from './settings-shared.js';
10
+ import { JobSecretsManager } from './settings-jobs-page.js';
9
11
  import { cn } from '../utils.js';
10
12
 
11
13
  const ACCEPTED_TYPES = [
@@ -48,6 +50,7 @@ export function ChatInput({ input, setInput, onSubmit, status, stop, files, setF
48
50
  const [modeDropdownOpen, setModeDropdownOpen] = useState(false);
49
51
  const [agentPickerOpen, setAgentPickerOpen] = useState(false);
50
52
  const [partialText, setPartialText] = useState('');
53
+ const [secretsOpen, setSecretsOpen] = useState(false);
51
54
  const dropdownRef = useRef(null);
52
55
  const agentPickerRef = useRef(null);
53
56
  const isStreaming = status === 'streaming' || status === 'submitted';
@@ -311,6 +314,19 @@ export function ChatInput({ input, setInput, onSubmit, status, stop, files, setF
311
314
  </div>
312
315
  )}
313
316
 
317
+ {!codeMode && (
318
+ <button
319
+ type="button"
320
+ onClick={() => setSecretsOpen(true)}
321
+ className="inline-flex items-center justify-center rounded-lg p-2.5 text-muted-foreground hover:text-foreground"
322
+ aria-label="Manage agent job secrets"
323
+ title="Manage agent job secrets"
324
+ disabled={isStreaming}
325
+ >
326
+ <KeyIcon size={16} />
327
+ </button>
328
+ )}
329
+
314
330
  {/* Interactive toggle — left-click to launch with default agent,
315
331
  right-click to pick a specific agent (when multiple are available) */}
316
332
  {codeModeSettings && !codeModeSettings.isInteractiveActive && (
@@ -433,10 +449,22 @@ export function ChatInput({ input, setInput, onSubmit, status, stop, files, setF
433
449
  </form>
434
450
  );
435
451
 
436
- if (bare) return formContent;
452
+ const secretsDialog = !codeMode ? (
453
+ <Dialog
454
+ open={secretsOpen}
455
+ onClose={() => setSecretsOpen(false)}
456
+ title="Agent Job Secrets"
457
+ maxWidth="max-w-2xl"
458
+ >
459
+ <JobSecretsManager showHeader={false} />
460
+ </Dialog>
461
+ ) : null;
462
+
463
+ if (bare) return <>{formContent}{secretsDialog}</>;
437
464
  return (
438
465
  <div className="mx-auto w-full max-w-4xl px-1.5 pb-[max(1rem,var(--safe-area-bottom))] md:px-6">
439
466
  {formContent}
467
+ {secretsDialog}
440
468
  </div>
441
469
  );
442
470
  }
@@ -344,100 +344,61 @@ function Chat({ chatId, initialMessages = [], workspace = null, chatMode = null
344
344
  }
345
345
  ) })
346
346
  ] })
347
- ] }) }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden relative", children: [
348
- showDiff && workspaceState?.id && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-10 bg-black/50" }),
349
- showDiff && workspaceState?.id ? /* @__PURE__ */ jsxs(Fragment, { children: [
350
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 z-20 p-0 md:p-4 flex flex-col", children: /* @__PURE__ */ jsx(
351
- DiffViewer,
347
+ ] }) }) : /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden", children: showDiff && workspaceState?.id ? /* @__PURE__ */ jsx(
348
+ DiffViewer,
349
+ {
350
+ workspaceId: workspaceState.id,
351
+ diffStats,
352
+ onClose: () => setShowDiff(false)
353
+ }
354
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
355
+ /* @__PURE__ */ jsx(Messages, { messages, status, onRetry: handleRetry, onEdit: handleEdit }),
356
+ error && /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-4xl px-2 md:px-4", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 px-4 py-2 text-sm text-destructive", children: error.message || "Something went wrong. Please try again." }) }),
357
+ /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-4xl px-4 pb-4 md:px-6", children: [
358
+ isInteractiveActive && /* @__PURE__ */ jsxs(
359
+ "a",
360
+ {
361
+ href: `/code/${workspaceState?.id}`,
362
+ className: "flex items-center justify-center gap-2 rounded-xl border border-primary/20 bg-primary/5 px-4 py-3 mb-2 text-sm font-medium text-primary hover:bg-primary/10 transition-colors",
363
+ children: [
364
+ /* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse" }),
365
+ "Click here to access Interactive Mode"
366
+ ]
367
+ }
368
+ ),
369
+ workspaceState && /* @__PURE__ */ jsx("div", { className: "rounded-t-xl border border-b-0 border-border px-3 py-2.5", children: /* @__PURE__ */ jsx(
370
+ WorkspaceBar,
352
371
  {
353
- workspaceId: workspaceState.id,
372
+ repo,
373
+ branch,
374
+ onBranchChange: handleBranchChange,
375
+ getBranches: fetchBranches,
376
+ workspace: workspaceState,
354
377
  diffStats,
355
- onClose: () => setShowDiff(false)
378
+ onDiffStatsRefresh: handleDiffStatsRefresh,
379
+ onShowDiff: () => setShowDiff(true)
356
380
  }
357
381
  ) }),
358
- /* @__PURE__ */ jsx("div", { className: "z-20 px-4 pb-4", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-4xl", children: [
359
- workspaceState && /* @__PURE__ */ jsx("div", { className: "rounded-t-xl border border-b-0 border-border px-3 py-2.5 bg-background", children: /* @__PURE__ */ jsx(
360
- WorkspaceBar,
361
- {
362
- repo,
363
- branch,
364
- onBranchChange: handleBranchChange,
365
- getBranches: fetchBranches,
366
- workspace: workspaceState,
367
- diffStats,
368
- onDiffStatsRefresh: handleDiffStatsRefresh,
369
- onShowDiff: () => setShowDiff(true),
370
- chatMode: codeMode ? "code" : "agent"
371
- }
372
- ) }),
373
- /* @__PURE__ */ jsx(
374
- ChatInput,
375
- {
376
- bare: true,
377
- input,
378
- setInput,
379
- onSubmit: handleSend,
380
- status,
381
- stop,
382
- files,
383
- setFiles,
384
- disabled: isInteractiveActive,
385
- placeholder: isInteractiveActive ? "Interactive mode is active." : defaultPlaceholder,
386
- className: workspaceState ? "rounded-t-none" : void 0,
387
- codeMode,
388
- codeModeSettings
389
- }
390
- )
391
- ] }) })
392
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
393
- /* @__PURE__ */ jsx(Messages, { messages, status, onRetry: handleRetry, onEdit: handleEdit }),
394
- error && /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-4xl px-2 md:px-4", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-destructive/50 bg-destructive/10 px-4 py-2 text-sm text-destructive", children: error.message || "Something went wrong. Please try again." }) }),
395
- /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-4xl px-4 pb-4 md:px-6", children: [
396
- isInteractiveActive && /* @__PURE__ */ jsxs(
397
- "a",
398
- {
399
- href: `/code/${workspaceState?.id}`,
400
- className: "flex items-center justify-center gap-2 rounded-xl border border-primary/20 bg-primary/5 px-4 py-3 mb-2 text-sm font-medium text-primary hover:bg-primary/10 transition-colors",
401
- children: [
402
- /* @__PURE__ */ jsx("span", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse" }),
403
- "Click here to access Interactive Mode"
404
- ]
405
- }
406
- ),
407
- workspaceState && /* @__PURE__ */ jsx("div", { className: "rounded-t-xl border border-b-0 border-border px-3 py-2.5", children: /* @__PURE__ */ jsx(
408
- WorkspaceBar,
409
- {
410
- repo,
411
- branch,
412
- onBranchChange: handleBranchChange,
413
- getBranches: fetchBranches,
414
- workspace: workspaceState,
415
- diffStats,
416
- onDiffStatsRefresh: handleDiffStatsRefresh,
417
- onShowDiff: () => setShowDiff(true)
418
- }
419
- ) }),
420
- /* @__PURE__ */ jsx(
421
- ChatInput,
422
- {
423
- bare: true,
424
- input,
425
- setInput,
426
- onSubmit: handleSend,
427
- status,
428
- stop,
429
- files,
430
- setFiles,
431
- disabled: isInteractiveActive,
432
- placeholder: isInteractiveActive ? "Interactive mode is active." : defaultPlaceholder,
433
- className: workspaceState ? "rounded-t-none" : void 0,
434
- codeMode,
435
- codeModeSettings
436
- }
437
- )
438
- ] })
382
+ /* @__PURE__ */ jsx(
383
+ ChatInput,
384
+ {
385
+ bare: true,
386
+ input,
387
+ setInput,
388
+ onSubmit: handleSend,
389
+ status,
390
+ stop,
391
+ files,
392
+ setFiles,
393
+ disabled: isInteractiveActive,
394
+ placeholder: isInteractiveActive ? "Interactive mode is active." : defaultPlaceholder,
395
+ className: workspaceState ? "rounded-t-none" : void 0,
396
+ codeMode,
397
+ codeModeSettings
398
+ }
399
+ )
439
400
  ] })
440
- ] })
401
+ ] }) })
441
402
  ] });
442
403
  }
443
404
  export {
@@ -409,54 +409,13 @@ export function Chat({ chatId, initialMessages = [], workspace = null, chatMode
409
409
  </div>
410
410
  </div>
411
411
  ) : (
412
- <div className="flex flex-1 flex-col min-h-0 overflow-hidden relative">
413
- {showDiff && workspaceState?.id && (
414
- <div className="absolute inset-0 z-10 bg-black/50" />
415
- )}
412
+ <div className="flex flex-1 flex-col min-h-0 overflow-hidden">
416
413
  {showDiff && workspaceState?.id ? (
417
- <>
418
- <div className="flex-1 min-h-0 z-20 p-0 md:p-4 flex flex-col">
419
- <DiffViewer
420
- workspaceId={workspaceState.id}
421
- diffStats={diffStats}
422
- onClose={() => setShowDiff(false)}
423
- />
424
- </div>
425
- <div className="z-20 px-4 pb-4">
426
- <div className="mx-auto w-full max-w-4xl">
427
- {workspaceState && (
428
- <div className="rounded-t-xl border border-b-0 border-border px-3 py-2.5 bg-background">
429
- <WorkspaceBar
430
- repo={repo}
431
- branch={branch}
432
- onBranchChange={handleBranchChange}
433
- getBranches={fetchBranches}
434
- workspace={workspaceState}
435
- diffStats={diffStats}
436
- onDiffStatsRefresh={handleDiffStatsRefresh}
437
- onShowDiff={() => setShowDiff(true)}
438
- chatMode={codeMode ? 'code' : 'agent'}
439
- />
440
- </div>
441
- )}
442
- <ChatInput
443
- bare
444
- input={input}
445
- setInput={setInput}
446
- onSubmit={handleSend}
447
- status={status}
448
- stop={stop}
449
- files={files}
450
- setFiles={setFiles}
451
- disabled={isInteractiveActive}
452
- placeholder={isInteractiveActive ? 'Interactive mode is active.' : defaultPlaceholder}
453
- className={workspaceState ? "rounded-t-none" : undefined}
454
- codeMode={codeMode}
455
- codeModeSettings={codeModeSettings}
456
- />
457
- </div>
458
- </div>
459
- </>
414
+ <DiffViewer
415
+ workspaceId={workspaceState.id}
416
+ diffStats={diffStats}
417
+ onClose={() => setShowDiff(false)}
418
+ />
460
419
  ) : (
461
420
  <>
462
421
  <Messages messages={messages} status={status} onRetry={handleRetry} onEdit={handleEdit} />
@@ -13,7 +13,7 @@ export { SettingsUsersPage } from './settings-users-page.js';
13
13
  export { HelperLlmPage, ChatConfigPage, ChatProvidersPage, SettingsChatPage } from './settings-chat-page.js';
14
14
  export { ChatProvidersPage as LlmsPage } from './settings-chat-page.js';
15
15
  export { CodingAgentsPage } from './settings-coding-agents-page.js';
16
- export { JobsPage } from './settings-jobs-page.js';
16
+ export { JobsPage, JobSecretsManager } from './settings-jobs-page.js';
17
17
  export { GitHubTokensPage, GitHubSecretsPage, GitHubVariablesPage, SettingsGitHubPage } from './settings-github-page.js';
18
18
  export { SettingsGeneralPage } from './settings-general-page.js';
19
19
  export { ProfileLayout, ProfileLoginPage, ProfileTelegramPage } from './profile-page.js';
@@ -489,7 +489,7 @@ function OAuthSecretRow({ secret, onReauthorize, onDelete }) {
489
489
  ] })
490
490
  ] });
491
491
  }
492
- function JobsPage() {
492
+ function JobSecretsManager({ showHeader = true }) {
493
493
  const [secrets, setSecrets] = useState([]);
494
494
  const [loading, setLoading] = useState(true);
495
495
  const [showAdd, setShowAdd] = useState(false);
@@ -526,7 +526,7 @@ function JobsPage() {
526
526
  return /* @__PURE__ */ jsx("div", { className: "h-48 animate-pulse rounded-md bg-border/50" });
527
527
  }
528
528
  return /* @__PURE__ */ jsxs("div", { children: [
529
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3 mb-4", children: [
529
+ showHeader ? /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3 mb-4", children: [
530
530
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
531
531
  /* @__PURE__ */ jsx("h2", { className: "text-base font-medium", children: "Job Secrets" }),
532
532
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Custom environment variables passed to agent job containers. These are merged with built-in auth credentials when launching jobs." })
@@ -542,7 +542,17 @@ function JobsPage() {
542
542
  ]
543
543
  }
544
544
  ) })
545
- ] }),
545
+ ] }) : /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end mb-4", children: /* @__PURE__ */ jsxs(
546
+ "button",
547
+ {
548
+ onClick: () => setShowAdd(true),
549
+ className: "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium bg-foreground text-background hover:bg-foreground/90 shrink-0 transition-colors",
550
+ children: [
551
+ /* @__PURE__ */ jsx(PlusIcon, { size: 14 }),
552
+ "Add secret"
553
+ ]
554
+ }
555
+ ) }),
546
556
  /* @__PURE__ */ jsx(
547
557
  AddSecretDialog,
548
558
  {
@@ -591,6 +601,10 @@ function JobsPage() {
591
601
  )) }) })
592
602
  ] });
593
603
  }
604
+ function JobsPage() {
605
+ return /* @__PURE__ */ jsx(JobSecretsManager, {});
606
+ }
594
607
  export {
608
+ JobSecretsManager,
595
609
  JobsPage
596
610
  };
@@ -590,7 +590,7 @@ function OAuthSecretRow({ secret, onReauthorize, onDelete }) {
590
590
  // Jobs page
591
591
  // ─────────────────────────────────────────────────────────────────────────────
592
592
 
593
- export function JobsPage() {
593
+ export function JobSecretsManager({ showHeader = true }) {
594
594
  const [secrets, setSecrets] = useState([]);
595
595
  const [loading, setLoading] = useState(true);
596
596
  const [showAdd, setShowAdd] = useState(false);
@@ -635,12 +635,24 @@ export function JobsPage() {
635
635
 
636
636
  return (
637
637
  <div>
638
- <div className="flex items-start justify-between gap-3 mb-4">
639
- <div className="min-w-0">
640
- <h2 className="text-base font-medium">Job Secrets</h2>
641
- <p className="text-sm text-muted-foreground">Custom environment variables passed to agent job containers. These are merged with built-in auth credentials when launching jobs.</p>
638
+ {showHeader ? (
639
+ <div className="flex items-start justify-between gap-3 mb-4">
640
+ <div className="min-w-0">
641
+ <h2 className="text-base font-medium">Job Secrets</h2>
642
+ <p className="text-sm text-muted-foreground">Custom environment variables passed to agent job containers. These are merged with built-in auth credentials when launching jobs.</p>
643
+ </div>
644
+ <div className="flex items-center gap-2 shrink-0 pt-0.5">
645
+ <button
646
+ onClick={() => setShowAdd(true)}
647
+ className="inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium bg-foreground text-background hover:bg-foreground/90 shrink-0 transition-colors"
648
+ >
649
+ <PlusIcon size={14} />
650
+ Add secret
651
+ </button>
652
+ </div>
642
653
  </div>
643
- <div className="flex items-center gap-2 shrink-0 pt-0.5">
654
+ ) : (
655
+ <div className="flex items-center justify-end mb-4">
644
656
  <button
645
657
  onClick={() => setShowAdd(true)}
646
658
  className="inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium bg-foreground text-background hover:bg-foreground/90 shrink-0 transition-colors"
@@ -649,7 +661,7 @@ export function JobsPage() {
649
661
  Add secret
650
662
  </button>
651
663
  </div>
652
- </div>
664
+ )}
653
665
  <AddSecretDialog
654
666
  open={showAdd}
655
667
  onAdd={handleAdd}
@@ -696,3 +708,7 @@ export function JobsPage() {
696
708
  </div>
697
709
  );
698
710
  }
711
+
712
+ export function JobsPage() {
713
+ return <JobSecretsManager />;
714
+ }
@@ -271,7 +271,7 @@ function VariableRow({ name, isSet, currentValue, onUpdate, onDelete }) {
271
271
  ] })
272
272
  ] });
273
273
  }
274
- function Dialog({ open, onClose, title, children }) {
274
+ function Dialog({ open, onClose, title, children, maxWidth = "max-w-md" }) {
275
275
  const ref = useRef(null);
276
276
  useEffect(() => {
277
277
  if (!open) return;
@@ -289,7 +289,7 @@ function Dialog({ open, onClose, title, children }) {
289
289
  "div",
290
290
  {
291
291
  ref,
292
- className: "relative z-50 w-full max-w-md mx-4 rounded-lg border border-border bg-background p-6 shadow-lg",
292
+ className: `relative z-50 w-full ${maxWidth} mx-4 rounded-lg border border-border bg-background p-6 shadow-lg max-h-[90vh] overflow-y-auto`,
293
293
  onClick: (e) => e.stopPropagation(),
294
294
  children: [
295
295
  /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold mb-4", children: title }),
@@ -289,7 +289,7 @@ export function VariableRow({ name, isSet, currentValue, onUpdate, onDelete }) {
289
289
  // Dialog — standardized modal
290
290
  // ─────────────────────────────────────────────────────────────────────────────
291
291
 
292
- export function Dialog({ open, onClose, title, children }) {
292
+ export function Dialog({ open, onClose, title, children, maxWidth = 'max-w-md' }) {
293
293
  const ref = useRef(null);
294
294
 
295
295
  useEffect(() => {
@@ -306,7 +306,7 @@ export function Dialog({ open, onClose, title, children }) {
306
306
  <div className="fixed inset-0 bg-black/50" onClick={onClose} />
307
307
  <div
308
308
  ref={ref}
309
- className="relative z-50 w-full max-w-md mx-4 rounded-lg border border-border bg-background p-6 shadow-lg"
309
+ className={`relative z-50 w-full ${maxWidth} mx-4 rounded-lg border border-border bg-background p-6 shadow-lg max-h-[90vh] overflow-y-auto`}
310
310
  onClick={(e) => e.stopPropagation()}
311
311
  >
312
312
  <h3 className="text-base font-semibold mb-4">{title}</h3>
@@ -266,7 +266,7 @@ function CodePage({ session, codeWorkspaceId }) {
266
266
  /* @__PURE__ */ jsxs(SidebarInset, { children: [
267
267
  /* @__PURE__ */ jsxs("div", { className: "flex h-svh flex-col overflow-hidden", children: [
268
268
  /* @__PURE__ */ jsx(ChatHeader, { workspaceId: codeWorkspaceId }),
269
- /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-0 px-4 bg-muted/30 border-b border-border shrink-0 overflow-x-auto scrollbar-hide", children: [
269
+ !showDiff && /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-0 px-4 bg-muted/30 border-b border-border shrink-0 overflow-x-auto scrollbar-hide", children: [
270
270
  /* @__PURE__ */ jsx(
271
271
  PinnedTab,
272
272
  {
@@ -310,7 +310,8 @@ export default function CodePage({ session, codeWorkspaceId }) {
310
310
  <div className="flex h-svh flex-col overflow-hidden">
311
311
  <ChatHeader workspaceId={codeWorkspaceId} />
312
312
 
313
- {/* Tab bar */}
313
+ {/* Tab bar — hidden while diff viewer is open so it fills the content area */}
314
+ {!showDiff && (
314
315
  <div className="flex items-end gap-0 px-4 bg-muted/30 border-b border-border shrink-0 overflow-x-auto scrollbar-hide">
315
316
  {/* Primary Code tab — pinned, not draggable */}
316
317
  <PinnedTab
@@ -429,6 +430,7 @@ export default function CodePage({ session, codeWorkspaceId }) {
429
430
  + Port
430
431
  </button>
431
432
  </div>
433
+ )}
432
434
 
433
435
  {/* Tab content panels — all mounted, hidden via display */}
434
436
  <div style={{ position: 'relative', flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }}>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thepopebot",
3
- "version": "1.2.76-beta.26",
3
+ "version": "1.2.76-beta.27",
4
4
  "type": "module",
5
5
  "description": "Create autonomous AI agents with a two-layer architecture: Next.js Event Handler + Docker Agent.",
6
6
  "bin": {