thepopebot 1.2.76-beta.2 → 1.2.76-beta.21

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.
Files changed (128) hide show
  1. package/README.md +3 -3
  2. package/api/CLAUDE.md +11 -4
  3. package/api/index.js +56 -18
  4. package/bin/CLAUDE.md +7 -4
  5. package/bin/cli.js +25 -45
  6. package/config/CLAUDE.md +23 -4
  7. package/drizzle/0021_coding_agent_workspace.sql +1 -0
  8. package/drizzle/0022_organic_apocalypse.sql +16 -0
  9. package/drizzle/0023_needy_ender_wiggin.sql +1 -0
  10. package/drizzle/meta/0021_snapshot.json +639 -0
  11. package/drizzle/meta/0022_snapshot.json +743 -0
  12. package/drizzle/meta/0023_snapshot.json +750 -0
  13. package/drizzle/meta/_journal.json +21 -0
  14. package/lib/CLAUDE.md +2 -2
  15. package/lib/actions.js +9 -1
  16. package/lib/ai/CLAUDE.md +72 -57
  17. package/lib/ai/helper-llm.js +108 -0
  18. package/lib/ai/index.js +308 -438
  19. package/lib/ai/line-mappers.js +42 -24
  20. package/lib/ai/scope.js +26 -0
  21. package/lib/ai/sdk-adapters/CLAUDE.md +114 -0
  22. package/lib/ai/sdk-adapters/claude-code.js +120 -8
  23. package/lib/ai/system-prompt.js +34 -0
  24. package/lib/ai/workspace-setup.js +19 -35
  25. package/lib/channels/CLAUDE.md +14 -4
  26. package/lib/channels/base.js +6 -2
  27. package/lib/channels/commands/index.js +42 -0
  28. package/lib/channels/commands/session.js +53 -0
  29. package/lib/channels/commands/verify.js +18 -0
  30. package/lib/channels/telegram.js +79 -28
  31. package/lib/chat/CLAUDE.md +4 -4
  32. package/lib/chat/actions.js +270 -49
  33. package/lib/chat/api.js +185 -31
  34. package/lib/chat/components/CLAUDE.md +6 -2
  35. package/lib/chat/components/chat-input.js +77 -47
  36. package/lib/chat/components/chat-input.jsx +77 -40
  37. package/lib/chat/components/chat-page.js +2 -0
  38. package/lib/chat/components/chat-page.jsx +3 -0
  39. package/lib/chat/components/chat.js +62 -14
  40. package/lib/chat/components/chat.jsx +68 -10
  41. package/lib/chat/components/code-mode-toggle.js +141 -22
  42. package/lib/chat/components/code-mode-toggle.jsx +129 -20
  43. package/lib/chat/components/containers-page.js +58 -40
  44. package/lib/chat/components/containers-page.jsx +64 -25
  45. package/lib/chat/components/crons-page.js +17 -3
  46. package/lib/chat/components/crons-page.jsx +34 -6
  47. package/lib/chat/components/index.js +2 -2
  48. package/lib/chat/components/message.js +18 -3
  49. package/lib/chat/components/message.jsx +18 -3
  50. package/lib/chat/components/profile-page.js +182 -4
  51. package/lib/chat/components/profile-page.jsx +196 -1
  52. package/lib/chat/components/scope-picker.js +21 -0
  53. package/lib/chat/components/scope-picker.jsx +27 -0
  54. package/lib/chat/components/settings-chat-page.js +11 -11
  55. package/lib/chat/components/settings-chat-page.jsx +14 -18
  56. package/lib/chat/components/settings-coding-agents-page.js +110 -16
  57. package/lib/chat/components/settings-coding-agents-page.jsx +87 -3
  58. package/lib/chat/components/settings-github-page.js +5 -0
  59. package/lib/chat/components/settings-github-page.jsx +5 -0
  60. package/lib/chat/components/settings-layout.js +3 -3
  61. package/lib/chat/components/settings-layout.jsx +3 -3
  62. package/lib/chat/components/settings-secrets-layout.js +1 -2
  63. package/lib/chat/components/settings-secrets-layout.jsx +1 -2
  64. package/lib/chat/components/settings-secrets-page.js +180 -75
  65. package/lib/chat/components/settings-secrets-page.jsx +212 -66
  66. package/lib/chat/components/triggers-page.js +17 -3
  67. package/lib/chat/components/triggers-page.jsx +34 -6
  68. package/lib/chat/components/ui/combobox.js +18 -2
  69. package/lib/chat/components/ui/combobox.jsx +17 -1
  70. package/lib/chat/components/ui/dropdown-menu.js +23 -2
  71. package/lib/chat/components/ui/dropdown-menu.jsx +27 -2
  72. package/lib/chat/telegram-profile.js +33 -0
  73. package/lib/cluster/CLAUDE.md +9 -3
  74. package/lib/code/CLAUDE.md +11 -3
  75. package/lib/code/actions.js +47 -8
  76. package/lib/code/terminal-view.js +31 -21
  77. package/lib/code/terminal-view.jsx +32 -23
  78. package/lib/config.js +15 -4
  79. package/lib/containers/CLAUDE.md +16 -6
  80. package/lib/db/CLAUDE.md +5 -2
  81. package/lib/db/chats.js +9 -17
  82. package/lib/db/code-workspaces.js +8 -3
  83. package/lib/db/config.js +0 -1
  84. package/lib/db/index.js +12 -0
  85. package/lib/db/schema.js +24 -1
  86. package/lib/db/user-channels.js +129 -0
  87. package/lib/llm-providers.js +8 -0
  88. package/lib/maintenance.js +31 -21
  89. package/lib/tools/CLAUDE.md +12 -3
  90. package/lib/tools/assemblyai.js +17 -0
  91. package/lib/tools/create-agent-job.js +12 -8
  92. package/lib/tools/docker.js +34 -10
  93. package/lib/tools/github.js +34 -0
  94. package/lib/tools/telegram.js +106 -0
  95. package/lib/utils/render-md.js +44 -18
  96. package/package.json +8 -8
  97. package/setup/CLAUDE.md +11 -5
  98. package/setup/lib/providers.mjs +2 -1
  99. package/setup/lib/targets.mjs +13 -16
  100. package/setup/lib/telegram.mjs +8 -69
  101. package/templates/.env.example +0 -7
  102. package/templates/.github/workflows/rebuild-event-handler.yml +1 -1
  103. package/templates/.gitignore.template +1 -3
  104. package/templates/CLAUDE.md +1 -1
  105. package/templates/CLAUDE.md.template +29 -7
  106. package/templates/agent-job/CLAUDE.md.template +5 -3
  107. package/templates/agent-job/CRONS.json +16 -0
  108. package/templates/agent-job/SYSTEM.md +16 -11
  109. package/templates/agents/CLAUDE.md.template +17 -17
  110. package/templates/coding-workspace/CLAUDE.md.template +7 -0
  111. package/templates/data/CLAUDE.md.template +1 -1
  112. package/templates/docker-compose.custom.yml +1 -0
  113. package/templates/docker-compose.yml +1 -0
  114. package/templates/event-handler/CLAUDE.md.template +79 -0
  115. package/templates/event-handler/TRIGGERS.json +18 -2
  116. package/templates/skills/CLAUDE.md.template +20 -22
  117. package/templates/skills/{library/agent-job-secrets → agent-job-secrets}/SKILL.md +2 -2
  118. package/lib/ai/agent.js +0 -65
  119. package/lib/ai/async-channel.js +0 -51
  120. package/lib/ai/model.js +0 -130
  121. package/lib/ai/tools.js +0 -164
  122. package/lib/tools/openai.js +0 -37
  123. package/setup/lib/telegram-verify.mjs +0 -63
  124. package/setup/setup-telegram.mjs +0 -260
  125. package/templates/agent-job/SOUL.md +0 -17
  126. /package/templates/{skills/active/.gitkeep → coding-workspace/SYSTEM.md} +0 -0
  127. /package/templates/skills/{library/agent-job-secrets → agent-job-secrets}/agent-job-secrets.js +0 -0
  128. /package/templates/skills/{library/playwright-cli → playwright-cli}/SKILL.md +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  getOAuthTokens,
