glimmervoid 0.31.0 → 0.32.1
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/dist/bin/glimmervoid.js +19 -14
- package/dist/chunks/{adapters-gn7ulNO4.js → adapters-BS_7o8fj.js} +28 -23
- package/dist/chunks/{adapters-ClA_GbtA.js → adapters-Bn-dQ02i.js} +1 -1
- package/dist/chunks/{agent-api-cli-DAA7Jx8N.js → agent-api-cli-BR0GVDn6.js} +21 -5
- package/dist/chunks/agent-api-core-DUiWHSHg.js +201 -0
- package/dist/chunks/{agent-setup-cli-CiJSDWSo.js → agent-setup-cli-BqYcwfOs.js} +1 -1
- package/dist/chunks/child-process-safe-B3zcPdFM.js +2 -0
- package/dist/chunks/{child-process-safe-Ch-Zgxqs.js → child-process-safe-DDELk9XC.js} +2 -1
- package/dist/chunks/{config-W1Sv-iPK.js → config-B6BkTOcE.js} +20 -6
- package/dist/chunks/config-store-C8Ry8ZFD.js +2 -0
- package/dist/chunks/{config-store-BCy4FHNG.js → config-store-aZpWeX92.js} +14 -5
- package/dist/chunks/{contracts-3LkrilQX.js → contracts-DzDg-Z9I.js} +100 -7
- package/dist/chunks/git-version-CrLW4a6r.js +58 -0
- package/dist/chunks/{grok-CXKeSt2z.js → grok-7Z5KcgcY.js} +1 -2
- package/dist/chunks/{knowledge-graph-cli-D2tt5hPn.js → knowledge-graph-cli-D5Gf87Y7.js} +2 -2
- package/dist/chunks/{main-DyTCWIu2.js → main-BG6iHwoY.js} +3724 -1928
- package/dist/chunks/{pair-cli-BbCBfd6l.js → pair-cli-DQkrt_-s.js} +2 -2
- package/dist/chunks/{remote-config-DKIH_VxM.js → remote-config-Da4C7tMG.js} +2 -2
- package/dist/chunks/rtk-resolver-CIVLE_xk.js +2 -0
- package/dist/chunks/{rtk-resolver-BGDzw5XK.js → rtk-resolver-jJxy_Mrt.js} +1 -1
- package/dist/chunks/{sandbox-deps-BPKE-ylr.js → sandbox-deps-DuaNFq7n.js} +1 -1
- package/dist/chunks/{session-fc4pFbon.js → session-Dtkp9o3r.js} +28 -2
- package/dist/chunks/{visions-cli-CT5rjiwf.js → visions-cli-BhFdym5n.js} +1 -1
- package/dist/chunks/{visions-setup-BmOkI-QE.js → visions-setup-CfgNHiG3.js} +1 -1
- package/dist/client/assets/index-BxU3Ww0L.css +1 -0
- package/dist/client/assets/index-Co4S7tnh.js +254 -0
- package/dist/client/index.html +2 -2
- package/dist/scripts/postinstall-path-check.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/session/hook-tool-relay.js +1 -1
- package/dist/session/sandbox-open-launcher.js +42 -3
- package/dist/session/statusline-relay.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/agent-api-core-hVcT26JW.js +0 -112
- package/dist/chunks/child-process-safe-BKPZ-5qQ.js +0 -2
- package/dist/chunks/config-store-DbBp7LJZ.js +0 -2
- package/dist/chunks/rtk-resolver-D4Nke1Fr.js +0 -2
- package/dist/client/assets/index-C6KD8lgZ.css +0 -1
- package/dist/client/assets/index-CThQEAEy.js +0 -249
package/dist/bin/glimmervoid.js
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
import { o as nodePtyRebuildHint, r as firstLine, t as probeNodePty } from "../chunks/node-pty-preflight-C8QIlrtU.js";
|
|
3
3
|
import { i as errorText } from "../chunks/text-DoirglWV.js";
|
|
4
4
|
import { a as packageRoot } from "../chunks/runtime-paths-BPoxENmK.js";
|
|
5
|
-
import { t as AGENT_API_VERBS } from "../chunks/session-
|
|
6
|
-
import { i as execSync } from "../chunks/child-process-safe-
|
|
5
|
+
import { t as AGENT_API_VERBS } from "../chunks/session-Dtkp9o3r.js";
|
|
6
|
+
import { i as execSync } from "../chunks/child-process-safe-DDELk9XC.js";
|
|
7
7
|
import { t as renderTable } from "../chunks/ascii-figure-core-pDAwtlKO.js";
|
|
8
8
|
import { n as glimmervoidHomeDir, t as decideConfigPath } from "../chunks/config-path-core-DFt-TemS.js";
|
|
9
|
-
import { i as sandboxDoctorRows, r as probeSandboxDependencies } from "../chunks/sandbox-deps-
|
|
9
|
+
import { i as sandboxDoctorRows, r as probeSandboxDependencies } from "../chunks/sandbox-deps-DuaNFq7n.js";
|
|
10
|
+
import { r as gitDoctorRows, t as probeGitVersion } from "../chunks/git-version-CrLW4a6r.js";
|
|
10
11
|
import { i as pnpmGlobalBinDir, n as npmGlobalBinDir, r as onPath, t as formatPathNotice } from "../chunks/path-doctor-C23VAqeu.js";
|
|
11
12
|
import fs from "node:fs";
|
|
12
13
|
import path from "node:path";
|
|
@@ -106,6 +107,8 @@ Commands:
|
|
|
106
107
|
spawn <prompt> From inside a Glimmervoid session, start a sibling session on that prompt
|
|
107
108
|
attention <note> From inside a Glimmervoid session, flag it as needing the operator
|
|
108
109
|
board From inside a Glimmervoid session, list the live sessions
|
|
110
|
+
push From inside a Glimmervoid session, land its commits on the integration branch and push it
|
|
111
|
+
edit <path> From inside a Glimmervoid session, surface a text file for the operator to edit in the dashboard
|
|
109
112
|
kg [command] Experimental typed knowledge and task graph (Settings > Lanes > Knowledge graph)
|
|
110
113
|
|
|
111
114
|
Options:
|
|
@@ -131,23 +134,23 @@ var SUBCOMMAND_RUNNERS = new Map([
|
|
|
131
134
|
return 0;
|
|
132
135
|
}],
|
|
133
136
|
["pair", async (subcommandArgs) => {
|
|
134
|
-
const { runPairCli } = await import("../chunks/pair-cli-
|
|
137
|
+
const { runPairCli } = await import("../chunks/pair-cli-DQkrt_-s.js");
|
|
135
138
|
return runPairCli(subcommandArgs);
|
|
136
139
|
}],
|
|
137
140
|
["agent", async (subcommandArgs) => {
|
|
138
|
-
const { runAgentSetupCli } = await import("../chunks/agent-setup-cli-
|
|
141
|
+
const { runAgentSetupCli } = await import("../chunks/agent-setup-cli-BqYcwfOs.js");
|
|
139
142
|
return runAgentSetupCli(subcommandArgs);
|
|
140
143
|
}],
|
|
141
144
|
["kg", async (subcommandArgs) => {
|
|
142
|
-
const { runKnowledgeGraphCommand } = await import("../chunks/knowledge-graph-cli-
|
|
145
|
+
const { runKnowledgeGraphCommand } = await import("../chunks/knowledge-graph-cli-D5Gf87Y7.js");
|
|
143
146
|
return runKnowledgeGraphCommand(subcommandArgs);
|
|
144
147
|
}],
|
|
145
148
|
["visions", async (subcommandArgs) => {
|
|
146
|
-
const { runVisionsCli } = await import("../chunks/visions-cli-
|
|
149
|
+
const { runVisionsCli } = await import("../chunks/visions-cli-BhFdym5n.js");
|
|
147
150
|
return runVisionsCli(subcommandArgs);
|
|
148
151
|
}],
|
|
149
152
|
...AGENT_API_VERBS.map((verb) => [verb, async (subcommandArgs, subcommandName) => {
|
|
150
|
-
const { runAgentApiCli } = await import("../chunks/agent-api-cli-
|
|
153
|
+
const { runAgentApiCli } = await import("../chunks/agent-api-cli-BR0GVDn6.js");
|
|
151
154
|
return runAgentApiCli([subcommandName, ...subcommandArgs]);
|
|
152
155
|
}])
|
|
153
156
|
]);
|
|
@@ -201,7 +204,7 @@ async function readDeclaredCustomAgents() {
|
|
|
201
204
|
declared: [],
|
|
202
205
|
error: null
|
|
203
206
|
};
|
|
204
|
-
const { loadConfigFile } = await import("../chunks/config-store-
|
|
207
|
+
const { loadConfigFile } = await import("../chunks/config-store-C8Ry8ZFD.js");
|
|
205
208
|
try {
|
|
206
209
|
const loaded = loadConfigFile(decided.path, { exitOnError: false });
|
|
207
210
|
if (!loaded.config) return {
|
|
@@ -277,7 +280,7 @@ async function runDoctor() {
|
|
|
277
280
|
}
|
|
278
281
|
switchSection("Agents");
|
|
279
282
|
try {
|
|
280
|
-
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-
|
|
283
|
+
const { listAgentIds, describeAgentResolvability, setCustomAgents } = await import("../chunks/adapters-Bn-dQ02i.js");
|
|
281
284
|
const declaredCustomAgents = await readDeclaredCustomAgents();
|
|
282
285
|
if (declaredCustomAgents.error) line("config", declaredCustomAgents.error);
|
|
283
286
|
setCustomAgents(declaredCustomAgents.declared);
|
|
@@ -285,7 +288,7 @@ async function runDoctor() {
|
|
|
285
288
|
const { label, path: resolvedPath } = describeAgentResolvability(id);
|
|
286
289
|
line(`${id} (${label})`, resolvedPath ?? "not found on PATH");
|
|
287
290
|
}
|
|
288
|
-
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-
|
|
291
|
+
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-BqYcwfOs.js");
|
|
289
292
|
const grokSetup = inspectGrokAgentSetup();
|
|
290
293
|
line("grok hook setup", `${grokSetup.classification}: ${grokSetup.filePath}`);
|
|
291
294
|
} catch (err) {
|
|
@@ -293,7 +296,7 @@ async function runDoctor() {
|
|
|
293
296
|
}
|
|
294
297
|
switchSection("rtk");
|
|
295
298
|
try {
|
|
296
|
-
const { getRtkPath } = await import("../chunks/rtk-resolver-
|
|
299
|
+
const { getRtkPath } = await import("../chunks/rtk-resolver-CIVLE_xk.js");
|
|
297
300
|
line("rtk", getRtkPath() || "not installed (Glimmervoid installs it when the rtk setting is on)");
|
|
298
301
|
} catch (err) {
|
|
299
302
|
line("rtk", `probe failed: ${firstLine(errorText(err))}`);
|
|
@@ -301,8 +304,8 @@ async function runDoctor() {
|
|
|
301
304
|
switchSection("Sane YOLO");
|
|
302
305
|
try {
|
|
303
306
|
const { resolvePackageBin } = await import("../chunks/runtime-paths-DU5jBEEO.js");
|
|
304
|
-
const { execFileSync } = await import("../chunks/child-process-safe-
|
|
305
|
-
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-
|
|
307
|
+
const { execFileSync } = await import("../chunks/child-process-safe-B3zcPdFM.js");
|
|
308
|
+
const { inspectGrokAgentSetup } = await import("../chunks/agent-setup-cli-BqYcwfOs.js");
|
|
306
309
|
const binPath = resolvePackageBin("cc-safety-net", "cc-safety-net");
|
|
307
310
|
line("Sane YOLO", binPath || "not installed");
|
|
308
311
|
if (binPath) line("cc-safety-net version", execFileSync(process.execPath, [binPath, "--version"], {
|
|
@@ -327,6 +330,8 @@ async function runDoctor() {
|
|
|
327
330
|
platform,
|
|
328
331
|
exec: execSync
|
|
329
332
|
}))) line(label, value);
|
|
333
|
+
switchSection("Git");
|
|
334
|
+
for (const [label, value] of gitDoctorRows(probeGitVersion())) line(label, value);
|
|
330
335
|
switchSection("Config");
|
|
331
336
|
line("resolved config", resolveConfigPathReadOnly());
|
|
332
337
|
flush();
|
|
@@ -1,27 +1,13 @@
|
|
|
1
1
|
import { o as relayPath } from "./runtime-paths-BPoxENmK.js";
|
|
2
|
-
import {
|
|
3
|
-
import { r as execFileSync } from "./child-process-safe-
|
|
2
|
+
import { C as firstDetailLine, f as PendingPromptQuestion, u as PROMPT_DETAIL_HIDDEN_CHARACTERS, w as toolDetailFieldValue } from "./session-Dtkp9o3r.js";
|
|
3
|
+
import { r as execFileSync } from "./child-process-safe-DDELk9XC.js";
|
|
4
4
|
import { n as resolveAgentCommand, t as buildAgentSpawnCommand } from "./spawn-command-Cc40FiZI.js";
|
|
5
5
|
import { n as isRecord } from "./coerce-NSst8oRP.js";
|
|
6
|
-
import { c as buildAgentEnv, i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, t as grok } from "./grok-
|
|
6
|
+
import { c as buildAgentEnv, i as isSpinnerChar, n as classifyAgentTitle, r as isBrailleChar, t as grok } from "./grok-7Z5KcgcY.js";
|
|
7
7
|
import { t as buildHookCommand } from "./hook-command-core-DclEoE9e.js";
|
|
8
|
-
import "./contracts-
|
|
8
|
+
import "./contracts-DzDg-Z9I.js";
|
|
9
9
|
import { n as mergeCodexPreToolUse, t as HOOK_TOOLS } from "./hook-tools-UX2fmt81.js";
|
|
10
10
|
import fs from "node:fs";
|
|
11
|
-
//#region session/core/anti-slop-prompt.ts
|
|
12
|
-
var ANTI_SLOP_NOTE = [
|
|
13
|
-
"Code hygiene for this session:",
|
|
14
|
-
"Write comments only to explain why, never narration that restates the code (no Now-we, This-function, or Step-1 openers).",
|
|
15
|
-
"Do not leave debug statements (console.log, print, debugger) in committed code.",
|
|
16
|
-
"Never swallow exceptions: no empty catch blocks and no catch that only logs and continues.",
|
|
17
|
-
"No placeholder stubs or in-a-real-implementation hand-waving; implement the real thing or stop and ask.",
|
|
18
|
-
"Do not silence type or lint errors with as-any, ts-ignore, or eslint-disable; fix the cause.",
|
|
19
|
-
"Avoid speculative wrappers and single-use indirection. Prefer deleting code over adding it."
|
|
20
|
-
].join(" ");
|
|
21
|
-
function buildAntiSlopArgs(enabled) {
|
|
22
|
-
return enabled ? ["--append-system-prompt", ANTI_SLOP_NOTE] : [];
|
|
23
|
-
}
|
|
24
|
-
//#endregion
|
|
25
11
|
//#region session/adapters/claude-code.ts
|
|
26
12
|
var ID$1 = "claude-code";
|
|
27
13
|
var COMMAND_NAME$1 = "claude";
|
|
@@ -175,7 +161,29 @@ function buildEnv$1(baseEnv, extraEnv, options) {
|
|
|
175
161
|
return buildAgentEnv(baseEnv, extraEnv, envProfile$2, options);
|
|
176
162
|
}
|
|
177
163
|
var settingsArgs = (settingsPath) => ["--settings", settingsPath];
|
|
178
|
-
|
|
164
|
+
var SESSION_ID_FLAG = "--session-id";
|
|
165
|
+
function requestedSessionId(extraArgs) {
|
|
166
|
+
const flagIndex = extraArgs.indexOf(SESSION_ID_FLAG);
|
|
167
|
+
if (flagIndex !== -1) return extraArgs[flagIndex + 1] ?? null;
|
|
168
|
+
const assignment = extraArgs.find((argument) => argument.startsWith(`${SESSION_ID_FLAG}=`));
|
|
169
|
+
return assignment ? assignment.slice(13) : null;
|
|
170
|
+
}
|
|
171
|
+
function launchSessionId({ resumeSessionId, extraArgs, generatedId }) {
|
|
172
|
+
const knownSessionId = resumeSessionId ?? requestedSessionId(extraArgs);
|
|
173
|
+
if (knownSessionId) return {
|
|
174
|
+
agentSessionId: knownSessionId,
|
|
175
|
+
extraArgs: [...extraArgs]
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
agentSessionId: generatedId,
|
|
179
|
+
extraArgs: [
|
|
180
|
+
...extraArgs,
|
|
181
|
+
SESSION_ID_FLAG,
|
|
182
|
+
generatedId
|
|
183
|
+
]
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function buildArgs$1({ dangerouslySkipPermissions = false, resumeSessionId = null, extraArgs = [], initialPrompt = null } = {}) {
|
|
179
187
|
const args = dangerouslySkipPermissions ? ["--dangerously-skip-permissions"] : [];
|
|
180
188
|
if (resumeSessionId) args.push("--resume", resumeSessionId);
|
|
181
189
|
for (let index = 0; index < extraArgs.length; index += 1) {
|
|
@@ -187,7 +195,6 @@ function buildArgs$1({ dangerouslySkipPermissions = false, resumeSessionId = nul
|
|
|
187
195
|
if (resumeSessionId && argument.startsWith("--session-id=")) continue;
|
|
188
196
|
args.push(argument);
|
|
189
197
|
}
|
|
190
|
-
args.push(...buildAntiSlopArgs(antiSlopPrompt));
|
|
191
198
|
if (initialPrompt != null) args.push(initialPrompt);
|
|
192
199
|
return args;
|
|
193
200
|
}
|
|
@@ -204,6 +211,7 @@ var claudeCode = {
|
|
|
204
211
|
buildEnv: buildEnv$1,
|
|
205
212
|
buildArgs: buildArgs$1,
|
|
206
213
|
settingsArgs,
|
|
214
|
+
launchSessionId,
|
|
207
215
|
capabilities: {
|
|
208
216
|
hooks: true,
|
|
209
217
|
awaitingInput: true,
|
|
@@ -212,7 +220,6 @@ var claudeCode = {
|
|
|
212
220
|
statusLine: true,
|
|
213
221
|
rtk: true,
|
|
214
222
|
saneYolo: true,
|
|
215
|
-
antiSlop: true,
|
|
216
223
|
compactQuiet: true,
|
|
217
224
|
skipPermissionsFlag: true,
|
|
218
225
|
headless: true
|
|
@@ -407,7 +414,6 @@ var codex = {
|
|
|
407
414
|
statusLine: false,
|
|
408
415
|
rtk: true,
|
|
409
416
|
saneYolo: true,
|
|
410
|
-
antiSlop: false,
|
|
411
417
|
compactQuiet: false,
|
|
412
418
|
skipPermissionsFlag: true,
|
|
413
419
|
headless: true
|
|
@@ -427,7 +433,6 @@ var TITLE_ONLY_CAPABILITIES = Object.freeze({
|
|
|
427
433
|
statusLine: false,
|
|
428
434
|
rtk: false,
|
|
429
435
|
saneYolo: false,
|
|
430
|
-
antiSlop: false,
|
|
431
436
|
compactQuiet: false,
|
|
432
437
|
skipPermissionsFlag: false,
|
|
433
438
|
headless: false
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as describeAgentResolvability, d as setCustomAgents, l as listAgentIds } from "./adapters-
|
|
1
|
+
import { a as describeAgentResolvability, d as setCustomAgents, l as listAgentIds } from "./adapters-BS_7o8fj.js";
|
|
2
2
|
export { describeAgentResolvability, listAgentIds, setCustomAgents };
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { t as errorCode } from "./text-DoirglWV.js";
|
|
2
|
-
import { a as AgentDispatchRequest, n as AGENT_URL_ENV } from "./session-
|
|
2
|
+
import { a as AgentDispatchRequest, c as AgentTicketRequest, n as AGENT_URL_ENV } from "./session-Dtkp9o3r.js";
|
|
3
3
|
import { i as resolveHookTarget } from "./hook-relay-core-DA_bz2KA.js";
|
|
4
4
|
import { n as decideSandboxProxy } from "./sandbox-proxy-core-hnQgKR0T.js";
|
|
5
|
-
import {
|
|
5
|
+
import { c as isAgentApiVerb, l as isOrchestratorAgentVerb } from "./agent-api-core-DUiWHSHg.js";
|
|
6
|
+
import path from "node:path";
|
|
6
7
|
import http from "node:http";
|
|
7
8
|
//#region server/agent-api-cli.ts
|
|
8
9
|
var AGENT_PATH_PREFIX = "/agent/";
|
|
10
|
+
function ticketBody(rest) {
|
|
11
|
+
const parsed = AgentTicketRequest.safeParse({ workId: rest[0] });
|
|
12
|
+
return parsed.success ? parsed.data : null;
|
|
13
|
+
}
|
|
9
14
|
var BODY_BUILDERS = {
|
|
10
15
|
spawn: (rest) => {
|
|
11
16
|
const prompt = rest.join(" ").trim();
|
|
@@ -16,10 +21,17 @@ var BODY_BUILDERS = {
|
|
|
16
21
|
return note ? { note } : null;
|
|
17
22
|
},
|
|
18
23
|
board: () => ({}),
|
|
24
|
+
push: () => ({}),
|
|
25
|
+
edit: (rest) => {
|
|
26
|
+
const docPath = rest.join(" ").trim();
|
|
27
|
+
return docPath ? { path: path.resolve(docPath) } : null;
|
|
28
|
+
},
|
|
19
29
|
dispatch: (rest) => {
|
|
20
30
|
const parsed = AgentDispatchRequest.safeParse(rest[0] === "--ready" ? { readyIntent: rest[1] } : { workId: rest[0] });
|
|
21
31
|
return parsed.success ? parsed.data : null;
|
|
22
|
-
}
|
|
32
|
+
},
|
|
33
|
+
reopen: (rest) => ticketBody(rest),
|
|
34
|
+
cancel: (rest) => ticketBody(rest)
|
|
23
35
|
};
|
|
24
36
|
function bodySaysOk(text) {
|
|
25
37
|
try {
|
|
@@ -110,8 +122,12 @@ async function runAgentApiCli(args) {
|
|
|
110
122
|
}
|
|
111
123
|
const body = BODY_BUILDERS[verb](args.slice(1));
|
|
112
124
|
if (!body) {
|
|
113
|
-
if (verb
|
|
114
|
-
console.error(
|
|
125
|
+
if (isOrchestratorAgentVerb(verb)) {
|
|
126
|
+
console.error(`glimmervoid ${verb}: expected a work id matching wrk-[0-9a-f]{16}`);
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
if (verb === "edit") {
|
|
130
|
+
console.error("glimmervoid edit: this command needs a file path, for example \"glimmervoid edit drafts/post.md\"");
|
|
115
131
|
return 1;
|
|
116
132
|
}
|
|
117
133
|
console.error(`glimmervoid ${verb}: this command needs text, for example "glimmervoid ${verb} check the failing test"`);
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { a as AgentDispatchRequest, i as AgentAttentionRequest, l as ORCHESTRATOR_AGENT_VERBS, o as AgentEditRequest, s as AgentSpawnRequest, t as AGENT_API_VERBS } from "./session-Dtkp9o3r.js";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
var MAX_SPAWNS_IN_FLIGHT = 1;
|
|
4
|
+
var SPAWNABLE_DEPTH = 0;
|
|
5
|
+
var REFUSAL_REASON = "unknown session";
|
|
6
|
+
var INVALID_BODY_STATUS = 400;
|
|
7
|
+
var PUSH_REFUSED_STATUS = 409;
|
|
8
|
+
var PUSH_UNAVAILABLE_REASON = "not-operator-session";
|
|
9
|
+
var PUSH_REFUSAL_COPY = Object.freeze({
|
|
10
|
+
[PUSH_UNAVAILABLE_REASON]: () => "only an operator session or a session it spawned can push",
|
|
11
|
+
"no-worktree": () => "this session has no worktree of its own, so there is nothing of its own to land",
|
|
12
|
+
"merge-in-progress": () => "a merge for this session is already running, so try again when it ends",
|
|
13
|
+
"not-continuable": () => "this session cannot be merged in its current state",
|
|
14
|
+
destroyed: () => "this session is ending",
|
|
15
|
+
"nothing-to-commit": () => "no commit on this branch is missing from the integration branch, so commit your work first",
|
|
16
|
+
"rebase-conflict": ({ base, conflicts = [] }) => `this branch conflicts with ${base} in ${conflicts.join(", ") || "one or more files"}, so rebase onto ${base}, resolve the conflicts, commit, then push again`,
|
|
17
|
+
"not-fast-forward": ({ base }) => `${base} could not be fast-forwarded to this branch, and a push is never forced`,
|
|
18
|
+
"base-diverged": ({ base }) => `the local ${base} and origin/${base} have diverged, which the operator has to reconcile`
|
|
19
|
+
});
|
|
20
|
+
function tokensMatch(presented, expected) {
|
|
21
|
+
if (presented.length !== expected.length) return false;
|
|
22
|
+
try {
|
|
23
|
+
return crypto.timingSafeEqual(Buffer.from(presented, "utf8"), Buffer.from(expected, "utf8"));
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function refused() {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
status: 404,
|
|
32
|
+
reason: REFUSAL_REASON
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function decideAgentRequest({ sessionId, presentedToken, expectedToken, isLoopback }) {
|
|
36
|
+
if (!isLoopback) return refused();
|
|
37
|
+
if (!sessionId) return refused();
|
|
38
|
+
if (!expectedToken) return refused();
|
|
39
|
+
if (!presentedToken) return refused();
|
|
40
|
+
if (!tokensMatch(presentedToken, expectedToken)) return refused();
|
|
41
|
+
return { ok: true };
|
|
42
|
+
}
|
|
43
|
+
function decideSpawnAllowance({ liveChildren, lifetimeSpawns, inFlight, depth }) {
|
|
44
|
+
if (depth !== SPAWNABLE_DEPTH) return {
|
|
45
|
+
ok: false,
|
|
46
|
+
status: 403,
|
|
47
|
+
reason: "a spawned session may not spawn another"
|
|
48
|
+
};
|
|
49
|
+
if (inFlight >= MAX_SPAWNS_IN_FLIGHT) return {
|
|
50
|
+
ok: false,
|
|
51
|
+
status: 429,
|
|
52
|
+
reason: "a spawn is already in flight"
|
|
53
|
+
};
|
|
54
|
+
if (liveChildren >= 3) return {
|
|
55
|
+
ok: false,
|
|
56
|
+
status: 429,
|
|
57
|
+
reason: `at most 3 spawned sessions may be live at once`
|
|
58
|
+
};
|
|
59
|
+
if (lifetimeSpawns >= 10) return {
|
|
60
|
+
ok: false,
|
|
61
|
+
status: 429,
|
|
62
|
+
reason: `this session has used its 10 spawns`
|
|
63
|
+
};
|
|
64
|
+
return { ok: true };
|
|
65
|
+
}
|
|
66
|
+
function isAgentApiVerb(verb) {
|
|
67
|
+
return AGENT_API_VERBS.includes(verb);
|
|
68
|
+
}
|
|
69
|
+
function isOrchestratorAgentVerb(verb) {
|
|
70
|
+
return ORCHESTRATOR_AGENT_VERBS.includes(verb);
|
|
71
|
+
}
|
|
72
|
+
var TICKET_ACTION_STATES = Object.freeze({
|
|
73
|
+
reopen: Object.freeze(["blocked"]),
|
|
74
|
+
cancel: Object.freeze(["open", "blocked"])
|
|
75
|
+
});
|
|
76
|
+
function decideTicketAction({ verb, intentId, ticket }) {
|
|
77
|
+
if (!ticket) return {
|
|
78
|
+
ok: false,
|
|
79
|
+
reason: "no such ticket"
|
|
80
|
+
};
|
|
81
|
+
if (ticket.parent !== intentId) return {
|
|
82
|
+
ok: false,
|
|
83
|
+
reason: "the ticket is not a child of the active intent"
|
|
84
|
+
};
|
|
85
|
+
const allowed = TICKET_ACTION_STATES[verb];
|
|
86
|
+
if (!allowed.includes(ticket.state)) return {
|
|
87
|
+
ok: false,
|
|
88
|
+
reason: `only a ${allowed.join(" or ")} ticket can be ${verb === "reopen" ? "reopened" : "cancelled"}, and this one is ${ticket.state}`
|
|
89
|
+
};
|
|
90
|
+
if (verb === "reopen") return {
|
|
91
|
+
ok: true,
|
|
92
|
+
kind: "transition",
|
|
93
|
+
to: "open"
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
ok: true,
|
|
97
|
+
kind: "close",
|
|
98
|
+
outcome: "cancelled"
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function refuseInvalidBody(issues) {
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
status: INVALID_BODY_STATUS,
|
|
105
|
+
error: issues[0]?.message || "invalid request"
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function parseAgentVerb(verb, payload) {
|
|
109
|
+
if (!isAgentApiVerb(verb)) return {
|
|
110
|
+
ok: false,
|
|
111
|
+
status: 404,
|
|
112
|
+
error: REFUSAL_REASON
|
|
113
|
+
};
|
|
114
|
+
if (verb === "dispatch") {
|
|
115
|
+
const parsed = AgentDispatchRequest.safeParse(payload);
|
|
116
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
117
|
+
return {
|
|
118
|
+
ok: true,
|
|
119
|
+
verb,
|
|
120
|
+
request: parsed.data
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (verb === "reopen" || verb === "cancel") return {
|
|
124
|
+
ok: false,
|
|
125
|
+
status: 403,
|
|
126
|
+
error: `${verb} requires a live factory orchestrator`
|
|
127
|
+
};
|
|
128
|
+
if (verb === "board" || verb === "push") return {
|
|
129
|
+
ok: true,
|
|
130
|
+
verb
|
|
131
|
+
};
|
|
132
|
+
if (verb === "attention") {
|
|
133
|
+
const parsed = AgentAttentionRequest.safeParse(payload);
|
|
134
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
135
|
+
return {
|
|
136
|
+
ok: true,
|
|
137
|
+
verb,
|
|
138
|
+
request: parsed.data
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (verb === "edit") {
|
|
142
|
+
const parsed = AgentEditRequest.safeParse(payload);
|
|
143
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
144
|
+
return {
|
|
145
|
+
ok: true,
|
|
146
|
+
verb,
|
|
147
|
+
request: parsed.data
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
const parsed = AgentSpawnRequest.safeParse(payload);
|
|
151
|
+
if (!parsed.success) return refuseInvalidBody(parsed.error.issues);
|
|
152
|
+
return {
|
|
153
|
+
ok: true,
|
|
154
|
+
verb,
|
|
155
|
+
request: parsed.data
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function describePushLanding(landing) {
|
|
159
|
+
if (!landing.merged) {
|
|
160
|
+
const reason = landing.reason || "unknown";
|
|
161
|
+
const explain = PUSH_REFUSAL_COPY[reason];
|
|
162
|
+
return {
|
|
163
|
+
status: PUSH_REFUSED_STATUS,
|
|
164
|
+
body: {
|
|
165
|
+
ok: false,
|
|
166
|
+
reason,
|
|
167
|
+
error: explain ? explain(landing) : `the merge stopped: ${reason}`
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (landing.pushed) return {
|
|
172
|
+
status: 200,
|
|
173
|
+
body: {
|
|
174
|
+
ok: true,
|
|
175
|
+
landedOn: landing.base ?? null,
|
|
176
|
+
pushed: true
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
return {
|
|
180
|
+
status: 200,
|
|
181
|
+
body: {
|
|
182
|
+
ok: true,
|
|
183
|
+
landedOn: landing.base ?? null,
|
|
184
|
+
pushed: false,
|
|
185
|
+
note: "landed locally and nothing was pushed, because the repository has no origin remote or origin did not take a fast-forward"
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function deriveChildSessionName(parentName, existingNames) {
|
|
190
|
+
const base = `${String(parentName || "").trim() || "session"} agent`;
|
|
191
|
+
const taken = new Set(existingNames);
|
|
192
|
+
let candidate = base;
|
|
193
|
+
let suffix = 1;
|
|
194
|
+
while (taken.has(candidate)) {
|
|
195
|
+
suffix += 1;
|
|
196
|
+
candidate = `${base} ${suffix}`;
|
|
197
|
+
}
|
|
198
|
+
return candidate;
|
|
199
|
+
}
|
|
200
|
+
//#endregion
|
|
201
|
+
export { decideTicketAction as a, isAgentApiVerb as c, decideSpawnAllowance as i, isOrchestratorAgentVerb as l, REFUSAL_REASON as n, deriveChildSessionName as o, decideAgentRequest as r, describePushLanding as s, PUSH_UNAVAILABLE_REASON as t, parseAgentVerb as u };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as isMissingFileError, r as errorMessage } from "./text-DoirglWV.js";
|
|
2
|
-
import { a as classifyGrokHooksFile, o as renderGrokHooksFile, t as grok } from "./grok-
|
|
2
|
+
import { a as classifyGrokHooksFile, o as renderGrokHooksFile, t as grok } from "./grok-7Z5KcgcY.js";
|
|
3
3
|
import { p as writeTextAtomicSync } from "./json-file-oEH9vt-0.js";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
@@ -13,7 +13,8 @@ function split(rest) {
|
|
|
13
13
|
let options;
|
|
14
14
|
let callback;
|
|
15
15
|
for (const v of rest) {
|
|
16
|
-
if (Array.isArray(v) && v.every((entry) => typeof entry === "string"))
|
|
16
|
+
if (Array.isArray(v) && !v.every((entry) => typeof entry === "string")) throw new TypeError("command arguments must all be strings");
|
|
17
|
+
if (Array.isArray(v)) args = v;
|
|
17
18
|
if (typeof v === "function") callback = v;
|
|
18
19
|
if (v && typeof v === "object" && !Array.isArray(v)) options = v;
|
|
19
20
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { x as TaskTitle } from "./session-Dtkp9o3r.js";
|
|
2
2
|
import { n as isRecord } from "./coerce-NSst8oRP.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -84,8 +84,8 @@ var CoherenceOrient = z.looseObject({
|
|
|
84
84
|
})),
|
|
85
85
|
unsynthesized: z.array(z.unknown())
|
|
86
86
|
}).nullable(),
|
|
87
|
-
consequences: z.looseObject({ unverifiedCompletedWork: z.array(z.string()) }),
|
|
88
|
-
verification: z.looseObject({ state: z.string() })
|
|
87
|
+
consequences: z.looseObject({ unverifiedCompletedWork: z.array(z.string()) }).nullable(),
|
|
88
|
+
verification: z.looseObject({ state: z.string() }).nullable()
|
|
89
89
|
});
|
|
90
90
|
var CoherenceWorkInspect = z.looseObject({
|
|
91
91
|
work: z.array(z.looseObject({
|
|
@@ -568,6 +568,7 @@ z.object({
|
|
|
568
568
|
});
|
|
569
569
|
var PriorReview = z.object({
|
|
570
570
|
head: CommitSha,
|
|
571
|
+
base: CommitSha.optional(),
|
|
571
572
|
verdict: ReviewVerdict,
|
|
572
573
|
summary: z.string(),
|
|
573
574
|
body: z.string(),
|
|
@@ -670,6 +671,7 @@ var ReviewDraft = z.object({
|
|
|
670
671
|
tier: z.enum(["stamp", "full"]),
|
|
671
672
|
reasons: z.array(z.string()),
|
|
672
673
|
reviewedHead: CommitSha,
|
|
674
|
+
reviewedBase: CommitSha.optional(),
|
|
673
675
|
verdict: storedVerdict,
|
|
674
676
|
summary: z.string(),
|
|
675
677
|
assessment: ReviewAssessment.optional(),
|
|
@@ -1397,7 +1399,8 @@ var FactorySettings = z.object({
|
|
|
1397
1399
|
posthogProjectId: z.number().int().positive()
|
|
1398
1400
|
})).optional(),
|
|
1399
1401
|
dailyBudgetUsd: z.number().finite().nonnegative().nullable().optional(),
|
|
1400
|
-
verifierModel: z.string().trim().min(1).nullable().optional()
|
|
1402
|
+
verifierModel: z.string().trim().min(1).nullable().optional(),
|
|
1403
|
+
mirrorHarnessRuns: optionalBoolean("factory.mirrorHarnessRuns")
|
|
1401
1404
|
}).nullable().optional();
|
|
1402
1405
|
var KnowledgeGraphSettings = optionalObject("knowledgeGraph", { enabled: optionalBoolean("knowledgeGraph.enabled") });
|
|
1403
1406
|
var posthogNumberRanges = {
|
|
@@ -1453,6 +1456,14 @@ var PlanReviewSettings = z.object({ enabled: optionalBoolean("planReview.enabled
|
|
|
1453
1456
|
var agentApiShape = { enabled: optionalBoolean("agentApi.enabled") };
|
|
1454
1457
|
var AgentApiSettings = z.object(agentApiShape, { error: "agentApi must be an object" }).strict().optional();
|
|
1455
1458
|
var AgentApiFileSettings = z.object(agentApiShape, { error: "agentApi must be an object" }).passthrough().optional();
|
|
1459
|
+
var optionalPathList = (field) => z.array(z.string({ error: `${field} must be an array of paths` }).trim().min(1, { error: `${field} must be an array of paths` }), { error: `${field} must be an array of paths` }).optional();
|
|
1460
|
+
var sandboxShape = {
|
|
1461
|
+
unconfinedRepos: optionalPathList("sandbox.unconfinedRepos"),
|
|
1462
|
+
writablePaths: optionalPathList("sandbox.writablePaths"),
|
|
1463
|
+
unreadablePaths: optionalPathList("sandbox.unreadablePaths")
|
|
1464
|
+
};
|
|
1465
|
+
var SandboxSettings = z.object(sandboxShape, { error: "sandbox must be an object" }).strict().optional();
|
|
1466
|
+
var SandboxFileSettings = z.object(sandboxShape, { error: "sandbox must be an object" }).passthrough().optional();
|
|
1456
1467
|
var telemetryShape = { enabled: optionalBoolean("telemetry.enabled") };
|
|
1457
1468
|
var TelemetrySettings = z.object(telemetryShape, { error: "telemetry must be an object" }).strict().optional();
|
|
1458
1469
|
var TelemetryFileSettings = z.object(telemetryShape, { error: "telemetry must be an object" }).passthrough().optional();
|
|
@@ -1469,7 +1480,6 @@ var createBrowserConfigShape = (isAbsolutePath) => ({
|
|
|
1469
1480
|
calmLayout: optionalBoolean("calmLayout"),
|
|
1470
1481
|
detectBackgroundAgents: optionalBoolean("detectBackgroundAgents"),
|
|
1471
1482
|
recordSignals: optionalBoolean("recordSignals"),
|
|
1472
|
-
antiSlopPrompt: optionalBoolean("antiSlopPrompt"),
|
|
1473
1483
|
rtk: optionalBoolean("rtk"),
|
|
1474
1484
|
saneYolo: optionalBoolean("saneYolo"),
|
|
1475
1485
|
skipPermissionsByDefault: optionalBoolean("skipPermissionsByDefault"),
|
|
@@ -1496,6 +1506,7 @@ var createBrowserConfigShape = (isAbsolutePath) => ({
|
|
|
1496
1506
|
telegram: TelegramSettings,
|
|
1497
1507
|
ingest: IngestSettings,
|
|
1498
1508
|
agentApi: AgentApiSettings,
|
|
1509
|
+
sandbox: SandboxSettings,
|
|
1499
1510
|
telemetry: TelemetrySettings,
|
|
1500
1511
|
workflows: WorkflowsSettings.nullable().optional()
|
|
1501
1512
|
});
|
|
@@ -1591,7 +1602,8 @@ var ProjectConfig = z.object({
|
|
|
1591
1602
|
repos: z.array(z.string()).min(2).optional(),
|
|
1592
1603
|
agent: z.string({ error: "projects[].agent must be a string" }).regex(AGENT_ID_RE, { error: `projects[].agent must be ${AGENT_ID_SHAPE_MESSAGE}` }).optional(),
|
|
1593
1604
|
codexBypassHookTrust: z.boolean().optional(),
|
|
1594
|
-
dangerouslySkipPermissions: z.boolean({ error: "projects[].dangerouslySkipPermissions must be a boolean" }).optional()
|
|
1605
|
+
dangerouslySkipPermissions: z.boolean({ error: "projects[].dangerouslySkipPermissions must be a boolean" }).optional(),
|
|
1606
|
+
unconfined: z.boolean({ error: "projects[].unconfined must be a boolean" }).optional()
|
|
1595
1607
|
}).passthrough();
|
|
1596
1608
|
var FILE_CONFIG_SHAPE = {
|
|
1597
1609
|
...BROWSER_CONFIG_SHAPE,
|
|
@@ -1610,6 +1622,7 @@ var FILE_CONFIG_SHAPE = {
|
|
|
1610
1622
|
ingest: optionalLooseObject("ingest"),
|
|
1611
1623
|
workflows: optionalLooseObject("workflows"),
|
|
1612
1624
|
agentApi: AgentApiFileSettings,
|
|
1625
|
+
sandbox: SandboxFileSettings,
|
|
1613
1626
|
telemetry: TelemetryFileSettings,
|
|
1614
1627
|
trace: TraceSettings,
|
|
1615
1628
|
planReview: PlanReviewSettings,
|
|
@@ -1666,6 +1679,7 @@ var CONFIG_BLOCK_KEYS = Object.freeze([
|
|
|
1666
1679
|
"telegram",
|
|
1667
1680
|
"ingest",
|
|
1668
1681
|
"agentApi",
|
|
1682
|
+
"sandbox",
|
|
1669
1683
|
"telemetry",
|
|
1670
1684
|
"workflows",
|
|
1671
1685
|
"coder"
|
|
@@ -3,8 +3,8 @@ import { i as equalsIgnoringCaseOnWindows, t as canonicalizePath } from "./paths
|
|
|
3
3
|
import { n as glimmervoidHomeDir$1, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
|
|
4
4
|
import { a as positiveIntOr, c as textOr, n as isRecord } from "./coerce-NSst8oRP.js";
|
|
5
5
|
import { d as writeJsonAtomicSync, f as writeTextAtomic, p as writeTextAtomicSync } from "./json-file-oEH9vt-0.js";
|
|
6
|
-
import { St as normalizeLegacyConfigNumbers, f as BranchGcFileSettings, i as Config, l as configIssueMessage, m as DEFAULT_FACTORY_PROTECTED_PATHS, n as BUILTIN_AGENT_IDS, p as DEFAULT_FACTORY_CHECKS, s as RUNTIME_CONFIG_SCALAR_KEYS, t as AGENT_ID_SHAPE_MESSAGE } from "./config-
|
|
7
|
-
import { V as FeatureFlagsResponse, W as TELEMETRY_KILL_SWITCH_FLAG } from "./contracts-
|
|
6
|
+
import { St as normalizeLegacyConfigNumbers, f as BranchGcFileSettings, i as Config, l as configIssueMessage, m as DEFAULT_FACTORY_PROTECTED_PATHS, n as BUILTIN_AGENT_IDS, p as DEFAULT_FACTORY_CHECKS, s as RUNTIME_CONFIG_SCALAR_KEYS, t as AGENT_ID_SHAPE_MESSAGE } from "./config-B6BkTOcE.js";
|
|
7
|
+
import { V as FeatureFlagsResponse, W as TELEMETRY_KILL_SWITCH_FLAG } from "./contracts-DzDg-Z9I.js";
|
|
8
8
|
import fs from "node:fs";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import os from "node:os";
|
|
@@ -1111,15 +1111,20 @@ var DEFAULT_CONFIG = {
|
|
|
1111
1111
|
watchWindowMinutes: 30,
|
|
1112
1112
|
watchProjects: [],
|
|
1113
1113
|
dailyBudgetUsd: null,
|
|
1114
|
-
verifierModel: null
|
|
1114
|
+
verifierModel: null,
|
|
1115
|
+
mirrorHarnessRuns: false
|
|
1115
1116
|
},
|
|
1116
1117
|
agentApi: { enabled: false },
|
|
1118
|
+
sandbox: {
|
|
1119
|
+
unconfinedRepos: [],
|
|
1120
|
+
writablePaths: ["~/.npm", "~/.cache"],
|
|
1121
|
+
unreadablePaths: []
|
|
1122
|
+
},
|
|
1117
1123
|
telemetry: { enabled: true },
|
|
1118
1124
|
checkForUpdates: true,
|
|
1119
1125
|
updateChannel: "release",
|
|
1120
1126
|
autoResume: true,
|
|
1121
1127
|
skipPermissionsByDefault: false,
|
|
1122
|
-
antiSlopPrompt: false,
|
|
1123
1128
|
rtk: false,
|
|
1124
1129
|
saneYolo: true,
|
|
1125
1130
|
telegramNotifications: false,
|
|
@@ -1517,9 +1522,12 @@ function createConfigStore({ settingsDefaults } = {}) {
|
|
|
1517
1522
|
recordSignals: config.recordSignals ?? effectiveDefaults.recordSignals,
|
|
1518
1523
|
trace: { enabled: config.trace?.enabled ?? DEFAULT_CONFIG.trace.enabled },
|
|
1519
1524
|
agentApi: { enabled: config.agentApi?.enabled ?? DEFAULT_CONFIG.agentApi.enabled },
|
|
1525
|
+
sandbox: {
|
|
1526
|
+
...DEFAULT_CONFIG.sandbox,
|
|
1527
|
+
...config.sandbox
|
|
1528
|
+
},
|
|
1520
1529
|
telemetry: { enabled: config.telemetry?.enabled ?? DEFAULT_CONFIG.telemetry.enabled },
|
|
1521
1530
|
telemetryForcedOff: isTelemetryForcedOff(process.env),
|
|
1522
|
-
antiSlopPrompt: config.antiSlopPrompt ?? effectiveDefaults.antiSlopPrompt,
|
|
1523
1531
|
rtk: config.rtk ?? effectiveDefaults.rtk,
|
|
1524
1532
|
rtkInstallSupported: assetForPlatform(process.platform, process.arch) !== null,
|
|
1525
1533
|
saneYolo: config.saneYolo ?? effectiveDefaults.saneYolo,
|
|
@@ -1592,6 +1600,7 @@ function createConfigStore({ settingsDefaults } = {}) {
|
|
|
1592
1600
|
if (newConfig.telegram != null) config.telegram = newConfig.telegram;
|
|
1593
1601
|
if (newConfig.ingest != null) config.ingest = newConfig.ingest;
|
|
1594
1602
|
if (newConfig.agentApi != null) config.agentApi = newConfig.agentApi;
|
|
1603
|
+
if (newConfig.sandbox != null) config.sandbox = newConfig.sandbox;
|
|
1595
1604
|
if (newConfig.telemetry != null) config.telemetry = newConfig.telemetry;
|
|
1596
1605
|
if (newConfig.workflows == null) delete config.workflows;
|
|
1597
1606
|
if (newConfig.workflows != null) config.workflows = newConfig.workflows;
|