agentbox-app 0.1.13 → 0.1.16
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/README.md +24 -9
- package/bin/agentbox.mjs +23 -1
- package/briefs/message-rules.md +36 -8
- package/briefs/worker.md +46 -23
- package/main/account-discovery.mjs +122 -30
- package/main/account-tooling.mjs +29 -1
- package/main/account-usage.mjs +46 -0
- package/main/agent-sessions.mjs +282 -268
- package/main/agents.mjs +179 -466
- package/main/analytics.mjs +12 -2
- package/main/answer-modes.mjs +103 -37
- package/main/approval-prompt-core.mjs +197 -0
- package/main/approval-prompt-server.mjs +4 -138
- package/main/approvals.mjs +101 -297
- package/main/artifact-path.mjs +47 -18
- package/main/claude-input.mjs +48 -4
- package/main/claude-plan.mjs +48 -0
- package/main/claude-session-open.mjs +28 -0
- package/main/claude-usage-process.mjs +40 -0
- package/main/claude-usage.mjs +18 -40
- package/main/cloud/account.mjs +179 -0
- package/main/cloud/aws.mjs +127 -0
- package/main/cloud/browser-return.mjs +58 -0
- package/main/cloud/clients.mjs +15 -0
- package/main/cloud/codex-cloud.mjs +53 -0
- package/main/cloud/config.mjs +107 -0
- package/main/cloud/docs.mjs +219 -0
- package/main/cloud/exec.mjs +27 -0
- package/main/cloud/host.mjs +165 -0
- package/main/cloud/kit.mjs +80 -0
- package/main/cloud/logins.mjs +543 -0
- package/main/cloud/managed.mjs +115 -0
- package/main/cloud/marker.mjs +104 -0
- package/main/cloud/org.mjs +53 -0
- package/main/cloud/reuse.mjs +208 -0
- package/main/cloud/run-cli.mjs +177 -0
- package/main/cloud/run.mjs +1934 -0
- package/main/cloud/usage.mjs +76 -0
- package/main/cloud-permission.mjs +51 -0
- package/main/codex-account.mjs +78 -0
- package/main/codex-app-server.mjs +276 -409
- package/main/codex-approvals.mjs +148 -433
- package/main/codex-models.mjs +20 -2
- package/main/codex-session.mjs +212 -507
- package/main/codex-threads-worker.mjs +12 -0
- package/main/codex-threads.mjs +71 -3
- package/main/codex-usage-file.mjs +5 -3
- package/main/codex-usage.mjs +56 -7
- package/main/codex-watch.mjs +17 -3
- package/main/codex.mjs +95 -363
- package/main/config.mjs +11 -1
- package/main/corner-tag.mjs +340 -19
- package/main/dev-window.mjs +1 -1
- package/main/engine-bin.mjs +232 -282
- package/main/engine-setup.mjs +21 -9
- package/main/feedback.mjs +3 -25
- package/main/folder-pictures.mjs +2 -2
- package/main/freeze-recorder-thread.mjs +86 -0
- package/main/freeze-recorder.mjs +146 -0
- package/main/fresh-user.mjs +20 -9
- package/main/git-change-offthread.mjs +17 -3
- package/main/git-change-thread.mjs +5 -2
- package/main/harnesses/claude.mjs +32 -11
- package/main/harnesses/codex.mjs +9 -2
- package/main/importable-threads.mjs +64 -6
- package/main/ipc.mjs +362 -111
- package/main/leftovers.mjs +117 -25
- package/main/liquid-glass.mjs +26 -0
- package/main/live-replies.mjs +10 -4
- package/main/main-went-red.mjs +330 -0
- package/main/main.mjs +199 -84
- package/main/memory-gate-history.mjs +36 -10
- package/main/memory-gate-server.mjs +62 -0
- package/main/memory-gate.mjs +14 -1
- package/main/menu.mjs +4 -2
- package/main/message-priority.mjs +2 -2
- package/main/mic.mjs +38 -0
- package/main/native/liquid-glass/build/liquid-glass.node +0 -0
- package/main/new-chats-watch.mjs +110 -0
- package/main/new-user-window.mjs +25 -0
- package/main/notify.mjs +24 -8
- package/main/phone-alerts.mjs +117 -0
- package/main/phone-inbox.mjs +625 -0
- package/main/phone-link.mjs +29 -9
- package/main/phone-uploads.mjs +476 -0
- package/main/picture-shape.mjs +114 -0
- package/main/quit-sequence.mjs +143 -0
- package/main/refresh-agent-models.mjs +15 -2
- package/main/relay-client.mjs +69 -1
- package/main/repeats.mjs +10 -4
- package/main/row-label.mjs +12 -41
- package/main/run-change.mjs +13 -0
- package/main/run-ledger.mjs +135 -0
- package/main/save-attachments.mjs +41 -0
- package/main/serve.mjs +45 -3
- package/main/settings.mjs +220 -44
- package/main/shell-path.mjs +185 -37
- package/main/ship-conflict-brief.mjs +119 -0
- package/main/ship-queue.mjs +115 -19
- package/main/source-updater.mjs +18 -10
- package/main/stage-attachment.mjs +68 -0
- package/main/stall-watch.mjs +50 -0
- package/main/store/home.mjs +87 -232
- package/main/store/paths.mjs +11 -0
- package/main/store/teammates-files.mjs +99 -0
- package/main/store/work-items.mjs +231 -13
- package/main/store.mjs +226 -52
- package/main/supervisor.mjs +3103 -341
- package/main/task-folders.mjs +430 -30
- package/main/task-terminals.mjs +110 -34
- package/main/team/index.mjs +114 -10
- package/main/team/memory-cloud.mjs +183 -1
- package/main/team/room-hours.mjs +48 -0
- package/main/team/room-setup.mjs +31 -0
- package/main/team/rooms-memory.mjs +454 -0
- package/main/team/rooms-shape.mjs +42 -0
- package/main/team/rooms-supabase.mjs +324 -0
- package/main/team/rooms.mjs +575 -0
- package/main/team/session.mjs +96 -26
- package/main/team/supabase-backend.mjs +180 -0
- package/main/team/sync.mjs +109 -1
- package/main/teammates.mjs +580 -0
- package/main/terminal-host.mjs +143 -0
- package/main/terminal-hosts.mjs +261 -0
- package/main/transcript-search.mjs +80 -0
- package/main/webview-guard.mjs +45 -0
- package/main/worktree-include.mjs +90 -219
- package/mcp/core/documents.mjs +3 -1
- package/mcp/core/repeats.mjs +88 -0
- package/mcp/core/teammates.mjs +222 -0
- package/mcp/core/work.mjs +76 -4
- package/mcp/stdio.mjs +24 -11
- package/mcp/tools.mjs +116 -8
- package/package.json +21 -5
- package/renderer/dist/assets/{abnfDiagram-YUKMZFIV-DPPuMWt-.js → abnfDiagram-YUKMZFIV-CoWB6YUK.js} +1 -1
- package/renderer/dist/assets/{arc-HmFfdseH.js → arc-Ch0NrCul.js} +1 -1
- package/renderer/dist/assets/{architectureDiagram-47P4ROYG-DxJ3zHrH.js → architectureDiagram-47P4ROYG-CXz9M5tQ.js} +1 -1
- package/renderer/dist/assets/{blockDiagram-E7TT5TSB-CbTXzOqQ.js → blockDiagram-E7TT5TSB-DchGUuHH.js} +1 -1
- package/renderer/dist/assets/{c4Diagram-CRA5TL53-X5ItFyLn.js → c4Diagram-CRA5TL53-Cip-zNyr.js} +1 -1
- package/renderer/dist/assets/channel-BQuQSL--.js +1 -0
- package/renderer/dist/assets/{chunk-2Q5K7J3B-DC12Ho_L.js → chunk-2Q5K7J3B-BoXid_2r.js} +1 -1
- package/renderer/dist/assets/{chunk-5VM5RSS4-ClVtfPd0.js → chunk-5VM5RSS4-Cpez1rRz.js} +1 -1
- package/renderer/dist/assets/{chunk-7TKQ45FW-DgcOm0HT.js → chunk-7TKQ45FW-DKA84YkE.js} +1 -1
- package/renderer/dist/assets/{chunk-AW2ZBBNX-C01s4yoF.js → chunk-AW2ZBBNX-Dg-SumPG.js} +1 -1
- package/renderer/dist/assets/{chunk-FVRAUYC3-Bj0zxhR4.js → chunk-FVRAUYC3-06TCvPm1.js} +2 -2
- package/renderer/dist/assets/{chunk-HTAEGDNF-DWDeEhLU.js → chunk-HTAEGDNF-CMEBy1Td.js} +1 -1
- package/renderer/dist/assets/{chunk-JWPE2WC7-Dsqwv3eW.js → chunk-JWPE2WC7-BJ2ObmV-.js} +1 -1
- package/renderer/dist/assets/{chunk-KQW6MTUR-CE86ANL2.js → chunk-KQW6MTUR-CGWOYXUE.js} +1 -1
- package/renderer/dist/assets/{chunk-XXDRQBXY-CoNTASfs.js → chunk-XXDRQBXY-CiZp07XC.js} +1 -1
- package/renderer/dist/assets/{classDiagram-v2-K4WV4PDN-2wprLqtw.js → classDiagram-v2-K4WV4PDN-DJNIX719.js} +1 -1
- package/renderer/dist/assets/cornerTag-CPgvu-q3.js +1 -0
- package/renderer/dist/assets/cornerTag-oMfEjzCO.css +1 -0
- package/renderer/dist/assets/{cose-bilkent-JH36ORCC-enqMiYbn.js → cose-bilkent-JH36ORCC-CbkyZOUH.js} +1 -1
- package/renderer/dist/assets/{cynefin-EF2NZ3EQ-DHngLxvQ.js → cynefin-EF2NZ3EQ-78iOroZO.js} +1 -1
- package/renderer/dist/assets/{cynefinDiagram-3GCD6N5R-C0rZZIl3.js → cynefinDiagram-3GCD6N5R-GcCopMs7.js} +1 -1
- package/renderer/dist/assets/{dagre-W4DXFKR2-DQnaEWO7.js → dagre-W4DXFKR2-DHLlXLkz.js} +1 -1
- package/renderer/dist/assets/{diagram-2UJZ2QOL-CS8AlGPx.js → diagram-2UJZ2QOL-DuZSUHcH.js} +1 -1
- package/renderer/dist/assets/{diagram-OVF4WLC6-yiDMHIkY.js → diagram-OVF4WLC6-Ckxu3cqH.js} +1 -1
- package/renderer/dist/assets/{diagram-PFPMY2P6-XbQKzbBA.js → diagram-PFPMY2P6-CsTw9Ycn.js} +1 -1
- package/renderer/dist/assets/{diagram-UMYRVEAY-dhVvlfl_.js → diagram-UMYRVEAY-CTXd8qVg.js} +1 -1
- package/renderer/dist/assets/{diagram-YEKJPTXX-DZHe8SCf.js → diagram-YEKJPTXX-CJs1T_9m.js} +1 -1
- package/renderer/dist/assets/{diagram-ZIFT7M5P-B5h6aXVR.js → diagram-ZIFT7M5P-CvjI23mf.js} +1 -1
- package/renderer/dist/assets/{ebnfDiagram-VR2GEFS7-PR9ScDco.js → ebnfDiagram-VR2GEFS7-d_IeAzOJ.js} +1 -1
- package/renderer/dist/assets/{elk-IJKZMXRS-Cg-yQXPd.js → elk-IJKZMXRS-zo9KFP3N.js} +1 -1
- package/renderer/dist/assets/{erDiagram-O2IAPWRE-omOrJMxu.js → erDiagram-O2IAPWRE-DqfYf5Dt.js} +1 -1
- package/renderer/dist/assets/{flowDiagram-OXPTDLAJ-aOX2hzvT.js → flowDiagram-OXPTDLAJ-DAWsMLmo.js} +1 -1
- package/renderer/dist/assets/{ganttDiagram-R7TSEDQI-B1H3pWyI.js → ganttDiagram-R7TSEDQI-4ml_bhwR.js} +1 -1
- package/renderer/dist/assets/{gitGraphDiagram-XJZIOB7I-Cvw304HC.js → gitGraphDiagram-XJZIOB7I-B_WcqSId.js} +1 -1
- package/renderer/dist/assets/{infoDiagram-5W2HQ5XZ-_ZXcNViH.js → infoDiagram-5W2HQ5XZ-CI-jYqzc.js} +1 -1
- package/renderer/dist/assets/{ishikawaDiagram-K3B6WC7H-C7Mx_qQk.js → ishikawaDiagram-K3B6WC7H-B56VWRlV.js} +1 -1
- package/renderer/dist/assets/{journeyDiagram-COXZFDF6-fr62QoAt.js → journeyDiagram-COXZFDF6-D1-p09Lr.js} +1 -1
- package/renderer/dist/assets/{kanban-definition-P3RFRI5V-J8zsabCe.js → kanban-definition-P3RFRI5V-Cv3w7JoN.js} +1 -1
- package/renderer/dist/assets/{linear-BmNdEtIi.js → linear-C35V2Spi.js} +1 -1
- package/renderer/dist/assets/main-BcoBiGwv.css +32 -0
- package/renderer/dist/assets/main-CLnIOulD.js +1191 -0
- package/renderer/dist/assets/{mermaid.core-CnYzvFkz.js → mermaid.core-BzGT5Vo9.js} +4 -4
- package/renderer/dist/assets/{mindmap-definition-LZFPQGKD-Bfcxc7PM.js → mindmap-definition-LZFPQGKD-BZUfuymC.js} +1 -1
- package/renderer/dist/assets/{pegDiagram-BGZESJAR-CwUJOq6X.js → pegDiagram-BGZESJAR-DFh9XNGe.js} +1 -1
- package/renderer/dist/assets/{pieDiagram-CAPJLFHJ-BrwMmqfC.js → pieDiagram-CAPJLFHJ-C65tPVsy.js} +1 -1
- package/renderer/dist/assets/{product-name-CTKLYNWY.js → product-name-CSNW6d7s.js} +1 -1
- package/renderer/dist/assets/{quadrantDiagram-GDMTTRAM-BN4Stoj-.js → quadrantDiagram-GDMTTRAM-Cushj_nk.js} +1 -1
- package/renderer/dist/assets/{railroadDiagram-SM67HX2B-CPZ5bbeR.js → railroadDiagram-SM67HX2B-DZGebGx5.js} +1 -1
- package/renderer/dist/assets/{requirementDiagram-X7JNWC4A-CgRnimVe.js → requirementDiagram-X7JNWC4A-DpAB0MNo.js} +1 -1
- package/renderer/dist/assets/{sankeyDiagram-UM26HJRW-Bt2rej__.js → sankeyDiagram-UM26HJRW-D-29rHra.js} +1 -1
- package/renderer/dist/assets/{sequenceDiagram-ZO4K6R2Y-Dd5nKe9G.js → sequenceDiagram-ZO4K6R2Y-FfOQAZol.js} +1 -1
- package/renderer/dist/assets/{sizeCapture-INFHLROL-usyNyXyh.js → sizeCapture-INFHLROL-C_n6fDBY.js} +1 -1
- package/renderer/dist/assets/{stateDiagram-v2-TBUQTH76-CRzUBb0u.js → stateDiagram-v2-TBUQTH76-BZjenzJG.js} +1 -1
- package/renderer/dist/assets/{swimlanes-N4OXWK64-C1GJvMS0.js → swimlanes-N4OXWK64-DxaMU9vX.js} +1 -1
- package/renderer/dist/assets/swimlanesDiagram-K3J5GTZL-Cb2kM6rr.js +8 -0
- package/renderer/dist/assets/{timeline-definition-YOQAKGHF-caeyPlcc.js → timeline-definition-YOQAKGHF-DTg5HJKz.js} +1 -1
- package/renderer/dist/assets/{usecaseDiagram-VIAY4XPW-BN_SV6PC.js → usecaseDiagram-VIAY4XPW-Bc3MZDsl.js} +1 -1
- package/renderer/dist/assets/{vennDiagram-BLWOH2XV-BLGuaUX-.js → vennDiagram-BLWOH2XV-GIVGk9Id.js} +1 -1
- package/renderer/dist/assets/{wardleyDiagram-YMQ3BMBF-Da0cJeNc.js → wardleyDiagram-YMQ3BMBF-NmJnbQOg.js} +1 -1
- package/renderer/dist/assets/{xychartDiagram-TAQBALBS-cGfUffMk.js → xychartDiagram-TAQBALBS-p-kfGfnW.js} +1 -1
- package/renderer/dist/corner-tag.html +3 -3
- package/renderer/dist/index.html +3 -3
- package/scripts/after-install.mjs +30 -8
- package/scripts/cloud-shim.pl +57 -0
- package/shared/account-names.d.mts +6 -0
- package/shared/account-names.mjs +15 -0
- package/shared/agent-hours.mjs +136 -0
- package/shared/agent-import.mjs +60 -34
- package/shared/agents.mjs +126 -522
- package/shared/analytics-events.mjs +12 -0
- package/shared/approval-card.mjs +36 -0
- package/shared/bridge-map.mjs +27 -1
- package/shared/claude-code-shape.mjs +6 -0
- package/shared/claude-usage.d.mts +1 -0
- package/shared/claude-usage.mjs +42 -1
- package/shared/cloud-hand-back.d.mts +7 -0
- package/shared/cloud-hand-back.mjs +20 -0
- package/shared/cloud-kit.d.mts +219 -0
- package/shared/cloud-kit.mjs +341 -0
- package/shared/cloud-login-name.mjs +4 -0
- package/shared/cloud-start.mjs +17 -0
- package/shared/cloud-versions.mjs +23 -0
- package/shared/codex-import.mjs +2 -2
- package/shared/codex-modes.d.mts +22 -9
- package/shared/codex-modes.mjs +67 -11
- package/shared/codex-usage.mjs +108 -2
- package/shared/corner-tag.d.mts +23 -1
- package/shared/corner-tag.mjs +284 -29
- package/shared/dead-run-trace.mjs +19 -2
- package/shared/engines.mjs +70 -309
- package/shared/feedback.d.mts +7 -0
- package/shared/feedback.mjs +25 -0
- package/shared/first-run-practice.mjs +17 -24
- package/shared/harness-definitions.mjs +8 -0
- package/shared/instruction-defaults.json +2 -2
- package/shared/key-caps.d.mts +14 -0
- package/shared/key-caps.mjs +68 -0
- package/shared/message-edits.d.mts +7 -0
- package/shared/message-edits.mjs +35 -0
- package/shared/move-thread.d.mts +24 -0
- package/shared/move-thread.mjs +112 -0
- package/shared/named-threads.mjs +72 -0
- package/shared/not-shipped.d.mts +22 -0
- package/shared/not-shipped.mjs +89 -0
- package/shared/notify-rules.d.mts +6 -0
- package/shared/notify-rules.mjs +36 -8
- package/shared/phone-files.mjs +28 -0
- package/shared/phone-settings.mjs +118 -0
- package/shared/phone-snapshot.d.mts +16 -0
- package/shared/phone-snapshot.mjs +348 -0
- package/shared/picture-formats.d.mts +1 -0
- package/shared/picture-formats.mjs +13 -0
- package/shared/rank.d.mts +2 -1
- package/shared/rank.mjs +32 -19
- package/shared/repeats.d.mts +8 -0
- package/shared/repeats.mjs +33 -2
- package/shared/room-cards.mjs +167 -0
- package/shared/room-links.d.mts +4 -0
- package/shared/room-links.mjs +21 -0
- package/shared/runs-on.d.mts +3 -3
- package/shared/runs-on.mjs +8 -5
- package/shared/shipped-note.d.mts +4 -0
- package/shared/shipped-note.mjs +6 -0
- package/shared/shortcuts.mjs +14 -6
- package/shared/spawn-trouble.d.mts +4 -0
- package/shared/spawn-trouble.mjs +443 -40
- package/shared/team-rules.mjs +9 -2
- package/shared/teammates.d.mts +19 -0
- package/shared/teammates.mjs +756 -0
- package/shared/terminal-focus.d.mts +1 -0
- package/shared/terminal-focus.mjs +13 -0
- package/shared/thread-cards.mjs +4 -1
- package/shared/usage.d.mts +9 -0
- package/shared/usage.mjs +49 -3
- package/shared/websites.d.mts +15 -0
- package/shared/websites.mjs +61 -0
- package/shared/work-items.mjs +127 -30
- package/shared/work-lines.mjs +92 -244
- package/renderer/dist/assets/channel-BlT2g9Sz.js +0 -1
- package/renderer/dist/assets/cornerTag-BLrxiDE5.css +0 -1
- package/renderer/dist/assets/cornerTag-BOT6u3Tn.js +0 -1
- package/renderer/dist/assets/main-ChNdnUvt.js +0 -1132
- package/renderer/dist/assets/main-nj0QR5kg.css +0 -32
- package/renderer/dist/assets/swimlanesDiagram-K3J5GTZL-Cy4Av2_p.js +0 -8
package/main/settings.mjs
CHANGED
|
@@ -12,27 +12,32 @@
|
|
|
12
12
|
// place a grant is reviewed; what changed is that she edits them as fields on
|
|
13
13
|
// the project they belong to instead of in a text editor.
|
|
14
14
|
|
|
15
|
+
import { teammatesOn } from '../shared/teammates.mjs';
|
|
16
|
+
import { phoneChoiceOf, phoneProjectsOf, withPhoneAll, withPhoneProject, phoneEligible } from '../shared/phone-snapshot.mjs';
|
|
15
17
|
import fs from 'node:fs';
|
|
16
18
|
import { harnessFor } from './harnesses.mjs';
|
|
17
19
|
import os from 'node:os';
|
|
18
20
|
import path from 'node:path';
|
|
19
21
|
import { codexChoiceToOpen, saveConfig } from './config.mjs';
|
|
20
22
|
import { forgetClaudeBin, INSTALL_URL } from './claude-bin.mjs';
|
|
23
|
+
import { lookAgain } from './engine-bin.mjs';
|
|
21
24
|
import { AGENT_MODES } from '../shared/agents.mjs';
|
|
22
25
|
import { analyticsKey, diagnosticsOn } from './analytics.mjs';
|
|
23
26
|
import { CLAUDE_PERMISSION_MODES } from '../shared/work-items.mjs';
|
|
24
27
|
import { accountSentence, engineTroubleNote, refineCause } from '../shared/spawn-trouble.mjs';
|
|
25
28
|
import { readPlan } from './claude-plan.mjs';
|
|
26
|
-
import { effectiveProfiles } from './account-discovery.mjs';
|
|
29
|
+
import { effectiveProfiles, troubleForProfile } from './account-discovery.mjs';
|
|
27
30
|
import { machineSlots, machineNote, autoAgents, MAX_SLOTS } from './machine.mjs';
|
|
28
31
|
import { shortPath } from './agent-files.mjs';
|
|
29
32
|
import { NAME, Name } from '../shared/product-name.mjs';
|
|
30
33
|
import { autoSlots } from './memory-gate.mjs';
|
|
31
34
|
import { accountIdentity, claudeLoginCommand, duplicateAccountNote, linkAccountTooling, makeClaudeHome } from './account-tooling.mjs';
|
|
32
35
|
import { isEngine } from '../shared/engines.mjs';
|
|
33
|
-
import { codexAccount, codexLoginCommand, makeCodexHome } from './codex-account.mjs';
|
|
34
|
-
import { codexDefaultModel,
|
|
36
|
+
import { codexAccount, codexFreePlan, codexLoginCommand, makeCodexHome } from './codex-account.mjs';
|
|
37
|
+
import { codexDefaultModel, codexModelsAcross } from './codex-models.mjs';
|
|
35
38
|
import { CODEX_DEFAULT_MODE, isCodexMode } from '../shared/codex-modes.mjs';
|
|
39
|
+
import { CLOUD_SAME, CLOUD_CLAUDE_DEFAULT, CLOUD_CODEX_DEFAULT } from './cloud-permission.mjs';
|
|
40
|
+
import { isPackagedElectron } from './team/session.mjs';
|
|
36
41
|
import { claudeModels } from './claude-models.mjs';
|
|
37
42
|
import { forgetCodexBin, INSTALL_URL as CODEX_INSTALL_URL } from './codex-bin.mjs';
|
|
38
43
|
|
|
@@ -215,6 +220,8 @@ export function buildSessionArgs(base, mode) {
|
|
|
215
220
|
return [...model, ...(tools.length ? ['--allowedTools', ...tools] : []), ...grant, ...parsed.other];
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
export { cloudPermissionArgs } from './cloud-permission.mjs';
|
|
224
|
+
|
|
218
225
|
// THE MODEL, WRITTEN BACK INTO THE SAME LIST buildSessionArgs READS FROM.The
|
|
219
226
|
// screen had no control over this at all; the flag was already there and only
|
|
220
227
|
// a text editor could change it.
|
|
@@ -247,10 +254,31 @@ export function setModelArg(base, model) {
|
|
|
247
254
|
|
|
248
255
|
const lineCount = (text) => (text.trim() ? text.trim().split('\n').length : 0);
|
|
249
256
|
|
|
257
|
+
// What launch found, or the last Check again, in the finder's own shape. For a
|
|
258
|
+
// read nobody is looking at: the search starts a login shell on the window's
|
|
259
|
+
// thread, and the phone reads settings every minute.
|
|
260
|
+
function knownEngine(config, engine) {
|
|
261
|
+
if (engine === 'claude') {
|
|
262
|
+
return {
|
|
263
|
+
path: config.claudeBin ?? null,
|
|
264
|
+
found: !!config.claudeFound,
|
|
265
|
+
certain: config.claudeCertain !== false,
|
|
266
|
+
from: config.claudeBinConfigured ? 'settings' : (config.claudeFrom ?? null),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
// recheckCodex moves codexBin and not codexFound, so the path is the answer.
|
|
270
|
+
return {
|
|
271
|
+
path: config.codexBin ?? null,
|
|
272
|
+
found: !!config.codexBin,
|
|
273
|
+
certain: config.codexCertain !== false,
|
|
274
|
+
from: config.codexBinConfigured ? 'settings' : (config.codexFrom ?? null),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
250
278
|
// Claude Code: the path, whether it is really there, and where to get it when
|
|
251
279
|
// it is not. One reader, here, so the screen and the config cannot disagree.
|
|
252
|
-
export function claudeState(config) {
|
|
253
|
-
const found = harnessFor('claude').discover(config.claudeBinConfigured ?? null);
|
|
280
|
+
export function claudeState(config, { search = true } = {}) {
|
|
281
|
+
const found = search ? harnessFor('claude').discover(config.claudeBinConfigured ?? null) : knownEngine(config, 'claude');
|
|
254
282
|
return {
|
|
255
283
|
claudeBin: found.path ?? config.claudeBin,
|
|
256
284
|
claudeFound: found.found,
|
|
@@ -274,6 +302,20 @@ export function claudeState(config) {
|
|
|
274
302
|
// `forgetClaudeBin` exists for.
|
|
275
303
|
export function recheckClaude(config) {
|
|
276
304
|
forgetClaudeBin();
|
|
305
|
+
return takeClaude(config);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Check again without holding the window: the shell is asked in the background
|
|
310
|
+
* and this settles once its answer is on the config. For every caller that can
|
|
311
|
+
* wait (the buttons, setup, the update check).
|
|
312
|
+
*/
|
|
313
|
+
export async function lookAgainFor(engine, config) {
|
|
314
|
+
await lookAgain(engine);
|
|
315
|
+
return engine === 'claude' ? takeClaude(config) : takeCodex(config);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function takeClaude(config) {
|
|
277
319
|
const state = claudeState(config);
|
|
278
320
|
// The config carries the path everything else spawns from, so a search that
|
|
279
321
|
// has just found Claude Code updates it rather than leaving the rest of the
|
|
@@ -282,7 +324,10 @@ export function recheckClaude(config) {
|
|
|
282
324
|
// And whether it is here at all, which is what decides that a Mac with only
|
|
283
325
|
// Codex runs on Codex (`Supervisor#_enginesFound`). Only a certain answer
|
|
284
326
|
// moves it, so an unsure search never takes Claude Code away from anybody.
|
|
285
|
-
if (state.claudeFound || state.claudeCertain)
|
|
327
|
+
if (state.claudeFound || state.claudeCertain) {
|
|
328
|
+
config.claudeFound = state.claudeFound;
|
|
329
|
+
config.claudeCertain = state.claudeCertain;
|
|
330
|
+
}
|
|
286
331
|
return state;
|
|
287
332
|
}
|
|
288
333
|
|
|
@@ -316,8 +361,8 @@ export function recheckClaude(config) {
|
|
|
316
361
|
* checked by uninstalling Codex from the machine running the suite is a card
|
|
317
362
|
* whose unsure state is not checked. Nothing in the app passes it.
|
|
318
363
|
*/
|
|
319
|
-
export function codexState(config, where = {}) {
|
|
320
|
-
const found = harnessFor('codex').discover(config.codexBinConfigured ?? null, where);
|
|
364
|
+
export function codexState(config, where = {}, { search = true } = {}) {
|
|
365
|
+
const found = search ? harnessFor('codex').discover(config.codexBinConfigured ?? null, where) : knownEngine(config, 'codex');
|
|
321
366
|
return {
|
|
322
367
|
// Empty rather than a path when there is nothing there, which is the same
|
|
323
368
|
// asymmetry `config.codexBin` already keeps (main/config.mjs): a configured
|
|
@@ -335,8 +380,8 @@ export function codexState(config, where = {}) {
|
|
|
335
380
|
}
|
|
336
381
|
|
|
337
382
|
/** `codexState` under the names the walk's last card reads beside Claude's. */
|
|
338
|
-
export function codexFoundState(config, where = {}) {
|
|
339
|
-
const state = codexState(config, where);
|
|
383
|
+
export function codexFoundState(config, where = {}, how = {}) {
|
|
384
|
+
const state = codexState(config, where, how);
|
|
340
385
|
return { codexFound: state.found, codexCertain: state.certain, codexInstallUrl: state.url };
|
|
341
386
|
}
|
|
342
387
|
|
|
@@ -348,8 +393,13 @@ export function codexFoundState(config, where = {}) {
|
|
|
348
393
|
* without a restart. */
|
|
349
394
|
export function recheckCodex(config) {
|
|
350
395
|
forgetCodexBin();
|
|
396
|
+
return takeCodex(config);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function takeCodex(config) {
|
|
351
400
|
const state = codexState(config);
|
|
352
401
|
config.codexBin = state.found ? state.bin : null;
|
|
402
|
+
config.codexCertain = state.certain;
|
|
353
403
|
// Found while the app is open, by this button or the plan setup: the choice
|
|
354
404
|
// opens now, as it would have at the next launch (main/config.mjs).
|
|
355
405
|
const opened = codexChoiceToOpen(config, state.found);
|
|
@@ -438,7 +488,19 @@ export function searchForEngineBin(config, engine) {
|
|
|
438
488
|
return { ok: true, state };
|
|
439
489
|
}
|
|
440
490
|
|
|
441
|
-
|
|
491
|
+
// THE ALPHA FEATURES SWITCHES (w-3d0fa23ffb). Off unless someone turned them
|
|
492
|
+
// on in Settings; only a real `true` counts. Multiplayer, the team version, is
|
|
493
|
+
// the exception in a checkout, where it was always on.
|
|
494
|
+
export function alphaFeatures(config, { packaged = isPackagedElectron() } = {}) {
|
|
495
|
+
return {
|
|
496
|
+
rooms: config?.alphaRooms === true,
|
|
497
|
+
teammates: teammatesOn(config),
|
|
498
|
+
multiplayer: packaged ? config?.alphaMultiplayer === true : config?.alphaMultiplayer !== false,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// `search: false` is for a read on a timer (`knownEngine`).
|
|
503
|
+
export function readSettings({ config, supervisor, store }, { search = true } = {}) {
|
|
442
504
|
const products = store.listProducts();
|
|
443
505
|
const status = supervisor.status();
|
|
444
506
|
const sessions = [...supervisor.sessions.values()];
|
|
@@ -469,10 +531,17 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
469
531
|
// waiting, because a page she chose to open interrupts nobody.
|
|
470
532
|
const troubles = status.accountTrouble ?? {};
|
|
471
533
|
const accounts = (profiles.length ? profiles : ['default']).map((profile) => {
|
|
472
|
-
|
|
534
|
+
// THE HOME THE WORKSPACE IS CONFIGURED WITH, not this process's own. Both
|
|
535
|
+
// of these read a login out of a folder, and both of them defaulted to
|
|
536
|
+
// `os.homedir()` while the list of folders above came from `config.home`,
|
|
537
|
+
// so a workspace pointed anywhere else drew rows for its own folders and
|
|
538
|
+
// read somebody else's login into them.
|
|
539
|
+
const plan = readPlan(profile, { home: config.home });
|
|
473
540
|
// A reason filed before an ended subscription had its own name still reads
|
|
474
541
|
// as an admin's block; the login's file says which it is.
|
|
475
|
-
|
|
542
|
+
// THE SUBSCRIPTION'S TROUBLE, not the folder's: one row stands for every
|
|
543
|
+
// folder holding this account (account-discovery.mjs says why).
|
|
544
|
+
const filed = troubleForProfile(troubles, profile, { home: config.home });
|
|
476
545
|
const trouble = filed ? { ...filed, cause: refineCause(filed.cause, plan) } : null;
|
|
477
546
|
const resting = (supervisor._profileCooldown?.[profile] ?? 0) >= now;
|
|
478
547
|
// WHOSE SUBSCRIPTION THIS ROW IS, not merely which folder it lives in.
|
|
@@ -480,14 +549,18 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
480
549
|
// person that one of their accounts had been replaced by the other;
|
|
481
550
|
// main/account-tooling.mjs has how that happens. Null when the
|
|
482
551
|
// folder holds no login, and then the row reads as it always did.
|
|
483
|
-
const identity = accountIdentity(profile === 'default' ? null : profile);
|
|
552
|
+
const identity = accountIdentity(profile === 'default' ? null : profile, { home: config.home });
|
|
484
553
|
return {
|
|
485
554
|
profile,
|
|
486
555
|
email: identity?.email ?? null,
|
|
487
556
|
accountUuid: identity?.accountUuid ?? null,
|
|
488
|
-
// WHICH ONE RUNS,
|
|
489
|
-
//
|
|
490
|
-
|
|
557
|
+
// WHICH ONE RUNS, AND ONE OF THEM ALWAYS DOES (w-dac993a554). This was
|
|
558
|
+
// false on every row until somebody picked, because until then every
|
|
559
|
+
// account really did take a share of the work. One account runs it now,
|
|
560
|
+
// so the supervisor is asked which rather than the config file: with
|
|
561
|
+
// nothing picked that is the primary login, and the page says so instead
|
|
562
|
+
// of leaving a person to guess which of their two plans is being spent.
|
|
563
|
+
chosen: (supervisor._profilesFor?.('claude') ?? [])[0] === profile,
|
|
491
564
|
// The default profile is whatever ~/.claude holds; anything else is a
|
|
492
565
|
// second logged-in home directory, and its path is the only name it has.
|
|
493
566
|
label: profile === 'default' ? 'default' : path.basename(profile),
|
|
@@ -519,6 +592,8 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
519
592
|
};
|
|
520
593
|
});
|
|
521
594
|
|
|
595
|
+
// On her phone: every project unless she kept it here (shared/phone-snapshot.mjs).
|
|
596
|
+
const phoneSlugs = new Set(phoneProjectsOf(config.phoneProducts, process.env.AGENTBOX_PERSON_ID, phoneEligible(products)));
|
|
522
597
|
const projects = products.map((product) => {
|
|
523
598
|
let instructions = '';
|
|
524
599
|
try { instructions = supervisor.readProjectInstructions(product.slug); } catch {}
|
|
@@ -540,6 +615,9 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
540
615
|
// workspace default and never a strip of Claude Code jargon on a page
|
|
541
616
|
// she opens to change her rules.
|
|
542
617
|
autonomous: (config.autonomousProducts ?? []).includes(product.slug),
|
|
618
|
+
// ON HER PHONE WITH THE MAC SHUT (docs/cloud/PHONE-PLAN.md): its threads
|
|
619
|
+
// go up to her own rows online on every sync (main/phone-inbox.mjs).
|
|
620
|
+
onPhone: phoneSlugs.has(product.slug),
|
|
543
621
|
permission: override ? permissionMode(override) : 'workspace',
|
|
544
622
|
permissionArgs: override ?? null,
|
|
545
623
|
codexMode: config.projectCodexMode?.[product.slug] ?? 'workspace',
|
|
@@ -564,6 +642,8 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
564
642
|
return {
|
|
565
643
|
archivedProjects,
|
|
566
644
|
workspace: {
|
|
645
|
+
// THE PHONE AS A WHOLE: on unless she turned it off (shared/phone-snapshot.mjs).
|
|
646
|
+
phoneAll: phoneChoiceOf(config.phoneProducts, process.env.AGENTBOX_PERSON_ID, phoneEligible(products)).all,
|
|
567
647
|
agentsRunning: !supervisor.paused,
|
|
568
648
|
// The number picked on the menu, for the whole computer, or what is
|
|
569
649
|
// running as the limit now when nothing was picked.
|
|
@@ -608,9 +688,11 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
608
688
|
// comes back with ONE entry and this screen draws exactly what it drew
|
|
609
689
|
// before. A page that derived its own list would offer her a choice the
|
|
610
690
|
// supervisor is about to refuse.
|
|
611
|
-
...engineSettings(supervisor, config),
|
|
691
|
+
...engineSettings(supervisor, config, { search }),
|
|
612
692
|
permission: permissionMode(workspaceArgs),
|
|
613
693
|
permissionArgs: workspaceArgs,
|
|
694
|
+
cloudPermission: config.cloudPermission ?? CLOUD_CLAUDE_DEFAULT,
|
|
695
|
+
cloudCodexMode: config.cloudCodexMode ?? CLOUD_CODEX_DEFAULT,
|
|
614
696
|
// ONE SWITCH FOR EVERYTHING THAT LEAVES THE MACHINE, and it is on when
|
|
615
697
|
// Agentbox is installed (legal/privacy.html, section 10). Off stops the
|
|
616
698
|
// counts AND the crash reports; there is deliberately no partial mode and
|
|
@@ -623,6 +705,8 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
623
705
|
// ADHD mode: whether the ADHD rules ride under hers (w-5737fe67cf). Off
|
|
624
706
|
// unless she turned it on, so only `true` means on.
|
|
625
707
|
adhdMode: config.adhdMode === true,
|
|
708
|
+
importNew: config.importNew === true,
|
|
709
|
+
alpha: alphaFeatures(config),
|
|
626
710
|
// The corner tag over other apps (w-dafae58a23). On unless she turned it
|
|
627
711
|
// off here, which is the only place it turns off for good.
|
|
628
712
|
cornerTag: config.cornerTag !== false,
|
|
@@ -650,11 +734,11 @@ export function readSettings({ config, supervisor, store }) {
|
|
|
650
734
|
// Looked up again on every read of this screen, not taken from boot.
|
|
651
735
|
// Someone who reads "install it, then open this screen again" and does
|
|
652
736
|
// exactly that has to see it turn found, without restarting the app.
|
|
653
|
-
...claudeState(config),
|
|
737
|
+
...claudeState(config, { search }),
|
|
654
738
|
// AND WHETHER CODEX IS, because the app needs one of the two and not
|
|
655
739
|
// both: the last card of the walk only shuts the inbox when neither is
|
|
656
740
|
// here (renderer/src/App.tsx).
|
|
657
|
-
...codexFoundState(config),
|
|
741
|
+
...codexFoundState(config, {}, { search }),
|
|
658
742
|
// AND WHAT THIS MAC'S CLAUDE CODE CALLS ITS MODELS.
|
|
659
743
|
//
|
|
660
744
|
// In the same trip, and for the same reason the line above is looked up
|
|
@@ -706,7 +790,7 @@ function engineTroubleFor(supervisor, engine) {
|
|
|
706
790
|
return trouble ? engineTroubleNote(trouble.cause) : null;
|
|
707
791
|
}
|
|
708
792
|
|
|
709
|
-
function engineSettings(supervisor, config) {
|
|
793
|
+
function engineSettings(supervisor, config, { search = true } = {}) {
|
|
710
794
|
const choices = supervisor.engineChoices();
|
|
711
795
|
const engine = supervisor.engineFacts().workspace;
|
|
712
796
|
// WHETHER THIS MAC HAS ASKED TO HEAR ABOUT CODEX AT ALL, which is a different
|
|
@@ -731,7 +815,7 @@ function engineSettings(supervisor, config) {
|
|
|
731
815
|
// links the install, which is the question that person had.
|
|
732
816
|
const codexIsHome = engine === 'codex';
|
|
733
817
|
const codex = {
|
|
734
|
-
...codexState(config),
|
|
818
|
+
...codexState(config, {}, { search }),
|
|
735
819
|
trouble: engineTroubleFor(supervisor, 'codex'),
|
|
736
820
|
account: codexAccount(supervisor._codexHome()),
|
|
737
821
|
// EVERY CODEX LOGIN ON THE MAC, NOT JUST THE FIRST. The supervisor has
|
|
@@ -746,6 +830,7 @@ function engineSettings(supervisor, config) {
|
|
|
746
830
|
return { engine, engineChoices: choices, codex, codexModels: [], codexModelDefault: null, codexModel: null };
|
|
747
831
|
}
|
|
748
832
|
const home = supervisor._codexHome();
|
|
833
|
+
const offered = supervisor._codexOfferHomes();
|
|
749
834
|
return {
|
|
750
835
|
engine,
|
|
751
836
|
engineChoices: choices,
|
|
@@ -754,9 +839,12 @@ function engineSettings(supervisor, config) {
|
|
|
754
839
|
// strip in the model drawer draws the picked model's list, so they travel
|
|
755
840
|
// beside the name rather than as a list of their own that could disagree
|
|
756
841
|
// with it.
|
|
757
|
-
codexModels:
|
|
842
|
+
codexModels: codexModelsAcross(offered).map((m) => ({
|
|
758
843
|
id: m.id, label: m.label, levels: m.levels.map((l) => l.id), defaultLevel: m.defaultLevel,
|
|
759
844
|
})),
|
|
845
|
+
// Set when every login offered is on ChatGPT's free plan, so the menu can
|
|
846
|
+
// say why Codex lists so few models.
|
|
847
|
+
codexFreePlan: codexFreePlan(offered),
|
|
760
848
|
// What her own `codex` in a terminal runs, so the card's word and her
|
|
761
849
|
// terminal cannot disagree. Null is a real answer and the card says
|
|
762
850
|
// "Codex's own" for it rather than guessing (renderer/src/models.ts).
|
|
@@ -786,12 +874,15 @@ const withSlug = (list, slug, on) => {
|
|
|
786
874
|
// `paused` and `driven` were the other three and all three are gone from the
|
|
787
875
|
// app: the first two because she could not tell what they did and would never
|
|
788
876
|
// have used them, the third because the self-driving it belonged to is deleted.
|
|
789
|
-
export function setProjectSetting({ config, supervisor }, { product, key, value }) {
|
|
877
|
+
export function setProjectSetting({ config, supervisor, store }, { product, key, value }) {
|
|
790
878
|
if (!product) throw new Error('no project');
|
|
791
879
|
switch (key) {
|
|
792
880
|
case 'autonomous':
|
|
793
881
|
saveConfig(config, { autonomousProducts: withSlug(config.autonomousProducts, product, !!value) });
|
|
794
882
|
break;
|
|
883
|
+
case 'phone':
|
|
884
|
+
saveConfig(config, { phoneProducts: withPhoneProject(config.phoneProducts, process.env.AGENTBOX_PERSON_ID, product, !!value, phoneEligible(store?.listProducts?.() ?? [])) });
|
|
885
|
+
break;
|
|
795
886
|
// WHICH OF HER CLAUDE CODE AGENTS THIS PROJECT TOOK. Names only: the files
|
|
796
887
|
// stay where their author put them and Agentbox never copies or moves one,
|
|
797
888
|
// so a list here that has gone stale costs nothing and an agent she
|
|
@@ -869,7 +960,9 @@ export function setProjectSetting({ config, supervisor }, { product, key, value
|
|
|
869
960
|
* not signed in.
|
|
870
961
|
*/
|
|
871
962
|
function codexAccountRows(supervisor) {
|
|
872
|
-
|
|
963
|
+
// THE ONE THAT RUNS, the same way the Claude rows answer it: the supervisor's
|
|
964
|
+
// own pick, which is the chosen account or the primary login (w-dac993a554).
|
|
965
|
+
const chosen = supervisor._profilesFor?.('codex')?.[0] ?? null;
|
|
873
966
|
return supervisor._codexProfiles().map((profile) => {
|
|
874
967
|
const home = supervisor._codexProfileHome(profile);
|
|
875
968
|
const id = codexAccount(home);
|
|
@@ -881,8 +974,7 @@ function codexAccountRows(supervisor) {
|
|
|
881
974
|
planNamed: id?.planNamed ?? false,
|
|
882
975
|
accountId: id?.accountId ?? null,
|
|
883
976
|
signedIn: !!id,
|
|
884
|
-
// WHICH ONE RUNS
|
|
885
|
-
// runs and the card says so rather than marking one at random.
|
|
977
|
+
// WHICH ONE RUNS, and one of them always does (`chosen` above).
|
|
886
978
|
chosen: chosen === profile,
|
|
887
979
|
};
|
|
888
980
|
});
|
|
@@ -927,9 +1019,12 @@ export function addCodexAccount({ config, supervisor }) {
|
|
|
927
1019
|
* ordinary reason for wanting it: a work login and a personal login, both
|
|
928
1020
|
* live, on one Mac.
|
|
929
1021
|
*
|
|
930
|
-
*
|
|
931
|
-
*
|
|
932
|
-
*
|
|
1022
|
+
* Main makes the folder and the terminal is left with the browser half, which
|
|
1023
|
+
* is genuinely hers. UNLIKE CODEX, NOTHING IS WRITTEN INTO THE CONFIG: the
|
|
1024
|
+
* folder is the shape main/account-discovery.mjs finds, so the account appears
|
|
1025
|
+
* the moment its sign-in lands and never before. Registering it first put an
|
|
1026
|
+
* abandoned sign-in in Settings as a "Not signed in" account and handed it
|
|
1027
|
+
* every other task (tests/an-account-shows-once-and-only-once-it-is-signed-in).
|
|
933
1028
|
*
|
|
934
1029
|
* THE TOOLING IS LINKED AT CREATION, which the Codex side has no equivalent of.
|
|
935
1030
|
* `linkAccountTooling` otherwise runs at the first spawn, and the first thing
|
|
@@ -939,9 +1034,6 @@ export function addCodexAccount({ config, supervisor }) {
|
|
|
939
1034
|
*/
|
|
940
1035
|
export function addClaudeAccount({ config, supervisor }) {
|
|
941
1036
|
const made = makeClaudeHome({ home: config.home });
|
|
942
|
-
const existing = (config.authProfiles ?? []).map((x) => x || 'default');
|
|
943
|
-
const list = existing.length ? existing : ['default'];
|
|
944
|
-
saveConfig(config, { authProfiles: [...list, made.profile] });
|
|
945
1037
|
// A failure here is a folder without her skills in it, which is a smaller
|
|
946
1038
|
// thing than a sign in that does not happen: the links are retried at every
|
|
947
1039
|
// spawn anyway.
|
|
@@ -1026,22 +1118,26 @@ export function leftoverSettings({ config, supervisor }) {
|
|
|
1026
1118
|
// Codex, 2026-10-05).
|
|
1027
1119
|
if (!on) {
|
|
1028
1120
|
if (total && stoppable) {
|
|
1029
|
-
now = `Right now finished agents have left ${total} program${total === 1 ? '' : 's'} running; turning this on stops ${stoppable === total ? (total === 1 ? 'it' : 'them') : `${stoppable} of them`}
|
|
1121
|
+
now = `Right now finished agents have left ${total} program${total === 1 ? '' : 's'} running; turning this on stops ${stoppable === total ? (total === 1 ? 'it' : 'them') : `${stoppable} of them`} when you close their tasks.`;
|
|
1030
1122
|
}
|
|
1031
1123
|
return { on, now };
|
|
1032
1124
|
}
|
|
1033
1125
|
{
|
|
1034
1126
|
if (!total) now = 'Nothing left running by finished agents.';
|
|
1035
1127
|
else {
|
|
1036
|
-
const
|
|
1128
|
+
const timed = list.filter((l) => l.programs && l.stopsAt);
|
|
1129
|
+
const next = timed.map((l) => l.stopsAt).sort((a, b) => a - b)[0];
|
|
1130
|
+
const soon = timed.reduce((n, l) => n + l.programs, 0);
|
|
1131
|
+
const open = stoppable - soon;
|
|
1037
1132
|
const when = (ms) => {
|
|
1038
1133
|
const m = Math.max(1, Math.round((ms - Date.now()) / 60_000));
|
|
1039
1134
|
return m >= 60 ? `${Math.floor(m / 60)} h${m % 60 ? ` ${m % 60} m` : ''}` : `${m} m`;
|
|
1040
1135
|
};
|
|
1041
|
-
|
|
1042
|
-
if (
|
|
1043
|
-
if (
|
|
1044
|
-
|
|
1136
|
+
const parts = [];
|
|
1137
|
+
if (soon) parts.push(`${soon} ${next > Date.now() ? `stop${soon === 1 ? 's' : ''} in ${when(next)}` : `${soon === 1 ? 'is' : 'are'} stopping`}`);
|
|
1138
|
+
if (open) parts.push(`${open} stop${open === 1 ? 's' : ''} when you close ${open === 1 ? 'its task' : 'their tasks'}`);
|
|
1139
|
+
if (kept) parts.push(`${kept} ${kept === 1 ? 'is' : 'are'} kept`);
|
|
1140
|
+
now = `Finished agents have left ${total} program${total === 1 ? '' : 's'} running. ${parts.join('; ')}.`;
|
|
1045
1141
|
const survivors = s?.survivors?.length ?? 0;
|
|
1046
1142
|
if (survivors) now += ` ${survivors} did not stop when asked.`;
|
|
1047
1143
|
}
|
|
@@ -1077,8 +1173,31 @@ export function strayFolderSettings({ supervisor }, home = os.homedir()) {
|
|
|
1077
1173
|
return { count, now };
|
|
1078
1174
|
}
|
|
1079
1175
|
|
|
1080
|
-
export function
|
|
1176
|
+
export function cornerTagTurnedOff({ key, value } = {}) {
|
|
1177
|
+
return key === 'cornerTag' && !value;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
export function countsTurnedOff({ key, value } = {}) {
|
|
1181
|
+
return key === 'diagnostics' && !value;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
export function setWorkspaceSetting({ config, supervisor, store }, { key, value }) {
|
|
1081
1185
|
switch (key) {
|
|
1186
|
+
// EVERY PROJECT ON HER PHONE, or none (shared/phone-snapshot.mjs). Which
|
|
1187
|
+
// ones she keeps here is remembered either way.
|
|
1188
|
+
case 'phoneAll':
|
|
1189
|
+
saveConfig(config, { phoneProducts: withPhoneAll(config.phoneProducts, process.env.AGENTBOX_PERSON_ID, !!value, phoneEligible(store?.listProducts?.() ?? [])) });
|
|
1190
|
+
break;
|
|
1191
|
+
// THE DROPDOWN'S WHOLE ANSWER AT ONCE: on or off, and which projects stay
|
|
1192
|
+
// on this computer. Only project slugs that exist are kept.
|
|
1193
|
+
case 'phoneProjects': {
|
|
1194
|
+
const person = process.env.AGENTBOX_PERSON_ID;
|
|
1195
|
+
if (!person) throw new Error('sign in first');
|
|
1196
|
+
const every = phoneEligible(store?.listProducts?.() ?? []);
|
|
1197
|
+
const except = Array.isArray(value?.except) ? value.except.filter((s) => every.includes(s)) : [];
|
|
1198
|
+
saveConfig(config, { phoneProducts: { owner: person, all: value?.all !== false, except } });
|
|
1199
|
+
break;
|
|
1200
|
+
}
|
|
1082
1201
|
case 'agentsRunning':
|
|
1083
1202
|
supervisor.paused = !value;
|
|
1084
1203
|
supervisor.onChange?.();
|
|
@@ -1139,6 +1258,43 @@ export function setWorkspaceSetting({ config, supervisor }, { key, value }) {
|
|
|
1139
1258
|
break;
|
|
1140
1259
|
// STOP WHAT FINISHED AGENTS LEAVE RUNNING (main/leftovers.mjs). Turning it
|
|
1141
1260
|
// on records the moment, which is the earliest the clock may start from.
|
|
1261
|
+
// WHERE THREADS RUN (renderer/src/cloud-menu.ts): 'mac' turns cloud runs
|
|
1262
|
+
// off, 'full' sends what does not fit here, 'all' sends everything first.
|
|
1263
|
+
// Read by the supervisor per call, so it takes effect on the next tick.
|
|
1264
|
+
case 'cloudRuns': {
|
|
1265
|
+
const map = { mac: false, full: null, all: 'all' };
|
|
1266
|
+
if (!(value in map)) throw new Error(`unknown cloud mode: ${value}`);
|
|
1267
|
+
// Turning the cloud on to one meaning makes that the one C goes back to.
|
|
1268
|
+
const patch = value === 'mac' ? { cloudRuns: false } : { cloudRuns: map[value], cloudWhenOn: value };
|
|
1269
|
+
saveConfig(config, patch);
|
|
1270
|
+
Object.assign(config, patch);
|
|
1271
|
+
supervisor.wake?.();
|
|
1272
|
+
supervisor.onChange?.();
|
|
1273
|
+
break;
|
|
1274
|
+
}
|
|
1275
|
+
// WHAT "ON" MEANS (renderer/src/cloud-menu.ts): kept while the cloud is
|
|
1276
|
+
// off, and taking effect at once while it is on.
|
|
1277
|
+
case 'cloudWhenOn': {
|
|
1278
|
+
if (value !== 'full' && value !== 'all') throw new Error(`unknown meaning of on: ${value}`);
|
|
1279
|
+
const patch = config.cloudRuns === false ? { cloudWhenOn: value } : { cloudWhenOn: value, cloudRuns: value === 'all' ? 'all' : null };
|
|
1280
|
+
saveConfig(config, patch);
|
|
1281
|
+
Object.assign(config, patch);
|
|
1282
|
+
supervisor.wake?.();
|
|
1283
|
+
supervisor.onChange?.();
|
|
1284
|
+
break;
|
|
1285
|
+
}
|
|
1286
|
+
// THE CLOUD'S OWN MODE PER ENGINE, CLOUD_SAME for this computer's, or null
|
|
1287
|
+
// for the cloud's default (main/cloud-permission.mjs).
|
|
1288
|
+
case 'cloudPermission':
|
|
1289
|
+
case 'cloudCodexMode': {
|
|
1290
|
+
const known = key === 'cloudPermission' ? CLAUDE_MODES.includes(value) : isCodexMode(value);
|
|
1291
|
+
if (value != null && value !== CLOUD_SAME && !known) throw new Error(`unknown permission mode: ${value}`);
|
|
1292
|
+
const patch = { [key]: value ?? null };
|
|
1293
|
+
saveConfig(config, patch);
|
|
1294
|
+
Object.assign(config, patch);
|
|
1295
|
+
supervisor.onChange?.();
|
|
1296
|
+
break;
|
|
1297
|
+
}
|
|
1142
1298
|
case 'cleanupLeftovers':
|
|
1143
1299
|
saveConfig(config, value ? { cleanupLeftovers: true, cleanupLeftoversSince: Date.now() } : { cleanupLeftovers: false });
|
|
1144
1300
|
supervisor.setLeftoverCleanup?.(!!value)?.catch?.((e) => console.warn('zero: leftovers:', e.message));
|
|
@@ -1162,6 +1318,26 @@ export function setWorkspaceSetting({ config, supervisor }, { key, value }) {
|
|
|
1162
1318
|
case 'adhdMode':
|
|
1163
1319
|
saveConfig(config, { adhdMode: !!value });
|
|
1164
1320
|
break;
|
|
1321
|
+
// New chats from Claude Code and Codex come in on their own
|
|
1322
|
+
// (main/new-chats-watch.mjs), only those started after it went on.
|
|
1323
|
+
case 'importNew':
|
|
1324
|
+
if (!value) saveConfig(config, { importNew: false });
|
|
1325
|
+
else if (config.importNew !== true) saveConfig(config, { importNew: true, importNewSince: Date.now() });
|
|
1326
|
+
break;
|
|
1327
|
+
// Rooms is read on every snapshot.
|
|
1328
|
+
case 'alphaRooms':
|
|
1329
|
+
saveConfig(config, { alphaRooms: !!value });
|
|
1330
|
+
supervisor.onChange?.();
|
|
1331
|
+
break;
|
|
1332
|
+
case 'alphaTeammates':
|
|
1333
|
+
saveConfig(config, { alphaTeammates: !!value });
|
|
1334
|
+
supervisor.onChange?.();
|
|
1335
|
+
supervisor.wake?.();
|
|
1336
|
+
break;
|
|
1337
|
+
case 'alphaMultiplayer':
|
|
1338
|
+
saveConfig(config, { alphaMultiplayer: !!value });
|
|
1339
|
+
supervisor.onChange?.();
|
|
1340
|
+
break;
|
|
1165
1341
|
// THE CORNER TAG (w-dafae58a23). Turning it back on also ends any hide, so
|
|
1166
1342
|
// the switch does what it says the moment she flips it.
|
|
1167
1343
|
case 'cornerTag':
|
|
@@ -1175,15 +1351,15 @@ export function setWorkspaceSetting({ config, supervisor }, { key, value }) {
|
|
|
1175
1351
|
// in one object keyed by engine is what stops a Codex pick being read as a
|
|
1176
1352
|
// Claude one, which is the collision `_accountKey` exists to prevent.
|
|
1177
1353
|
//
|
|
1178
|
-
// NULL CLEARS IT, and clearing means
|
|
1179
|
-
//
|
|
1180
|
-
//
|
|
1181
|
-
// the fleet.
|
|
1354
|
+
// NULL CLEARS IT, and clearing means the primary login runs the work again.
|
|
1355
|
+
// `Supervisor#_theOneAccount` also ignores a name that no longer exists, so
|
|
1356
|
+
// a login she removes cannot wedge the fleet.
|
|
1182
1357
|
case 'activeAccount': {
|
|
1183
1358
|
const engineId = value?.engine;
|
|
1184
1359
|
if (!isEngine(engineId)) throw new Error(`unknown coding agent: ${engineId}`);
|
|
1185
1360
|
const profile = typeof value?.profile === 'string' && value.profile ? value.profile : null;
|
|
1186
1361
|
saveConfig(config, { activeAccount: { ...(config.activeAccount ?? {}), [engineId]: profile } });
|
|
1362
|
+
supervisor.accountChosen?.(engineId, profile);
|
|
1187
1363
|
supervisor.onChange?.();
|
|
1188
1364
|
break;
|
|
1189
1365
|
}
|