15
15
  deleteOAuthToken
16
16
  } from "../actions.js";
17
- function ChatConfigPage() {
17
+ function HelperLlmPage() {
18
18
  const [settings, setSettings] = useState(null);
19
19
  const [loading, setLoading] = useState(true);
20
20
  const loadSettings = async () => {
@@ -40,20 +40,19 @@ function ChatConfigPage() {
40
40
  if (settings?.error) {
41
41
  return /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: settings.error });
42
42
  }
43
- const sdkAgentActive = settings?.sdkAgentActive;
44
- const defaultAgent = settings?.defaultAgent;
45
43
  return /* @__PURE__ */ jsxs("div", { children: [
46
- sdkAgentActive && /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 px-4 py-3 mb-4", children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive", children: [
47
- defaultAgent,
48
- " manages its own LLM directly. These settings only apply when using a coding agent without built-in SDK support."
49
- ] }) }),
50
44
  /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
51
- /* @__PURE__ */ jsx("h2", { className: "text-base font-medium", children: "Configuration" }),
52
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Select the LLM provider and model for chat. Only providers with configured API keys appear in the dropdown." })
45
+ /* @__PURE__ */ jsx("h2", { className: "text-base font-medium", children: "Helper LLM" }),
46
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
47
+ "Used for chat titles, agent-job titles, and agent-job summaries. Independent of your coding agent. Only providers with configured API keys appear in the dropdown \u2014 set keys at ",
48
+ /* @__PURE__ */ jsx("a", { href: "/admin/event-handler/llms", className: "underline hover:text-foreground", children: "Providers" }),
49
+ "."
50
+ ] })
53
51
  ] }),
