codex-autorunner 0.1.2__py3-none-any.whl → 1.1.0__py3-none-any.whl
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.
- codex_autorunner/__init__.py +12 -1
- codex_autorunner/__main__.py +4 -0
- codex_autorunner/agents/codex/harness.py +1 -1
- codex_autorunner/agents/opencode/client.py +68 -35
- codex_autorunner/agents/opencode/constants.py +3 -0
- codex_autorunner/agents/opencode/harness.py +6 -1
- codex_autorunner/agents/opencode/logging.py +21 -5
- codex_autorunner/agents/opencode/run_prompt.py +1 -0
- codex_autorunner/agents/opencode/runtime.py +176 -47
- codex_autorunner/agents/opencode/supervisor.py +36 -48
- codex_autorunner/agents/registry.py +155 -8
- codex_autorunner/api.py +25 -0
- codex_autorunner/bootstrap.py +22 -37
- codex_autorunner/cli.py +5 -1156
- codex_autorunner/codex_cli.py +20 -84
- codex_autorunner/core/__init__.py +4 -0
- codex_autorunner/core/about_car.py +49 -32
- codex_autorunner/core/adapter_utils.py +21 -0
- codex_autorunner/core/app_server_ids.py +59 -0
- codex_autorunner/core/app_server_logging.py +7 -3
- codex_autorunner/core/app_server_prompts.py +27 -260
- codex_autorunner/core/app_server_threads.py +26 -28
- codex_autorunner/core/app_server_utils.py +165 -0
- codex_autorunner/core/archive.py +349 -0
- codex_autorunner/core/codex_runner.py +12 -2
- codex_autorunner/core/config.py +587 -103
- codex_autorunner/core/docs.py +10 -2
- codex_autorunner/core/drafts.py +136 -0
- codex_autorunner/core/engine.py +1531 -866
- codex_autorunner/core/exceptions.py +4 -0
- codex_autorunner/core/flows/__init__.py +25 -0
- codex_autorunner/core/flows/controller.py +202 -0
- codex_autorunner/core/flows/definition.py +82 -0
- codex_autorunner/core/flows/models.py +88 -0
- codex_autorunner/core/flows/reasons.py +52 -0
- codex_autorunner/core/flows/reconciler.py +131 -0
- codex_autorunner/core/flows/runtime.py +382 -0
- codex_autorunner/core/flows/store.py +568 -0
- codex_autorunner/core/flows/transition.py +138 -0
- codex_autorunner/core/flows/ux_helpers.py +257 -0
- codex_autorunner/core/flows/worker_process.py +242 -0
- codex_autorunner/core/git_utils.py +62 -0
- codex_autorunner/core/hub.py +136 -16
- codex_autorunner/core/locks.py +4 -0
- codex_autorunner/core/notifications.py +14 -2
- codex_autorunner/core/ports/__init__.py +28 -0
- codex_autorunner/core/ports/agent_backend.py +150 -0
- codex_autorunner/core/ports/backend_orchestrator.py +41 -0
- codex_autorunner/core/ports/run_event.py +91 -0
- codex_autorunner/core/prompt.py +15 -7
- codex_autorunner/core/redaction.py +29 -0
- codex_autorunner/core/review_context.py +5 -8
- codex_autorunner/core/run_index.py +6 -0
- codex_autorunner/core/runner_process.py +5 -2
- codex_autorunner/core/state.py +0 -88
- codex_autorunner/core/state_roots.py +57 -0
- codex_autorunner/core/supervisor_protocol.py +15 -0
- codex_autorunner/core/supervisor_utils.py +67 -0
- codex_autorunner/core/text_delta_coalescer.py +54 -0
- codex_autorunner/core/ticket_linter_cli.py +201 -0
- codex_autorunner/core/ticket_manager_cli.py +432 -0
- codex_autorunner/core/update.py +24 -16
- codex_autorunner/core/update_paths.py +28 -0
- codex_autorunner/core/update_runner.py +2 -0
- codex_autorunner/core/usage.py +164 -12
- codex_autorunner/core/utils.py +120 -11
- codex_autorunner/discovery.py +2 -4
- codex_autorunner/flows/review/__init__.py +17 -0
- codex_autorunner/{core/review.py → flows/review/service.py} +15 -10
- codex_autorunner/flows/ticket_flow/__init__.py +3 -0
- codex_autorunner/flows/ticket_flow/definition.py +98 -0
- codex_autorunner/integrations/agents/__init__.py +17 -0
- codex_autorunner/integrations/agents/backend_orchestrator.py +284 -0
- codex_autorunner/integrations/agents/codex_adapter.py +90 -0
- codex_autorunner/integrations/agents/codex_backend.py +448 -0
- codex_autorunner/integrations/agents/opencode_adapter.py +108 -0
- codex_autorunner/integrations/agents/opencode_backend.py +598 -0
- codex_autorunner/integrations/agents/runner.py +91 -0
- codex_autorunner/integrations/agents/wiring.py +271 -0
- codex_autorunner/integrations/app_server/client.py +583 -152
- codex_autorunner/integrations/app_server/env.py +2 -107
- codex_autorunner/{core/app_server_events.py → integrations/app_server/event_buffer.py} +15 -8
- codex_autorunner/integrations/app_server/supervisor.py +59 -33
- codex_autorunner/integrations/telegram/adapter.py +204 -165
- codex_autorunner/integrations/telegram/api_schemas.py +120 -0
- codex_autorunner/integrations/telegram/config.py +221 -0
- codex_autorunner/integrations/telegram/constants.py +17 -2
- codex_autorunner/integrations/telegram/dispatch.py +17 -0
- codex_autorunner/integrations/telegram/doctor.py +47 -0
- codex_autorunner/integrations/telegram/handlers/callbacks.py +7 -4
- codex_autorunner/integrations/telegram/handlers/commands/__init__.py +2 -0
- codex_autorunner/integrations/telegram/handlers/commands/execution.py +53 -57
- codex_autorunner/integrations/telegram/handlers/commands/files.py +2 -6
- codex_autorunner/integrations/telegram/handlers/commands/flows.py +1364 -0
- codex_autorunner/integrations/telegram/handlers/commands/formatting.py +1 -1
- codex_autorunner/integrations/telegram/handlers/commands/github.py +41 -582
- codex_autorunner/integrations/telegram/handlers/commands/workspace.py +8 -8
- codex_autorunner/integrations/telegram/handlers/commands_runtime.py +137 -478
- codex_autorunner/integrations/telegram/handlers/commands_spec.py +17 -4
- codex_autorunner/integrations/telegram/handlers/messages.py +121 -9
- codex_autorunner/integrations/telegram/handlers/selections.py +61 -1
- codex_autorunner/integrations/telegram/helpers.py +111 -16
- codex_autorunner/integrations/telegram/outbox.py +208 -37
- codex_autorunner/integrations/telegram/progress_stream.py +3 -10
- codex_autorunner/integrations/telegram/service.py +221 -42
- codex_autorunner/integrations/telegram/state.py +100 -2
- codex_autorunner/integrations/telegram/ticket_flow_bridge.py +611 -0
- codex_autorunner/integrations/telegram/transport.py +39 -4
- codex_autorunner/integrations/telegram/trigger_mode.py +53 -0
- codex_autorunner/manifest.py +2 -0
- codex_autorunner/plugin_api.py +22 -0
- codex_autorunner/routes/__init__.py +37 -67
- codex_autorunner/routes/agents.py +2 -137
- codex_autorunner/routes/analytics.py +3 -0
- codex_autorunner/routes/app_server.py +2 -131
- codex_autorunner/routes/base.py +2 -624
- codex_autorunner/routes/file_chat.py +7 -0
- codex_autorunner/routes/flows.py +7 -0
- codex_autorunner/routes/messages.py +7 -0
- codex_autorunner/routes/repos.py +2 -196
- codex_autorunner/routes/review.py +2 -147
- codex_autorunner/routes/sessions.py +2 -175
- codex_autorunner/routes/settings.py +2 -168
- codex_autorunner/routes/shared.py +2 -275
- codex_autorunner/routes/system.py +4 -188
- codex_autorunner/routes/usage.py +3 -0
- codex_autorunner/routes/voice.py +2 -119
- codex_autorunner/routes/workspace.py +3 -0
- codex_autorunner/server.py +3 -2
- codex_autorunner/static/agentControls.js +41 -11
- codex_autorunner/static/agentEvents.js +248 -0
- codex_autorunner/static/app.js +35 -24
- codex_autorunner/static/archive.js +826 -0
- codex_autorunner/static/archiveApi.js +37 -0
- codex_autorunner/static/autoRefresh.js +36 -8
- codex_autorunner/static/bootstrap.js +1 -0
- codex_autorunner/static/bus.js +1 -0
- codex_autorunner/static/cache.js +1 -0
- codex_autorunner/static/constants.js +20 -4
- codex_autorunner/static/dashboard.js +344 -325
- codex_autorunner/static/diffRenderer.js +37 -0
- codex_autorunner/static/docChatCore.js +324 -0
- codex_autorunner/static/docChatStorage.js +65 -0
- codex_autorunner/static/docChatVoice.js +65 -0
- codex_autorunner/static/docEditor.js +133 -0
- codex_autorunner/static/env.js +1 -0
- codex_autorunner/static/eventSummarizer.js +166 -0
- codex_autorunner/static/fileChat.js +182 -0
- codex_autorunner/static/health.js +155 -0
- codex_autorunner/static/hub.js +126 -185
- codex_autorunner/static/index.html +839 -863
- codex_autorunner/static/liveUpdates.js +1 -0
- codex_autorunner/static/loader.js +1 -0
- codex_autorunner/static/messages.js +873 -0
- codex_autorunner/static/mobileCompact.js +2 -1
- codex_autorunner/static/preserve.js +17 -0
- codex_autorunner/static/settings.js +149 -217
- codex_autorunner/static/smartRefresh.js +52 -0
- codex_autorunner/static/styles.css +8850 -3876
- codex_autorunner/static/tabs.js +175 -11
- codex_autorunner/static/terminal.js +32 -0
- codex_autorunner/static/terminalManager.js +34 -59
- codex_autorunner/static/ticketChatActions.js +333 -0
- codex_autorunner/static/ticketChatEvents.js +16 -0
- codex_autorunner/static/ticketChatStorage.js +16 -0
- codex_autorunner/static/ticketChatStream.js +264 -0
- codex_autorunner/static/ticketEditor.js +844 -0
- codex_autorunner/static/ticketVoice.js +9 -0
- codex_autorunner/static/tickets.js +1988 -0
- codex_autorunner/static/utils.js +43 -3
- codex_autorunner/static/voice.js +1 -0
- codex_autorunner/static/workspace.js +765 -0
- codex_autorunner/static/workspaceApi.js +53 -0
- codex_autorunner/static/workspaceFileBrowser.js +504 -0
- codex_autorunner/surfaces/__init__.py +5 -0
- codex_autorunner/surfaces/cli/__init__.py +6 -0
- codex_autorunner/surfaces/cli/cli.py +1224 -0
- codex_autorunner/surfaces/cli/codex_cli.py +20 -0
- codex_autorunner/surfaces/telegram/__init__.py +3 -0
- codex_autorunner/surfaces/web/__init__.py +1 -0
- codex_autorunner/surfaces/web/app.py +2019 -0
- codex_autorunner/surfaces/web/hub_jobs.py +192 -0
- codex_autorunner/surfaces/web/middleware.py +587 -0
- codex_autorunner/surfaces/web/pty_session.py +370 -0
- codex_autorunner/surfaces/web/review.py +6 -0
- codex_autorunner/surfaces/web/routes/__init__.py +78 -0
- codex_autorunner/surfaces/web/routes/agents.py +138 -0
- codex_autorunner/surfaces/web/routes/analytics.py +277 -0
- codex_autorunner/surfaces/web/routes/app_server.py +132 -0
- codex_autorunner/surfaces/web/routes/archive.py +357 -0
- codex_autorunner/surfaces/web/routes/base.py +615 -0
- codex_autorunner/surfaces/web/routes/file_chat.py +836 -0
- codex_autorunner/surfaces/web/routes/flows.py +1164 -0
- codex_autorunner/surfaces/web/routes/messages.py +459 -0
- codex_autorunner/surfaces/web/routes/repos.py +197 -0
- codex_autorunner/surfaces/web/routes/review.py +148 -0
- codex_autorunner/surfaces/web/routes/sessions.py +176 -0
- codex_autorunner/surfaces/web/routes/settings.py +169 -0
- codex_autorunner/surfaces/web/routes/shared.py +280 -0
- codex_autorunner/surfaces/web/routes/system.py +196 -0
- codex_autorunner/surfaces/web/routes/usage.py +89 -0
- codex_autorunner/surfaces/web/routes/voice.py +120 -0
- codex_autorunner/surfaces/web/routes/workspace.py +271 -0
- codex_autorunner/surfaces/web/runner_manager.py +25 -0
- codex_autorunner/surfaces/web/schemas.py +417 -0
- codex_autorunner/surfaces/web/static_assets.py +490 -0
- codex_autorunner/surfaces/web/static_refresh.py +86 -0
- codex_autorunner/surfaces/web/terminal_sessions.py +78 -0
- codex_autorunner/tickets/__init__.py +27 -0
- codex_autorunner/tickets/agent_pool.py +399 -0
- codex_autorunner/tickets/files.py +89 -0
- codex_autorunner/tickets/frontmatter.py +55 -0
- codex_autorunner/tickets/lint.py +102 -0
- codex_autorunner/tickets/models.py +97 -0
- codex_autorunner/tickets/outbox.py +244 -0
- codex_autorunner/tickets/replies.py +179 -0
- codex_autorunner/tickets/runner.py +881 -0
- codex_autorunner/tickets/spec_ingest.py +77 -0
- codex_autorunner/web/__init__.py +5 -1
- codex_autorunner/web/app.py +2 -1771
- codex_autorunner/web/hub_jobs.py +2 -191
- codex_autorunner/web/middleware.py +2 -587
- codex_autorunner/web/pty_session.py +2 -369
- codex_autorunner/web/runner_manager.py +2 -24
- codex_autorunner/web/schemas.py +2 -396
- codex_autorunner/web/static_assets.py +4 -484
- codex_autorunner/web/static_refresh.py +2 -85
- codex_autorunner/web/terminal_sessions.py +2 -77
- codex_autorunner/workspace/__init__.py +40 -0
- codex_autorunner/workspace/paths.py +335 -0
- codex_autorunner-1.1.0.dist-info/METADATA +154 -0
- codex_autorunner-1.1.0.dist-info/RECORD +308 -0
- {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/WHEEL +1 -1
- codex_autorunner/agents/execution/policy.py +0 -292
- codex_autorunner/agents/factory.py +0 -52
- codex_autorunner/agents/orchestrator.py +0 -358
- codex_autorunner/core/doc_chat.py +0 -1446
- codex_autorunner/core/snapshot.py +0 -580
- codex_autorunner/integrations/github/chatops.py +0 -268
- codex_autorunner/integrations/github/pr_flow.py +0 -1314
- codex_autorunner/routes/docs.py +0 -381
- codex_autorunner/routes/github.py +0 -327
- codex_autorunner/routes/runs.py +0 -250
- codex_autorunner/spec_ingest.py +0 -812
- codex_autorunner/static/docChatActions.js +0 -287
- codex_autorunner/static/docChatEvents.js +0 -300
- codex_autorunner/static/docChatRender.js +0 -205
- codex_autorunner/static/docChatStream.js +0 -361
- codex_autorunner/static/docs.js +0 -20
- codex_autorunner/static/docsClipboard.js +0 -69
- codex_autorunner/static/docsCrud.js +0 -257
- codex_autorunner/static/docsDocUpdates.js +0 -62
- codex_autorunner/static/docsDrafts.js +0 -16
- codex_autorunner/static/docsElements.js +0 -69
- codex_autorunner/static/docsInit.js +0 -285
- codex_autorunner/static/docsParse.js +0 -160
- codex_autorunner/static/docsSnapshot.js +0 -87
- codex_autorunner/static/docsSpecIngest.js +0 -263
- codex_autorunner/static/docsState.js +0 -127
- codex_autorunner/static/docsThreadRegistry.js +0 -44
- codex_autorunner/static/docsUi.js +0 -153
- codex_autorunner/static/docsVoice.js +0 -56
- codex_autorunner/static/github.js +0 -504
- codex_autorunner/static/logs.js +0 -678
- codex_autorunner/static/review.js +0 -157
- codex_autorunner/static/runs.js +0 -418
- codex_autorunner/static/snapshot.js +0 -124
- codex_autorunner/static/state.js +0 -94
- codex_autorunner/static/todoPreview.js +0 -27
- codex_autorunner/workspace.py +0 -16
- codex_autorunner-0.1.2.dist-info/METADATA +0 -249
- codex_autorunner-0.1.2.dist-info/RECORD +0 -222
- /codex_autorunner/{routes → surfaces/web/routes}/terminal_images.py +0 -0
- {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/entry_points.txt +0 -0
- {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/licenses/LICENSE +0 -0
- {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GENERATED FILE - do not edit directly. Source: static_src/
|
|
1
2
|
import { isMobileViewport, setMobileChromeHidden, setMobileComposeFixed, } from "./utils.js";
|
|
2
3
|
import { subscribe } from "./bus.js";
|
|
3
4
|
import { getTerminalManager } from "./terminal.js";
|
|
@@ -100,7 +101,7 @@ function updateMobileControlsOffset() {
|
|
|
100
101
|
document.documentElement.style.setProperty("--compose-total-height", `${totalHeight}px`);
|
|
101
102
|
}
|
|
102
103
|
function updateDocComposeOffset() {
|
|
103
|
-
const composePanel = document.querySelector("#
|
|
104
|
+
const composePanel = document.querySelector("#workspace .doc-chat-panel, #workspace .ticket-chat-panel");
|
|
104
105
|
if (!composePanel || !isVisible(composePanel))
|
|
105
106
|
return;
|
|
106
107
|
const composeHeight = composePanel.offsetHeight || 0;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// GENERATED FILE - do not edit directly. Source: static_src/
|
|
2
|
+
export function preserveScroll(el, render, opts) {
|
|
3
|
+
if (!el) {
|
|
4
|
+
render();
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const top = el.scrollTop;
|
|
8
|
+
render();
|
|
9
|
+
const restore = () => {
|
|
10
|
+
el.scrollTop = top;
|
|
11
|
+
};
|
|
12
|
+
if (opts?.restoreOnNextFrame && typeof requestAnimationFrame === "function") {
|
|
13
|
+
requestAnimationFrame(restore);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
restore();
|
|
17
|
+
}
|
|
@@ -1,190 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
let currentSettings = null;
|
|
1
|
+
// GENERATED FILE - do not edit directly. Source: static_src/
|
|
2
|
+
import { api, confirmModal, flash, resolvePath, openModal } from "./utils.js";
|
|
4
3
|
const ui = {
|
|
5
4
|
settingsBtn: document.getElementById("repo-settings"),
|
|
6
|
-
modelSelect: document.getElementById("autorunner-model-select"),
|
|
7
|
-
effortSelect: document.getElementById("autorunner-effort-select"),
|
|
8
|
-
approvalSelect: document.getElementById("autorunner-approval-select"),
|
|
9
|
-
sandboxSelect: document.getElementById("autorunner-sandbox-select"),
|
|
10
|
-
maxRunsInput: document.getElementById("autorunner-max-runs-input"),
|
|
11
|
-
networkToggle: document.getElementById("autorunner-network-toggle"),
|
|
12
|
-
networkRow: document.getElementById("autorunner-network-row"),
|
|
13
|
-
saveBtn: document.getElementById("autorunner-settings-save"),
|
|
14
|
-
reloadBtn: document.getElementById("autorunner-settings-reload"),
|
|
15
|
-
warning: document.getElementById("autorunner-settings-warning"),
|
|
16
5
|
threadList: document.getElementById("thread-tools-list"),
|
|
17
6
|
threadNew: document.getElementById("thread-new-autorunner"),
|
|
18
7
|
threadArchive: document.getElementById("thread-archive-autorunner"),
|
|
19
8
|
threadResetAll: document.getElementById("thread-reset-all"),
|
|
20
9
|
threadDownload: document.getElementById("thread-backup-download"),
|
|
21
10
|
};
|
|
22
|
-
const DEFAULT_EFFORTS = ["low", "medium", "high"];
|
|
23
|
-
function getModelId(model) {
|
|
24
|
-
if (!model || typeof model !== "object")
|
|
25
|
-
return null;
|
|
26
|
-
const modelObj = model;
|
|
27
|
-
const keys = ["id", "model", "name", "model_id", "modelId"];
|
|
28
|
-
for (const key of keys) {
|
|
29
|
-
const value = modelObj[key];
|
|
30
|
-
if (typeof value === "string" && value.trim()) {
|
|
31
|
-
return value.trim();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
function getModelEfforts(model) {
|
|
37
|
-
if (!model || typeof model !== "object")
|
|
38
|
-
return null;
|
|
39
|
-
const modelObj = model;
|
|
40
|
-
const keys = [
|
|
41
|
-
"supported_reasoning_efforts",
|
|
42
|
-
"supportedReasoningEfforts",
|
|
43
|
-
"reasoning_efforts",
|
|
44
|
-
"reasoningEfforts",
|
|
45
|
-
"supported_efforts",
|
|
46
|
-
"supportedEfforts",
|
|
47
|
-
"efforts",
|
|
48
|
-
];
|
|
49
|
-
for (const key of keys) {
|
|
50
|
-
const value = modelObj[key];
|
|
51
|
-
if (Array.isArray(value) && value.length) {
|
|
52
|
-
return value.map((entry) => String(entry));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
function normalizeModels(raw) {
|
|
58
|
-
if (Array.isArray(raw))
|
|
59
|
-
return raw;
|
|
60
|
-
if (raw && typeof raw === "object") {
|
|
61
|
-
const rawObj = raw;
|
|
62
|
-
if (Array.isArray(rawObj.models))
|
|
63
|
-
return rawObj.models;
|
|
64
|
-
if (Array.isArray(rawObj.data))
|
|
65
|
-
return rawObj.data;
|
|
66
|
-
if (Array.isArray(rawObj.items))
|
|
67
|
-
return rawObj.items;
|
|
68
|
-
if (Array.isArray(rawObj.results))
|
|
69
|
-
return rawObj.results;
|
|
70
|
-
}
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
function setOptions(select, options, selected, placeholder) {
|
|
74
|
-
if (!select)
|
|
75
|
-
return;
|
|
76
|
-
select.innerHTML = "";
|
|
77
|
-
const empty = document.createElement("option");
|
|
78
|
-
empty.value = "";
|
|
79
|
-
empty.textContent = placeholder;
|
|
80
|
-
select.appendChild(empty);
|
|
81
|
-
options.forEach((opt) => {
|
|
82
|
-
const option = document.createElement("option");
|
|
83
|
-
option.value = opt.value;
|
|
84
|
-
option.textContent = opt.label;
|
|
85
|
-
select.appendChild(option);
|
|
86
|
-
});
|
|
87
|
-
if (selected) {
|
|
88
|
-
const exists = options.some((opt) => opt.value === selected);
|
|
89
|
-
if (!exists) {
|
|
90
|
-
const custom = document.createElement("option");
|
|
91
|
-
custom.value = selected;
|
|
92
|
-
custom.textContent = `${selected} (custom)`;
|
|
93
|
-
select.appendChild(custom);
|
|
94
|
-
}
|
|
95
|
-
select.value = selected;
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
select.value = "";
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function updateNetworkVisibility() {
|
|
102
|
-
if (!ui.networkRow || !ui.sandboxSelect)
|
|
103
|
-
return;
|
|
104
|
-
const show = ui.sandboxSelect.value === "workspaceWrite";
|
|
105
|
-
ui.networkRow.classList.toggle("hidden", !show);
|
|
106
|
-
}
|
|
107
|
-
async function loadModels() {
|
|
108
|
-
try {
|
|
109
|
-
const data = await api("/api/app-server/models");
|
|
110
|
-
modelsCache = normalizeModels(data);
|
|
111
|
-
}
|
|
112
|
-
catch (err) {
|
|
113
|
-
modelsCache = [];
|
|
114
|
-
const error = err;
|
|
115
|
-
flash(error.message || "Failed to load models", "error");
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
async function loadSessionSettings() {
|
|
119
|
-
const data = await api("/api/session/settings");
|
|
120
|
-
currentSettings = data;
|
|
121
|
-
return data;
|
|
122
|
-
}
|
|
123
|
-
function renderSettings(settings) {
|
|
124
|
-
if (!settings)
|
|
125
|
-
return;
|
|
126
|
-
const modelOptions = modelsCache
|
|
127
|
-
.map((model) => {
|
|
128
|
-
const id = getModelId(model);
|
|
129
|
-
return id ? { value: id, label: id } : null;
|
|
130
|
-
})
|
|
131
|
-
.filter((opt) => opt !== null);
|
|
132
|
-
setOptions(ui.modelSelect, modelOptions, settings.autorunner_model_override, "Default model");
|
|
133
|
-
const selectedModelId = ui.modelSelect?.value || settings.autorunner_model_override;
|
|
134
|
-
const selectedModel = modelsCache.find((model) => getModelId(model) === selectedModelId) || null;
|
|
135
|
-
const efforts = getModelEfforts(selectedModel) || [...DEFAULT_EFFORTS];
|
|
136
|
-
const effortOptions = efforts.map((effort) => ({
|
|
137
|
-
value: effort,
|
|
138
|
-
label: effort,
|
|
139
|
-
}));
|
|
140
|
-
setOptions(ui.effortSelect, effortOptions, settings.autorunner_effort_override, "Default effort");
|
|
141
|
-
setOptions(ui.approvalSelect, [
|
|
142
|
-
{ value: "never", label: "Never" },
|
|
143
|
-
{ value: "unlessTrusted", label: "Unless trusted" },
|
|
144
|
-
], settings.autorunner_approval_policy, "Default approval");
|
|
145
|
-
setOptions(ui.sandboxSelect, [
|
|
146
|
-
{ value: "dangerFullAccess", label: "Full access" },
|
|
147
|
-
{ value: "workspaceWrite", label: "Workspace write" },
|
|
148
|
-
], settings.autorunner_sandbox_mode, "Default sandbox");
|
|
149
|
-
if (ui.networkToggle) {
|
|
150
|
-
ui.networkToggle.checked = Boolean(settings.autorunner_workspace_write_network);
|
|
151
|
-
}
|
|
152
|
-
if (ui.maxRunsInput) {
|
|
153
|
-
const maxRuns = settings.runner_stop_after_runs;
|
|
154
|
-
ui.maxRunsInput.value = maxRuns ? String(maxRuns) : "";
|
|
155
|
-
}
|
|
156
|
-
updateNetworkVisibility();
|
|
157
|
-
}
|
|
158
|
-
async function saveSettings() {
|
|
159
|
-
if (!ui.saveBtn)
|
|
160
|
-
return;
|
|
161
|
-
ui.saveBtn.disabled = true;
|
|
162
|
-
ui.saveBtn.classList.add("loading");
|
|
163
|
-
try {
|
|
164
|
-
const payload = {
|
|
165
|
-
autorunner_model_override: ui.modelSelect?.value || null,
|
|
166
|
-
autorunner_effort_override: ui.effortSelect?.value || null,
|
|
167
|
-
autorunner_approval_policy: ui.approvalSelect?.value || null,
|
|
168
|
-
autorunner_sandbox_mode: ui.sandboxSelect?.value || null,
|
|
169
|
-
autorunner_workspace_write_network: Boolean(ui.networkToggle?.checked),
|
|
170
|
-
runner_stop_after_runs: ui.maxRunsInput?.value ? parseInt(ui.maxRunsInput.value, 10) : null,
|
|
171
|
-
};
|
|
172
|
-
const data = await api("/api/session/settings", {
|
|
173
|
-
method: "POST",
|
|
174
|
-
body: payload,
|
|
175
|
-
});
|
|
176
|
-
currentSettings = data;
|
|
177
|
-
flash("Autorunner settings saved", "success");
|
|
178
|
-
}
|
|
179
|
-
catch (err) {
|
|
180
|
-
const error = err;
|
|
181
|
-
flash(error.message || "Failed to save settings", "error");
|
|
182
|
-
}
|
|
183
|
-
finally {
|
|
184
|
-
ui.saveBtn.disabled = false;
|
|
185
|
-
ui.saveBtn.classList.remove("loading");
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
11
|
function renderThreadTools(data) {
|
|
189
12
|
if (!ui.threadList)
|
|
190
13
|
return;
|
|
@@ -197,17 +20,25 @@ function renderThreadTools(data) {
|
|
|
197
20
|
if (data.autorunner !== undefined) {
|
|
198
21
|
entries.push({ label: "Autorunner", value: data.autorunner || "—" });
|
|
199
22
|
}
|
|
200
|
-
if (data.
|
|
201
|
-
entries.push({ label: "
|
|
23
|
+
if (data.file_chat !== undefined) {
|
|
24
|
+
entries.push({ label: "File chat", value: data.file_chat || "—" });
|
|
202
25
|
}
|
|
203
|
-
if (data.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
value: data.doc_chat[key] || "—",
|
|
208
|
-
});
|
|
26
|
+
if (data.file_chat_opencode !== undefined) {
|
|
27
|
+
entries.push({
|
|
28
|
+
label: "File chat (opencode)",
|
|
29
|
+
value: data.file_chat_opencode || "—",
|
|
209
30
|
});
|
|
210
31
|
}
|
|
32
|
+
// Render any additional string/number keys to avoid hiding future entries.
|
|
33
|
+
Object.keys(data).forEach((key) => {
|
|
34
|
+
if (["autorunner", "file_chat", "file_chat_opencode", "corruption"].includes(key)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const value = data[key];
|
|
38
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
39
|
+
entries.push({ label: key, value: value || "—" });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
211
42
|
if (!entries.length) {
|
|
212
43
|
ui.threadList.textContent = "No threads recorded.";
|
|
213
44
|
return;
|
|
@@ -239,39 +70,12 @@ async function loadThreadTools() {
|
|
|
239
70
|
}
|
|
240
71
|
}
|
|
241
72
|
async function refreshSettings() {
|
|
242
|
-
await loadModels();
|
|
243
|
-
const settings = await loadSessionSettings();
|
|
244
|
-
renderSettings(settings);
|
|
245
73
|
await loadThreadTools();
|
|
246
74
|
}
|
|
247
75
|
export function initRepoSettingsPanel() {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
if (ui.modelSelect) {
|
|
254
|
-
ui.modelSelect.addEventListener("change", () => {
|
|
255
|
-
if (!currentSettings)
|
|
256
|
-
return;
|
|
257
|
-
const currentEffort = ui.effortSelect?.value || null;
|
|
258
|
-
const updated = {
|
|
259
|
-
...currentSettings,
|
|
260
|
-
autorunner_model_override: ui.modelSelect.value || null,
|
|
261
|
-
autorunner_effort_override: currentEffort || currentSettings.autorunner_effort_override,
|
|
262
|
-
};
|
|
263
|
-
renderSettings(updated);
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
if (ui.sandboxSelect) {
|
|
267
|
-
ui.sandboxSelect.addEventListener("change", updateNetworkVisibility);
|
|
268
|
-
}
|
|
269
|
-
if (ui.saveBtn) {
|
|
270
|
-
ui.saveBtn.addEventListener("click", () => saveSettings());
|
|
271
|
-
}
|
|
272
|
-
if (ui.reloadBtn) {
|
|
273
|
-
ui.reloadBtn.addEventListener("click", () => refreshSettings());
|
|
274
|
-
}
|
|
76
|
+
window.__CAR_SETTINGS = { loadThreadTools, refreshSettings };
|
|
77
|
+
// Initialize the modal interaction
|
|
78
|
+
initRepoSettingsModal();
|
|
275
79
|
if (ui.threadNew) {
|
|
276
80
|
ui.threadNew.addEventListener("click", async () => {
|
|
277
81
|
try {
|
|
@@ -338,4 +142,132 @@ export function initRepoSettingsPanel() {
|
|
|
338
142
|
window.location.href = resolvePath("/api/app-server/threads/backup");
|
|
339
143
|
});
|
|
340
144
|
}
|
|
145
|
+
// Clear cached logs since log loading is no longer available
|
|
146
|
+
try {
|
|
147
|
+
localStorage.removeItem("logs:tail");
|
|
148
|
+
}
|
|
149
|
+
catch (_err) {
|
|
150
|
+
// ignore
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const UPDATE_TARGET_LABELS = {
|
|
154
|
+
both: "web + Telegram",
|
|
155
|
+
web: "web only",
|
|
156
|
+
telegram: "Telegram only",
|
|
157
|
+
};
|
|
158
|
+
function normalizeUpdateTarget(value) {
|
|
159
|
+
if (!value)
|
|
160
|
+
return "both";
|
|
161
|
+
if (value === "both" || value === "web" || value === "telegram")
|
|
162
|
+
return value;
|
|
163
|
+
return "both";
|
|
164
|
+
}
|
|
165
|
+
function getUpdateTarget(selectId) {
|
|
166
|
+
const select = selectId ? document.getElementById(selectId) : null;
|
|
167
|
+
return normalizeUpdateTarget(select ? select.value : "both");
|
|
168
|
+
}
|
|
169
|
+
function describeUpdateTarget(target) {
|
|
170
|
+
return UPDATE_TARGET_LABELS[target] || UPDATE_TARGET_LABELS.both;
|
|
171
|
+
}
|
|
172
|
+
async function handleSystemUpdate(btnId, targetSelectId) {
|
|
173
|
+
const btn = document.getElementById(btnId);
|
|
174
|
+
if (!btn)
|
|
175
|
+
return;
|
|
176
|
+
const originalText = btn.textContent;
|
|
177
|
+
btn.disabled = true;
|
|
178
|
+
btn.textContent = "Checking...";
|
|
179
|
+
const updateTarget = getUpdateTarget(targetSelectId);
|
|
180
|
+
const targetLabel = describeUpdateTarget(updateTarget);
|
|
181
|
+
let check;
|
|
182
|
+
try {
|
|
183
|
+
check = await api("/system/update/check");
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
check = { update_available: true, message: err.message || "Unable to check for updates." };
|
|
187
|
+
}
|
|
188
|
+
if (!check?.update_available) {
|
|
189
|
+
flash(check?.message || "No update available.", "info");
|
|
190
|
+
btn.disabled = false;
|
|
191
|
+
btn.textContent = originalText;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const restartNotice = updateTarget === "telegram"
|
|
195
|
+
? "The Telegram bot will restart."
|
|
196
|
+
: "The service will restart.";
|
|
197
|
+
const confirmed = await confirmModal(`${check?.message || "Update available."} Update Codex Autorunner (${targetLabel})? ${restartNotice}`);
|
|
198
|
+
if (!confirmed) {
|
|
199
|
+
btn.disabled = false;
|
|
200
|
+
btn.textContent = originalText;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
btn.textContent = "Updating...";
|
|
204
|
+
try {
|
|
205
|
+
const res = await api("/system/update", {
|
|
206
|
+
method: "POST",
|
|
207
|
+
body: { target: updateTarget },
|
|
208
|
+
});
|
|
209
|
+
flash(res.message || `Update started (${targetLabel}).`, "success");
|
|
210
|
+
if (updateTarget === "telegram") {
|
|
211
|
+
btn.disabled = false;
|
|
212
|
+
btn.textContent = originalText;
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
document.body.style.pointerEvents = "none";
|
|
216
|
+
setTimeout(() => {
|
|
217
|
+
const url = new URL(window.location.href);
|
|
218
|
+
url.searchParams.set("v", String(Date.now()));
|
|
219
|
+
window.location.replace(url.toString());
|
|
220
|
+
}, 8000);
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
flash(err.message || "Update failed", "error");
|
|
224
|
+
btn.disabled = false;
|
|
225
|
+
btn.textContent = originalText;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
let repoSettingsCloseModal = null;
|
|
229
|
+
function hideRepoSettingsModal() {
|
|
230
|
+
if (repoSettingsCloseModal) {
|
|
231
|
+
const close = repoSettingsCloseModal;
|
|
232
|
+
repoSettingsCloseModal = null;
|
|
233
|
+
close();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export function openRepoSettings(triggerEl) {
|
|
237
|
+
const modal = document.getElementById("repo-settings-modal");
|
|
238
|
+
const closeBtn = document.getElementById("repo-settings-close");
|
|
239
|
+
const updateBtn = document.getElementById("repo-update-btn");
|
|
240
|
+
if (!modal)
|
|
241
|
+
return;
|
|
242
|
+
hideRepoSettingsModal();
|
|
243
|
+
repoSettingsCloseModal = openModal(modal, {
|
|
244
|
+
initialFocus: closeBtn || updateBtn || modal,
|
|
245
|
+
returnFocusTo: triggerEl || null,
|
|
246
|
+
onRequestClose: hideRepoSettingsModal,
|
|
247
|
+
});
|
|
248
|
+
// Trigger settings refresh when modal opens
|
|
249
|
+
const { refreshSettings } = window.__CAR_SETTINGS || {};
|
|
250
|
+
if (typeof refreshSettings === "function") {
|
|
251
|
+
refreshSettings();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function initRepoSettingsModal() {
|
|
255
|
+
const settingsBtn = document.getElementById("repo-settings");
|
|
256
|
+
const closeBtn = document.getElementById("repo-settings-close");
|
|
257
|
+
const updateBtn = document.getElementById("repo-update-btn");
|
|
258
|
+
const updateTarget = document.getElementById("repo-update-target");
|
|
259
|
+
// If the gear button exists in HTML, wire it up (backwards compatibility)
|
|
260
|
+
if (settingsBtn) {
|
|
261
|
+
settingsBtn.addEventListener("click", () => {
|
|
262
|
+
openRepoSettings(settingsBtn);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (closeBtn) {
|
|
266
|
+
closeBtn.addEventListener("click", () => {
|
|
267
|
+
hideRepoSettingsModal();
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
if (updateBtn) {
|
|
271
|
+
updateBtn.addEventListener("click", () => handleSystemUpdate("repo-update-btn", updateTarget ? updateTarget.id : null));
|
|
272
|
+
}
|
|
341
273
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// GENERATED FILE - do not edit directly. Source: static_src/
|
|
2
|
+
/**
|
|
3
|
+
* Create a signature-aware refresh helper that only calls render when data changes.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* const smartRefresh = createSmartRefresh({
|
|
7
|
+
* getSignature: (payload) => payload.items.map((i) => i.id).join("|"),
|
|
8
|
+
* render: (payload) => renderList(payload.items),
|
|
9
|
+
* });
|
|
10
|
+
*
|
|
11
|
+
* await smartRefresh.refresh(loadItems, { reason: "background" });
|
|
12
|
+
*/
|
|
13
|
+
export function createSmartRefresh(options) {
|
|
14
|
+
let lastSignature = options.initialSignature ?? null;
|
|
15
|
+
const refresh = async (load, request = {}) => {
|
|
16
|
+
const payload = await load();
|
|
17
|
+
const nextSignature = options.getSignature(payload);
|
|
18
|
+
const previousSignature = lastSignature;
|
|
19
|
+
const isInitial = previousSignature === null || request.reason === "initial";
|
|
20
|
+
const isForced = Boolean(request.force);
|
|
21
|
+
const updated = isForced || isInitial || nextSignature !== previousSignature;
|
|
22
|
+
const reason = request.reason ?? (isInitial ? "initial" : "background");
|
|
23
|
+
const ctx = {
|
|
24
|
+
isInitial,
|
|
25
|
+
isForced,
|
|
26
|
+
previousSignature,
|
|
27
|
+
nextSignature,
|
|
28
|
+
updated,
|
|
29
|
+
reason,
|
|
30
|
+
};
|
|
31
|
+
if (updated) {
|
|
32
|
+
lastSignature = nextSignature;
|
|
33
|
+
await options.render(payload, ctx);
|
|
34
|
+
}
|
|
35
|
+
else if (options.onSkip) {
|
|
36
|
+
await options.onSkip(payload, ctx);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
updated,
|
|
40
|
+
signature: nextSignature,
|
|
41
|
+
previousSignature,
|
|
42
|
+
reason,
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
refresh,
|
|
47
|
+
reset: () => {
|
|
48
|
+
lastSignature = null;
|
|
49
|
+
},
|
|
50
|
+
getSignature: () => lastSignature,
|
|
51
|
+
};
|
|
52
|
+
}
|