54
- /* @__PURE__ */ jsx("div", { className: sdkAgentActive ? "opacity-50 pointer-events-none" : "", children: /* @__PURE__ */ jsx(ActiveConfig, { settings, onSave: handleSaveActive }) })
52
+ /* @__PURE__ */ jsx(ActiveConfig, { settings, onSave: handleSaveActive })
55
53
  ] });
56
54
  }
55
+ const ChatConfigPage = HelperLlmPage;
57
56
  function ActiveConfig({ settings, onSave }) {
58
57
  const [provider, setProvider] = useState("");
59
58
  const [model, setModel] = useState("");
@@ -738,10 +737,11 @@ function CustomProviderDialog({ open, initial, onSave, onCancel }) {
738
737
  ] });
739
738
  }
740
739
  function SettingsChatPage() {
741
- return /* @__PURE__ */ jsx(ChatConfigPage, {});
740
+ return /* @__PURE__ */ jsx(HelperLlmPage, {});
742
741
  }
743
742
  export {
744
743
  ChatConfigPage,
745
744
  ChatProvidersPage,
745
+ HelperLlmPage,
746
746
  SettingsChatPage
747
747
  };
@@ -16,10 +16,14 @@ import {
16
16
  } from '../actions.js';
17
17
 
18
18
  // ─────────────────────────────────────────────────────────────────────────────
19
- // Configuration sub-tab (auto-save)
19
+ // Helper LLM page (auto-save)
20
+ //
21
+ // Picks the provider + model used for short background generations: chat
22
+ // titles, agent-job titles, and agent-job summaries. Independent of the
23
+ // coding agent. Credentials live at /admin/event-handler/llms.
20
24
  // ─────────────────────────────────────────────────────────────────────────────
21
25
 
22
- export function ChatConfigPage() {
26
+ export function HelperLlmPage() {
23
27
  const [settings, setSettings] = useState(null);
24
28
  const [loading, setLoading] = useState(true);
25
29
 
@@ -52,29 +56,21 @@ export function ChatConfigPage() {
52
56
  return <p className="text-sm text-destructive">{settings.error}</p>;
53
57
  }
54
58
 
55
- const sdkAgentActive = settings?.sdkAgentActive;
56
- const defaultAgent = settings?.defaultAgent;
57
-
58
59
  return (
59
60
  <div>
60
- {sdkAgentActive && (
61
- <div className="rounded-lg border border-destructive/30 bg-destructive/5 px-4 py-3 mb-4">
62
- <p className="text-sm text-destructive">
63
- {defaultAgent} manages its own LLM directly. These settings only apply when using a coding agent without built-in SDK support.
64
- </p>
65
- </div>
66
- )}
67
61
  <div className="mb-4">
68
- <h2 className="text-base font-medium">Configuration</h2>
69
- <p className="text-sm text-muted-foreground">Select the LLM provider and model for chat. Only providers with configured API keys appear in the dropdown.</p>
70
- </div>
71
- <div className={sdkAgentActive ? 'opacity-50 pointer-events-none' : ''}>
72
- <ActiveConfig settings={settings} onSave={handleSaveActive} />
62
+ <h2 className="text-base font-medium">Helper LLM</h2>
63
+ <p className="text-sm text-muted-foreground">Used for chat titles, agent-job titles, and agent-job summaries. Independent of your coding agent. Only providers with configured API keys appear in the dropdown — set keys at <a href="/admin/event-handler/llms" className="underline hover:text-foreground">Providers</a>.</p>
73
64
  </div>
65
+ <ActiveConfig settings={settings} onSave={handleSaveActive} />
74
66
  </div>
75
67
  );
76
68
  }
77
69
 
70
+ // Backwards-compat alias — kept so route files importing the old name keep working
71
+ // during the route move.
72
+ export const ChatConfigPage = HelperLlmPage;
73
+
78
74
  function ActiveConfig({ settings, onSave }) {
79
75
  const [provider, setProvider] = useState('');
80
76
  const [model, setModel] = useState('');
@@ -777,5 +773,5 @@ function CustomProviderDialog({ open, initial, onSave, onCancel }) {
777
773
 
778
774
  // Backwards compat
779
775
  export function SettingsChatPage() {
780
- return <ChatConfigPage />;
776
+ return <HelperLlmPage />;
781
777
  }
@@ -5,7 +5,8 @@ import { CheckIcon } from "./icons.js";
5
5
  import {
6
6
  getCodingAgentSettings,
7
7
  updateCodingAgentConfig,
8
- setCodingAgentDefault
8
+ setCodingAgentDefault,
9
+ setModeDefault
9
10
  } from "../actions.js";
10
11
  function CodingAgentsPage() {
11
12
  const [settings, setSettings] = useState(null);
@@ -67,28 +68,121 @@ function DefaultAgentSection({ settings, onReload }) {
67
68
  };
68
69
  return /* @__PURE__ */ jsxs("div", { children: [
69
70
  /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
70
- /* @__PURE__ */ jsx("h2", { className: "text-base font-medium", children: "Default Coding Agent" }),
71
+ /* @__PURE__ */ jsx("h2", { className: "text-base font-medium", children: "Coding Agent" }),
71
72
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Select which coding agent runs headless tasks and code workspaces." })
72
73
  ] }),
73
- /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
74
- /* @__PURE__ */ jsx("label", { className: "text-sm font-medium shrink-0", children: "Agent" }),
75
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
76
- saving && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Saving..." }),
77
- saved && /* @__PURE__ */ jsxs("span", { className: "text-xs text-green-500 inline-flex items-center gap-1", children: [
78
- /* @__PURE__ */ jsx(CheckIcon, { size: 12 }),
79
- " Saved"
80
- ] }),
74
+ /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card p-4 space-y-3", children: [
75
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
76
+ /* @__PURE__ */ jsx("label", { className: "text-sm font-medium shrink-0", children: "Default Coding Agent" }),
77
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
78
+ saving && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Saving..." }),
79
+ saved && /* @__PURE__ */ jsxs("span", { className: "text-xs text-green-500 inline-flex items-center gap-1", children: [
80
+ /* @__PURE__ */ jsx(CheckIcon, { size: 12 }),
81
+ " Saved"
82
+ ] }),
83
+ /* @__PURE__ */ jsx(
84
+ "select",
85
+ {
86
+ value: settings.defaultAgent || "claude-code",
87
+ onChange: handleChange,
88
+ className: "w-48 rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground",
89
+ children: available.length > 0 ? available.map((a) => /* @__PURE__ */ jsx("option", { value: a.value, children: a.label }, a.value)) : /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "No agents ready" })
90
+ }
91
+ )
92
+ ] })
93
+ ] }),
94
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-border pt-3 space-y-3", children: [
81
95
  /* @__PURE__ */ jsx(
82
- "select",
96
+ ModeDefaultRow,
83
97
  {
84
- value: settings.defaultAgent || "claude-code",
85
- onChange: handleChange,
86
- className: "w-48 rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground",
87
- children: available.length > 0 ? available.map((a) => /* @__PURE__ */ jsx("option", { value: a.value, children: a.label }, a.value)) : /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "No agents ready" })
98
+ label: "Agent mode branch",
99
+ mode: "agent",
100
+ field: "branch",
101
+ value: settings.modeDefaults?.agent?.branch || "default",
102
+ options: BRANCH_OPTIONS,
103
+ onSaved: onReload
104
+ }
105
+ ),
106
+ /* @__PURE__ */ jsx(
107
+ ModeDefaultRow,
108
+ {
109
+ label: "Agent mode git action",
110
+ mode: "agent",
111
+ field: "gitAction",
112
+ value: settings.modeDefaults?.agent?.gitAction || "push",
113
+ options: GIT_ACTION_OPTIONS,
114
+ onSaved: onReload
115
+ }
116
+ )
117
+ ] }),
118
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-border pt-3 space-y-3", children: [
119
+ /* @__PURE__ */ jsx(
120
+ ModeDefaultRow,
121
+ {
122
+ label: "Code mode branch",
123
+ mode: "code",
124
+ field: "branch",
125
+ value: settings.modeDefaults?.code?.branch || "dynamic",
126
+ options: BRANCH_OPTIONS,
127
+ onSaved: onReload
128
+ }
129
+ ),
130
+ /* @__PURE__ */ jsx(
131
+ ModeDefaultRow,
132
+ {
133
+ label: "Code mode git action",
134
+ mode: "code",
135
+ field: "gitAction",
136
+ value: settings.modeDefaults?.code?.gitAction || "create-pr",
137
+ options: GIT_ACTION_OPTIONS,
138
+ onSaved: onReload
88
139
  }
89
140
  )
90
141
  ] })
91
- ] }) })
142
+ ] })
143
+ ] });
144
+ }
145
+ const BRANCH_OPTIONS = [
146
+ { value: "default", label: "Default branch" },
147
+ { value: "dynamic", label: "Feature branch" }
148
+ ];
149
+ const GIT_ACTION_OPTIONS = [
150
+ { value: "commit", label: "Commit" },
151
+ { value: "push", label: "Push" },
152
+ { value: "create-pr", label: "Create PR" },
153
+ { value: "pull", label: "Pull" }
154
+ ];
155
+ function ModeDefaultRow({ label, mode, field, value, options, onSaved }) {
156
+ const [saving, setSaving] = useState(false);
157
+ const [saved, setSaved] = useState(false);
158
+ const handleChange = async (e) => {
159
+ setSaving(true);
160
+ const result = await setModeDefault(mode, field, e.target.value);
161
+ setSaving(false);
162
+ if (result?.success) {
163
+ setSaved(true);
164
+ setTimeout(() => setSaved(false), 2e3);
165
+ await onSaved();
166
+ }
167
+ };
168
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
169
+ /* @__PURE__ */ jsx("label", { className: "text-sm font-medium shrink-0", children: label }),
170
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
171
+ saving && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Saving..." }),
172
+ saved && /* @__PURE__ */ jsxs("span", { className: "text-xs text-green-500 inline-flex items-center gap-1", children: [
173
+ /* @__PURE__ */ jsx(CheckIcon, { size: 12 }),
174
+ " Saved"
175
+ ] }),
176
+ /* @__PURE__ */ jsx(
177
+ "select",
178
+ {
179
+ value,
180
+ onChange: handleChange,
181
+ className: "w-48 rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground",
182
+ children: options.map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value))
183
+ }
184
+ )
185
+ ] })
92
186
  ] });
93
187
  }
94
188
  function AgentCards({ settings, onReload }) {
@@ -6,6 +6,7 @@ import {
6
6
  getCodingAgentSettings,
7
7
  updateCodingAgentConfig,
8
8
  setCodingAgentDefault,
9
+ setModeDefault,
9
10
  } from '../actions.js';
10
11
 
11
12
  // ─────────────────────────────────────────────────────────────────────────────
@@ -90,12 +91,12 @@ function DefaultAgentSection({ settings, onReload }) {
90
91
  return (
91
92
  <div>
92
93
  <div className="mb-4">
93
- <h2 className="text-base font-medium">Default Coding Agent</h2>
94
+ <h2 className="text-base font-medium">Coding Agent</h2>
94
95
  <p className="text-sm text-muted-foreground">Select which coding agent runs headless tasks and code workspaces.</p>
95
96
  </div>
96
- <div className="rounded-lg border bg-card p-4">
97
+ <div className="rounded-lg border bg-card p-4 space-y-3">
97
98
  <div className="flex items-center justify-between">
98
- <label className="text-sm font-medium shrink-0">Agent</label>
99
+ <label className="text-sm font-medium shrink-0">Default Coding Agent</label>
99
100
  <div className="flex items-center gap-3">
100
101
  {saving && <span className="text-xs text-muted-foreground">Saving...</span>}
101
102
  {saved && <span className="text-xs text-green-500 inline-flex items-center gap-1"><CheckIcon size={12} /> Saved</span>}
@@ -114,6 +115,89 @@ function DefaultAgentSection({ settings, onReload }) {
114
115
  </select>
115
116
  </div>
116
117
  </div>
118
+ <div className="border-t border-border pt-3 space-y-3">
119
+ <ModeDefaultRow
120
+ label="Agent mode branch"
121
+ mode="agent"
122
+ field="branch"
123
+ value={settings.modeDefaults?.agent?.branch || 'default'}
124
+ options={BRANCH_OPTIONS}
125
+ onSaved={onReload}
126
+ />
127
+ <ModeDefaultRow
128
+ label="Agent mode git action"
129
+ mode="agent"
130
+ field="gitAction"
131
+ value={settings.modeDefaults?.agent?.gitAction || 'push'}
132
+ options={GIT_ACTION_OPTIONS}
133
+ onSaved={onReload}
134
+ />
135
+ </div>
136
+ <div className="border-t border-border pt-3 space-y-3">
137
+ <ModeDefaultRow
138
+ label="Code mode branch"
139
+ mode="code"
140
+ field="branch"
141
+ value={settings.modeDefaults?.code?.branch || 'dynamic'}
142
+ options={BRANCH_OPTIONS}
143
+ onSaved={onReload}
144
+ />
145
+ <ModeDefaultRow
146
+ label="Code mode git action"
147
+ mode="code"
148
+ field="gitAction"
149
+ value={settings.modeDefaults?.code?.gitAction || 'create-pr'}
150
+ options={GIT_ACTION_OPTIONS}
151
+ onSaved={onReload}
152
+ />
153
+ </div>
154
+ </div>
155
+ </div>
156
+ );
157
+ }
158
+
159
+ const BRANCH_OPTIONS = [
160
+ { value: 'default', label: 'Default branch' },
161
+ { value: 'dynamic', label: 'Feature branch' },
162
+ ];
163
+
164
+ const GIT_ACTION_OPTIONS = [
165
+ { value: 'commit', label: 'Commit' },
166
+ { value: 'push', label: 'Push' },
167
+ { value: 'create-pr', label: 'Create PR' },
168
+ { value: 'pull', label: 'Pull' },
169
+ ];
170
+
171
+ function ModeDefaultRow({ label, mode, field, value, options, onSaved }) {
172
+ const [saving, setSaving] = useState(false);
173
+ const [saved, setSaved] = useState(false);
174
+
175
+ const handleChange = async (e) => {
176
+ setSaving(true);
177
+ const result = await setModeDefault(mode, field, e.target.value);
178
+ setSaving(false);
179
+ if (result?.success) {
180
+ setSaved(true);
181
+ setTimeout(() => setSaved(false), 2000);
182
+ await onSaved();
183
+ }
184
+ };
185
+
186
+ return (
187
+ <div className="flex items-center justify-between">
188
+ <label className="text-sm font-medium shrink-0">{label}</label>
189
+ <div className="flex items-center gap-3">
190
+ {saving && <span className="text-xs text-muted-foreground">Saving...</span>}
191
+ {saved && <span className="text-xs text-green-500 inline-flex items-center gap-1"><CheckIcon size={12} /> Saved</span>}
192
+ <select
193
+ value={value}
194
+ onChange={handleChange}
195
+ className="w-48 rounded-md border border-border bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-foreground"
196
+ >
197
+ {options.map((o) => (
198
+ <option key={o.value} value={o.value}>{o.label}</option>
199
+ ))}
200
+ </select>
117
201
  </div>
118
202
  </div>
119
203
  );
@@ -354,6 +354,11 @@ function GitHubVariablesPage() {
354
354
  onCancel: () => setShowAdd(false)
355
355
  }
356
356
  ),
357
+ data.variablesError && /* @__PURE__ */ jsxs("div", { className: "mb-4 rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: [
358
+ "Couldn't read GitHub variables: ",
359
+ data.variablesError,
360
+ ". Statuses below may be inaccurate. Check that the GitHub PAT has Variables: Read scope."
361
+ ] }),
357
362
  /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-card p-4", children: /* @__PURE__ */ jsx("div", { className: "divide-y divide-border", children: data.variables.map((v) => /* @__PURE__ */ jsx(VariableRow, { name: v.name, isSet: v.isSet, currentValue: v.value, onUpdate: handleUpdate, onDelete: handleDelete }, v.name)) }) })
358
363
  ] });
359
364
  }
@@ -389,6 +389,11 @@ export function GitHubVariablesPage() {
389
389
  onAdd={handleUpdate}
390
390
  onCancel={() => setShowAdd(false)}
391
391
  />
392
+ {data.variablesError && (
393
+ <div className="mb-4 rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-xs text-destructive">
394
+ Couldn't read GitHub variables: {data.variablesError}. Statuses below may be inaccurate. Check that the GitHub PAT has Variables: Read scope.
395
+ </div>
396
+ )}
392
397
  <div className="rounded-lg border bg-card p-4">
393
398
  <div className="divide-y divide-border">
394
399
  {data.variables.map((v) => (
@@ -4,12 +4,12 @@ import { useState, useEffect } from "react";
4
4
  import { PageLayout } from "./page-layout.js";
5
5
  import { UserIcon, ClockIcon, ZapIcon, MessageIcon, GitBranchIcon, SettingsIcon } from "./icons.js";
6
6
  const TABS = [
7
+ { id: "general", label: "General", href: "/admin/general", icon: SettingsIcon },
7
8
  { id: "event-handler", label: "Event Handler", href: "/admin/event-handler", icon: MessageIcon },
8
- { id: "github", label: "GitHub", href: "/admin/github", icon: GitBranchIcon },
9
- { id: "users", label: "Users", href: "/admin/users", icon: UserIcon },
10
9
  { id: "crons", label: "Crons", href: "/admin/crons", icon: ClockIcon },
11
10
  { id: "triggers", label: "Triggers", href: "/admin/triggers", icon: ZapIcon },
12
- { id: "general", label: "General", href: "/admin/general", icon: SettingsIcon }
11
+ { id: "users", label: "Users", href: "/admin/users", icon: UserIcon },
12
+ { id: "github", label: "GitHub", href: "/admin/github", icon: GitBranchIcon }
13
13
  ];
14
14
  function SettingsLayout({ session, children }) {
15
15
  const [activePath, setActivePath] = useState("");
@@ -5,12 +5,12 @@ import { PageLayout } from './page-layout.js';
5
5
  import { UserIcon, ClockIcon, ZapIcon, MessageIcon, GitBranchIcon, SettingsIcon } from './icons.js';
6
6
 
7
7
  const TABS = [
8
+ { id: 'general', label: 'General', href: '/admin/general', icon: SettingsIcon },
8
9
  { id: 'event-handler', label: 'Event Handler', href: '/admin/event-handler', icon: MessageIcon },
9
- { id: 'github', label: 'GitHub', href: '/admin/github', icon: GitBranchIcon },
10
- { id: 'users', label: 'Users', href: '/admin/users', icon: UserIcon },
11
10
  { id: 'crons', label: 'Crons', href: '/admin/crons', icon: ClockIcon },
12
11
  { id: 'triggers', label: 'Triggers', href: '/admin/triggers', icon: ZapIcon },
13
- { id: 'general', label: 'General', href: '/admin/general', icon: SettingsIcon },
12
+ { id: 'users', label: 'Users', href: '/admin/users', icon: UserIcon },
13
+ { id: 'github', label: 'GitHub', href: '/admin/github', icon: GitBranchIcon },
14
14
  ];
15
15
 
16
16
  export function SettingsLayout({ session, children }) {
@@ -29,7 +29,7 @@ const API_KEYS_TABS = [
29
29
  const EVENT_HANDLER_TABS = [
30
30
  { id: "llms", label: "LLMs", href: "/admin/event-handler/llms" },
31
31
  { id: "coding-agents", label: "Coding Agents", href: "/admin/event-handler/coding-agents" },
32
- { id: "chat", label: "Chat", href: "/admin/event-handler/chat" },
32
+ { id: "helper-llm", label: "Helper LLM", href: "/admin/event-handler/helper-llm" },
33
33
  { id: "agent-secrets", label: "Agent Secrets", href: "/admin/event-handler/agent-secrets" },
34
34
  { id: "webhooks", label: "Webhooks", href: "/admin/event-handler/webhooks" },
35
35
  { id: "telegram", label: "Telegram", href: "/admin/event-handler/telegram" },
@@ -37,7 +37,6 @@ const EVENT_HANDLER_TABS = [
37
37
  ];
38
38
  const GITHUB_TABS = [
39
39
  { id: "tokens", label: "Tokens", href: "/admin/github/tokens" },
40
- { id: "secrets", label: "Secrets", href: "/admin/github/secrets" },
41
40
  { id: "variables", label: "Variables", href: "/admin/github/variables" }
42
41
  ];
43
42
  function ApiKeysLayout({ children }) {
@@ -51,7 +51,7 @@ const API_KEYS_TABS = [
51
51
  const EVENT_HANDLER_TABS = [
52
52
  { id: 'llms', label: 'LLMs', href: '/admin/event-handler/llms' },
53
53
  { id: 'coding-agents', label: 'Coding Agents', href: '/admin/event-handler/coding-agents' },
54
- { id: 'chat', label: 'Chat', href: '/admin/event-handler/chat' },
54
+ { id: 'helper-llm', label: 'Helper LLM', href: '/admin/event-handler/helper-llm' },
55
55
  { id: 'agent-secrets', label: 'Agent Secrets', href: '/admin/event-handler/agent-secrets' },
56
56
  { id: 'webhooks', label: 'Webhooks', href: '/admin/event-handler/webhooks' },
57
57
  { id: 'telegram', label: 'Telegram', href: '/admin/event-handler/telegram' },
@@ -60,7 +60,6 @@ const EVENT_HANDLER_TABS = [
60
60
 
61
61
  const GITHUB_TABS = [
62
62
  { id: 'tokens', label: 'Tokens', href: '/admin/github/tokens' },
63
- { id: 'secrets', label: 'Secrets', href: '/admin/github/secrets' },
64
63
  { id: 'variables', label: 'Variables', href: '/admin/github/variables' },
65
64
  ];
66
65