openfox 2.0.16 → 2.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/agent-defaults/builder.agent.md +1 -2
  2. package/dist/agent-defaults/code-reviewer.agent.md +1 -1
  3. package/dist/agent-defaults/planner.agent.md +4 -1
  4. package/dist/agent-defaults/verifier.agent.md +1 -1
  5. package/dist/{chat-handler-PC6OVDUR.js → chat-handler-Z2C4372A.js} +5 -5
  6. package/dist/{chunk-63UEI4AF.js → chunk-4MTSWBWH.js} +3 -3
  7. package/dist/{chunk-L7TDUIQY.js → chunk-DX37WNM7.js} +28 -3
  8. package/dist/{chunk-JO6RF2U2.js → chunk-FCSFHRKI.js} +79 -49
  9. package/dist/{chunk-DQ6SV26Y.js → chunk-FERQPF5N.js} +28 -21
  10. package/dist/{chunk-OUK5IW26.js → chunk-M6ELTMPZ.js} +2 -2
  11. package/dist/{chunk-WOTBK3QQ.js → chunk-MPSOO6KF.js} +7 -7
  12. package/dist/{chunk-XAMAYRDA.js → chunk-O4TED6AJ.js} +5 -1
  13. package/dist/{chunk-FWJ6YXGA.js → chunk-VHWUZ7TO.js} +2 -2
  14. package/dist/cli/dev.js +1 -1
  15. package/dist/cli/index.js +1 -1
  16. package/dist/{compactor-R7GRFBOU.js → compactor-FAN7KRQN.js} +3 -3
  17. package/dist/{orchestrator-3SB2BMQ7.js → orchestrator-YPL5S4QN.js} +5 -5
  18. package/dist/package.json +1 -1
  19. package/dist/{processor-KWPYXPL7.js → processor-GUUAJ24C.js} +5 -5
  20. package/dist/{project-creator-6DU7E75S.js → project-creator-BDDFQM6G.js} +2 -2
  21. package/dist/{projects-2HYIZC4Y.js → projects-VO4PMVZY.js} +2 -2
  22. package/dist/{serve-HZXJXK6T.js → serve-Z5GO323T.js} +8 -8
  23. package/dist/server/index.js +7 -7
  24. package/dist/{server-RYKKAOFF.js → server-IZL6UZEZ.js} +7 -7
  25. package/dist/{tools-Y7ZGLK7A.js → tools-QTEXQQ7Z.js} +4 -4
  26. package/dist/web/assets/{index-Ho_tVUbw.css → index-Bq9rJ9jH.css} +1 -1
  27. package/dist/web/assets/index-ByjaBwIN.js +301 -0
  28. package/dist/web/index.html +2 -2
  29. package/dist/web/sw.js +1 -1
  30. package/package.json +1 -1
  31. package/dist/web/assets/index-BMz5-yAf.js +0 -301
@@ -11,12 +11,11 @@ allowedTools:
11
11
  - edit_file
12
12
  - run_command
13
13
  - ask_user
14
- - session_metadata:get,add,update,remove
14
+ - session_metadata
15
15
  - call_sub_agent
16
16
  - load_skill
17
17
  - dev_server
18
18
  - background_process
19
- - step_done
20
19
  ---
21
20
 
22
21
  # Build Mode
@@ -8,7 +8,7 @@ allowedTools:
8
8
  - read_file
9
9
  - run_command
10
10
  - web_fetch
11
- - session_metadata:get,add,update,remove
11
+ - session_metadata
12
12
  ---
13
13
 
14
14
  You are a code reviewer. Review the **git diff** of the modified files rather than reading the full files.
@@ -8,10 +8,13 @@ allowedTools:
8
8
  - read_file
9
9
  - web_fetch
10
10
  - run_command
11
- - session_metadata:get,add,update,remove
11
+ - ask_user
12
+ - session_metadata
12
13
  - call_sub_agent
13
14
  - load_skill
14
15
  - background_process
16
+ - mcp_config
17
+ - dev_server
15
18
  ---
16
19
 
17
20
  # Plan Mode
@@ -7,7 +7,7 @@ color: '#22c55e'
7
7
  allowedTools:
8
8
  - read_file
9
9
  - run_command
10
- - session_metadata:get,add,update,remove
10
+ - session_metadata
11
11
  - web_fetch
12
12
  ---
13
13
 
@@ -8,10 +8,10 @@ import {
8
8
  } from "./chunk-J7KOV4ST.js";
9
9
  import {
10
10
  runChatTurn
11
- } from "./chunk-63UEI4AF.js";
12
- import "./chunk-JO6RF2U2.js";
13
- import "./chunk-XAMAYRDA.js";
14
- import "./chunk-L7TDUIQY.js";
11
+ } from "./chunk-4MTSWBWH.js";
12
+ import "./chunk-FCSFHRKI.js";
13
+ import "./chunk-O4TED6AJ.js";
14
+ import "./chunk-DX37WNM7.js";
15
15
  import "./chunk-DL6ZILAF.js";
16
16
  import "./chunk-PBGOZMVY.js";
17
17
  import "./chunk-VRGRAQDG.js";
@@ -164,4 +164,4 @@ export {
164
164
  startChatSession,
165
165
  stopSessionExecution
166
166
  };
167
- //# sourceMappingURL=chat-handler-PC6OVDUR.js.map
167
+ //# sourceMappingURL=chat-handler-Z2C4372A.js.map
@@ -14,7 +14,7 @@ import {
14
14
  loadAllAgentsDefault,
15
15
  processEventsForConversation,
16
16
  runTopLevelAgentLoop
17
- } from "./chunk-JO6RF2U2.js";
17
+ } from "./chunk-FCSFHRKI.js";
18
18
  import {
19
19
  TurnMetrics,
20
20
  WORKFLOW_KICKOFF_PROMPT,
@@ -22,7 +22,7 @@ import {
22
22
  buildAgentSmallReminder,
23
23
  createChatDoneEvent,
24
24
  createMessageStartEvent
25
- } from "./chunk-L7TDUIQY.js";
25
+ } from "./chunk-DX37WNM7.js";
26
26
  import {
27
27
  getCurrentContextWindowId,
28
28
  getCurrentWindowMessageOptions,
@@ -320,4 +320,4 @@ export {
320
320
  runAgentTurn,
321
321
  injectWorkflowKickoffIfNeeded
322
322
  };
323
- //# sourceMappingURL=chunk-63UEI4AF.js.map
323
+ //# sourceMappingURL=chunk-4MTSWBWH.js.map
@@ -8,6 +8,24 @@ import {
8
8
  logger
9
9
  } from "./chunk-K44MW7JJ.js";
10
10
 
11
+ // src/server/tools/tool-policy.ts
12
+ var ALWAYS_ALLOWED = /* @__PURE__ */ new Set(["step_done"]);
13
+ var ALWAYS_ALLOWED_FOR_SUBAGENTS = /* @__PURE__ */ new Set(["return_value"]);
14
+ var TOP_LEVEL_ONLY_TOOLS = /* @__PURE__ */ new Set(["call_sub_agent"]);
15
+ function computeEffectiveTools(allowedTools, type) {
16
+ const tools = /* @__PURE__ */ new Set();
17
+ for (const entry of allowedTools) {
18
+ const baseName = entry.includes(":") ? entry.split(":")[0] : entry;
19
+ if (baseName === "return_value" && type === "agent") continue;
20
+ tools.add(baseName);
21
+ }
22
+ const alwaysAllowed = type === "sub-agent" ? ALWAYS_ALLOWED_FOR_SUBAGENTS : ALWAYS_ALLOWED;
23
+ for (const tool of alwaysAllowed) {
24
+ tools.add(tool);
25
+ }
26
+ return tools;
27
+ }
28
+
11
29
  // src/server/chat/prompts.ts
12
30
  function buildBasePrompt(workdir, customInstructions, skills, modelName) {
13
31
  const instructionsSection = customInstructions ? `
@@ -199,8 +217,11 @@ function buildToolPermissionsSection(allowedTools, isSubAgent) {
199
217
  toolPermissions.set(toolName, [...existing, ...actions]);
200
218
  }
201
219
  }
202
- if (isSubAgent && !baseTools.includes("return_value") && !toolPermissions.has("return_value")) {
203
- baseTools.push("return_value");
220
+ const effectiveTools = computeEffectiveTools(allowedTools, isSubAgent ? "sub-agent" : "agent");
221
+ for (const tool of effectiveTools) {
222
+ if (!baseTools.includes(tool) && !toolPermissions.has(tool)) {
223
+ baseTools.push(tool);
224
+ }
204
225
  }
205
226
  const parts = [];
206
227
  for (const [toolName, actions] of toolPermissions) {
@@ -658,6 +679,10 @@ async function consumeStreamGenerator(gen, onEvent) {
658
679
  }
659
680
 
660
681
  export {
682
+ ALWAYS_ALLOWED,
683
+ ALWAYS_ALLOWED_FOR_SUBAGENTS,
684
+ TOP_LEVEL_ONLY_TOOLS,
685
+ computeEffectiveTools,
661
686
  buildBasePrompt,
662
687
  buildTopLevelSystemPrompt,
663
688
  buildSubAgentSystemPrompt,
@@ -674,4 +699,4 @@ export {
674
699
  createChatDoneEvent,
675
700
  consumeStreamGenerator
676
701
  };
677
- //# sourceMappingURL=chunk-L7TDUIQY.js.map
702
+ //# sourceMappingURL=chunk-DX37WNM7.js.map
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  getProject
3
- } from "./chunk-XAMAYRDA.js";
3
+ } from "./chunk-O4TED6AJ.js";
4
4
  import {
5
5
  COMPACTION_PROMPT,
6
6
  TurnMetrics,
7
7
  buildBasePrompt,
8
8
  buildSubAgentSystemPrompt,
9
9
  buildTopLevelSystemPrompt,
10
+ computeEffectiveTools,
10
11
  consumeStreamGenerator,
11
12
  createChatDoneEvent,
12
13
  createMessageDoneEvent,
@@ -14,7 +15,7 @@ import {
14
15
  createToolCallEvent,
15
16
  createToolResultEvent,
16
17
  streamLLMPure
17
- } from "./chunk-L7TDUIQY.js";
18
+ } from "./chunk-DX37WNM7.js";
18
19
  import {
19
20
  startInspectProxy
20
21
  } from "./chunk-DL6ZILAF.js";
@@ -479,7 +480,7 @@ function validateAction(action, allowed, startTime) {
479
480
  return void 0;
480
481
  }
481
482
  function checkActionPermission(action, permittedActions, startTime) {
482
- if (action && permittedActions && !permittedActions.includes(action)) {
483
+ if (action && permittedActions && permittedActions.length > 0 && !permittedActions.includes(action)) {
483
484
  return {
484
485
  success: false,
485
486
  error: `Action '${action}' not allowed. Available: ${permittedActions.join(", ")}`,
@@ -962,7 +963,8 @@ var readFileTool = createTool(
962
963
  metadata: {
963
964
  encoding,
964
965
  confidence: Math.round(confidence * 100) / 100,
965
- lineCount: totalLines
966
+ lineCount: totalLines,
967
+ path: fullPath
966
968
  }
967
969
  });
968
970
  }
@@ -1059,7 +1061,10 @@ var writeFileTool = createTool(
1059
1061
  if (newHash) {
1060
1062
  context.sessionManager.updateFileHash(context.sessionId, fullPath, newHash);
1061
1063
  }
1062
- return helpers.success(output, false, diagnostics.length > 0 ? { diagnostics } : void 0);
1064
+ return helpers.success(output, false, {
1065
+ ...diagnostics.length > 0 && { diagnostics },
1066
+ metadata: { path: fullPath }
1067
+ });
1063
1068
  }
1064
1069
  );
1065
1070
 
@@ -1318,7 +1323,8 @@ Make sure whitespace and indentation match exactly.`
1318
1323
  }
1319
1324
  return helpers.success(output, false, {
1320
1325
  ...diagnostics.length > 0 && { diagnostics },
1321
- ...editContextRegions.length > 0 && { editContext: { regions: editContextRegions } }
1326
+ ...editContextRegions.length > 0 && { editContext: { regions: editContextRegions } },
1327
+ metadata: { path: fullPath }
1322
1328
  });
1323
1329
  });
1324
1330
  }
@@ -2536,7 +2542,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
2536
2542
  sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens);
2537
2543
  if (!compacting) {
2538
2544
  const contextState = sessionManager.getContextState(sessionId);
2539
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-R7GRFBOU.js");
2545
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-FAN7KRQN.js");
2540
2546
  if (shouldCompact(contextState.currentTokens, contextState.maxTokens, runtimeConfig.context.compactionThreshold)) {
2541
2547
  appendCompactionPrompt(sessionId, append);
2542
2548
  compacting = true;
@@ -3341,7 +3347,7 @@ var callSubAgentTool = {
3341
3347
  };
3342
3348
  }
3343
3349
  try {
3344
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-Y7ZGLK7A.js");
3350
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-QTEXQQ7Z.js");
3345
3351
  const toolRegistry = getToolRegistryForAgent2(agentDef);
3346
3352
  const turnMetrics = new TurnMetrics();
3347
3353
  const result = await executeSubAgent({
@@ -4147,7 +4153,7 @@ async function computeContextHash(sessionManager, sessionId) {
4147
4153
  const runtimeConfig = getRuntimeConfig();
4148
4154
  const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
4149
4155
  const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
4150
- const { createToolRegistry: createToolRegistry2 } = await import("./tools-Y7ZGLK7A.js");
4156
+ const { createToolRegistry: createToolRegistry2 } = await import("./tools-QTEXQQ7Z.js");
4151
4157
  const allTools = createToolRegistry2().definitions;
4152
4158
  const toolFingerprint = getToolFingerprint(allTools);
4153
4159
  const hash = computeDynamicContextHash(instructionContent, skills, toolFingerprint);
@@ -4260,7 +4266,7 @@ var mcpConfigTool = createTool(
4260
4266
  await saveGlobalConfig(mcpConfigMode, { ...globalConfig, mcpServers: updated });
4261
4267
  }
4262
4268
  async function rebuildTools() {
4263
- const { setMcpTools: setMcpTools2 } = await import("./tools-Y7ZGLK7A.js");
4269
+ const { setMcpTools: setMcpTools2 } = await import("./tools-QTEXQQ7Z.js");
4264
4270
  const mcpTools = createMcpTools(mcpManagerForTools);
4265
4271
  setMcpTools2(mcpTools);
4266
4272
  }
@@ -4361,6 +4367,37 @@ var mcpConfigTool = createTool(
4361
4367
  );
4362
4368
 
4363
4369
  // src/server/tools/index.ts
4370
+ var _builtInTools;
4371
+ function getBuiltInTools() {
4372
+ if (!_builtInTools) {
4373
+ _builtInTools = [
4374
+ readFileTool,
4375
+ writeFileTool,
4376
+ editFileTool,
4377
+ runCommandTool,
4378
+ askUserTool,
4379
+ sessionMetadataTool,
4380
+ callSubAgentTool,
4381
+ loadSkillTool,
4382
+ returnValueTool,
4383
+ webFetchTool,
4384
+ devServerTool,
4385
+ stepDoneTool,
4386
+ backgroundProcessTool,
4387
+ mcpConfigTool
4388
+ ];
4389
+ }
4390
+ return _builtInTools;
4391
+ }
4392
+ function getBuiltInToolNames() {
4393
+ if (BUILT_IN_TOOL_NAMES_CACHE.size === 0) {
4394
+ for (const t of getBuiltInTools()) {
4395
+ BUILT_IN_TOOL_NAMES_CACHE.add(t.name);
4396
+ }
4397
+ }
4398
+ return BUILT_IN_TOOL_NAMES_CACHE;
4399
+ }
4400
+ var BUILT_IN_TOOL_NAMES_CACHE = /* @__PURE__ */ new Set();
4364
4401
  function parseToolPermissions(allowedTools) {
4365
4402
  const result = {};
4366
4403
  for (const entry of allowedTools) {
@@ -4396,9 +4433,8 @@ function validateToolAction(toolName, action, permissions) {
4396
4433
  function extractSubAgentPrompt(args) {
4397
4434
  return args["prompt"] || args["query"] || args["task"] || "";
4398
4435
  }
4399
- function createRegistryFromTools(tools, allowedTools, toolPermissions) {
4436
+ function createRegistryFromTools(tools, allowedTools, toolPermissions, agentId, isSubAgent) {
4400
4437
  const toolMap = /* @__PURE__ */ new Map();
4401
- const allowedToolsSet = new Set(allowedTools || []);
4402
4438
  for (const tool of tools) {
4403
4439
  toolMap.set(tool.name, tool);
4404
4440
  }
@@ -4431,18 +4467,22 @@ function createRegistryFromTools(tools, allowedTools, toolPermissions) {
4431
4467
  truncated: false
4432
4468
  };
4433
4469
  }
4434
- const hasBaseToolPermission = allowedToolsSet.has(name) || [...allowedToolsSet].some((entry) => entry.startsWith(`${name}:`));
4435
- if (allowedTools && allowedTools.length > 0 && !hasBaseToolPermission) {
4436
- logger.debug("Permission denied: tool not in allowed list", {
4437
- tool: name,
4438
- allowedTools
4439
- });
4440
- return {
4441
- success: false,
4442
- error: createPermissionErrorMessage(name, allowedTools),
4443
- durationMs: 0,
4444
- truncated: false
4445
- };
4470
+ const isMcpTool = !getBuiltInToolNames().has(name);
4471
+ const hasRestrictions = allowedTools !== void 0;
4472
+ if (!isMcpTool && hasRestrictions) {
4473
+ const effectiveTools = computeEffectiveTools(allowedTools, isSubAgent ? "sub-agent" : "agent");
4474
+ if (!effectiveTools.has(name)) {
4475
+ logger.debug("Permission denied: tool not in allowed list", {
4476
+ tool: name,
4477
+ allowedTools
4478
+ });
4479
+ return {
4480
+ success: false,
4481
+ error: createPermissionErrorMessage(name, allowedTools, agentId, isSubAgent),
4482
+ durationMs: 0,
4483
+ truncated: false
4484
+ };
4485
+ }
4446
4486
  }
4447
4487
  if (toolPermissions) {
4448
4488
  const action = args["action"];
@@ -4503,30 +4543,20 @@ function setMcpTools(tools) {
4503
4543
  mcpToolsOverride = tools;
4504
4544
  }
4505
4545
  function getAllToolsMap() {
4506
- const builtInTools = [
4507
- readFileTool,
4508
- writeFileTool,
4509
- editFileTool,
4510
- runCommandTool,
4511
- askUserTool,
4512
- sessionMetadataTool,
4513
- callSubAgentTool,
4514
- loadSkillTool,
4515
- returnValueTool,
4516
- webFetchTool,
4517
- devServerTool,
4518
- stepDoneTool,
4519
- backgroundProcessTool,
4520
- mcpConfigTool
4521
- ].map((t) => [t.name, t]);
4546
+ const builtInEntries = getBuiltInTools().map((t) => [t.name, t]);
4522
4547
  const mcpEntries = mcpToolsOverride.map((t) => [t.name, t]);
4523
- return new Map([...builtInTools, ...mcpEntries]);
4548
+ return new Map([...builtInEntries, ...mcpEntries]);
4524
4549
  }
4525
- function createPermissionErrorMessage(toolName, allowedTools) {
4526
- if (allowedTools.length === 0) {
4550
+ function createPermissionErrorMessage(toolName, allowedTools, agentId, isSubAgent) {
4551
+ const effectiveTools = computeEffectiveTools(allowedTools, isSubAgent ? "sub-agent" : "agent");
4552
+ const available = [...effectiveTools].sort();
4553
+ if (agentId) {
4554
+ return `Tool '${toolName}' is not available in '${agentId}' mode. Available: ${available.join(", ")}`;
4555
+ }
4556
+ if (available.length === 0) {
4527
4557
  return `Tool '${toolName}' is not in your allowed tools list. No tools are allowed.`;
4528
4558
  }
4529
- return `Tool '${toolName}' is not in your allowed tools list. Available: ${allowedTools.join(", ")}`;
4559
+ return `Tool '${toolName}' is not in your allowed tools list. Available: ${available.join(", ")}`;
4530
4560
  }
4531
4561
  function addReturnValueToAllowedTools(allowedTools) {
4532
4562
  if (!allowedTools.includes("return_value")) {
@@ -4552,7 +4582,7 @@ function getToolRegistryForSubAgent(toolNames) {
4552
4582
  if (rv) tools.push(rv);
4553
4583
  }
4554
4584
  const allowedToolsWithReturnValue = addReturnValueToAllowedTools(toolNames);
4555
- return createRegistryFromTools(tools, allowedToolsWithReturnValue, toolPermissions);
4585
+ return createRegistryFromTools(tools, allowedToolsWithReturnValue, toolPermissions, void 0, true);
4556
4586
  }
4557
4587
  function getToolRegistryForAgent(agentDef) {
4558
4588
  if (agentDef.metadata.subagent) {
@@ -4560,15 +4590,15 @@ function getToolRegistryForAgent(agentDef) {
4560
4590
  }
4561
4591
  const allTools = getAllToolsMap();
4562
4592
  const tools = [];
4563
- const allowedTools = [];
4564
4593
  for (const [name, tool] of allTools.entries()) {
4565
4594
  if (name === "return_value") {
4566
4595
  continue;
4567
4596
  }
4568
4597
  tools.push(tool);
4569
- allowedTools.push(name);
4570
4598
  }
4571
- return createRegistryFromTools(tools, allowedTools);
4599
+ const allowedTools = agentDef.metadata.allowedTools;
4600
+ const toolPermissions = parseToolPermissions(allowedTools);
4601
+ return createRegistryFromTools(tools, allowedTools, toolPermissions, agentDef.metadata.id, false);
4572
4602
  }
4573
4603
  function createToolRegistry() {
4574
4604
  return createRegistryFromTools(Array.from(getAllToolsMap().values()));
@@ -4640,4 +4670,4 @@ export {
4640
4670
  getToolRegistryForAgent,
4641
4671
  createToolRegistry
4642
4672
  };
4643
- //# sourceMappingURL=chunk-JO6RF2U2.js.map
4673
+ //# sourceMappingURL=chunk-FCSFHRKI.js.map
@@ -21,7 +21,7 @@ import {
21
21
  tokenFromPassword,
22
22
  verifyPassword,
23
23
  workflowExists
24
- } from "./chunk-WOTBK3QQ.js";
24
+ } from "./chunk-MPSOO6KF.js";
25
25
  import {
26
26
  agentExists,
27
27
  createToolRegistry,
@@ -61,10 +61,15 @@ import {
61
61
  setMcpTools,
62
62
  setNotifyMcpServersChanged,
63
63
  skillExists
64
- } from "./chunk-JO6RF2U2.js";
64
+ } from "./chunk-FCSFHRKI.js";
65
65
  import {
66
66
  getProject
67
- } from "./chunk-XAMAYRDA.js";
67
+ } from "./chunk-O4TED6AJ.js";
68
+ import {
69
+ ALWAYS_ALLOWED,
70
+ ALWAYS_ALLOWED_FOR_SUBAGENTS,
71
+ TOP_LEVEL_ONLY_TOOLS
72
+ } from "./chunk-DX37WNM7.js";
68
73
  import {
69
74
  getPathSeparator,
70
75
  isAbsolutePath
@@ -3944,7 +3949,7 @@ import { Router as Router6 } from "express";
3944
3949
  import { spawn as spawn2 } from "child_process";
3945
3950
 
3946
3951
  // src/constants.ts
3947
- var VERSION = "2.0.16";
3952
+ var VERSION = "2.0.18";
3948
3953
 
3949
3954
  // src/server/routes/auto-update.ts
3950
3955
  var updateInProgress = false;
@@ -4124,7 +4129,7 @@ async function createServerHandle(config4) {
4124
4129
  setMcpTools(mcpTools);
4125
4130
  logger.info("MCP tools registered", { count: mcpTools.length });
4126
4131
  }
4127
- const { signalMcpReady } = await import("./server-RYKKAOFF.js");
4132
+ const { signalMcpReady } = await import("./server-IZL6UZEZ.js");
4128
4133
  signalMcpReady();
4129
4134
  });
4130
4135
  const app = express();
@@ -4179,12 +4184,14 @@ async function createServerHandle(config4) {
4179
4184
  app.get("/api/tools", (_req, res) => {
4180
4185
  const tools = toolRegistry.tools.map((t) => ({
4181
4186
  name: t.name,
4182
- actions: t.permittedActions || []
4187
+ actions: t.permittedActions || [],
4188
+ alwaysAllowed: ALWAYS_ALLOWED.has(t.name) || ALWAYS_ALLOWED_FOR_SUBAGENTS.has(t.name),
4189
+ topLevelOnly: TOP_LEVEL_ONLY_TOOLS.has(t.name)
4183
4190
  }));
4184
4191
  res.json({ tools });
4185
4192
  });
4186
4193
  app.get("/api/projects", async (_req, res) => {
4187
- const { listProjects } = await import("./projects-2HYIZC4Y.js");
4194
+ const { listProjects } = await import("./projects-VO4PMVZY.js");
4188
4195
  const projects = listProjects();
4189
4196
  res.json({ projects });
4190
4197
  });
@@ -4193,7 +4200,7 @@ async function createServerHandle(config4) {
4193
4200
  if (!name || !workdir) {
4194
4201
  return res.status(400).json({ error: "name and workdir are required" });
4195
4202
  }
4196
- const { createDirectoryWithGit } = await import("./project-creator-6DU7E75S.js");
4203
+ const { createDirectoryWithGit } = await import("./project-creator-BDDFQM6G.js");
4197
4204
  try {
4198
4205
  const project = await createDirectoryWithGit(name, workdir);
4199
4206
  res.status(201).json({ project });
@@ -4238,7 +4245,7 @@ async function createServerHandle(config4) {
4238
4245
  }
4239
4246
  });
4240
4247
  app.get("/api/projects/:id", async (req, res) => {
4241
- const { getProject: getProject2 } = await import("./projects-2HYIZC4Y.js");
4248
+ const { getProject: getProject2 } = await import("./projects-VO4PMVZY.js");
4242
4249
  const project = getProject2(req.params.id);
4243
4250
  if (!project) {
4244
4251
  return res.status(404).json({ error: "Project not found" });
@@ -4246,7 +4253,7 @@ async function createServerHandle(config4) {
4246
4253
  res.json({ project });
4247
4254
  });
4248
4255
  app.put("/api/projects/:id", async (req, res) => {
4249
- const { updateProject } = await import("./projects-2HYIZC4Y.js");
4256
+ const { updateProject } = await import("./projects-VO4PMVZY.js");
4250
4257
  const { name, customInstructions, dangerLevel } = req.body;
4251
4258
  const updates = {};
4252
4259
  if (name !== void 0) updates.name = name;
@@ -4259,7 +4266,7 @@ async function createServerHandle(config4) {
4259
4266
  res.json({ project: updated });
4260
4267
  });
4261
4268
  app.delete("/api/projects/:id", async (req, res) => {
4262
- const { getProject: getProject2, deleteProject } = await import("./projects-2HYIZC4Y.js");
4269
+ const { getProject: getProject2, deleteProject } = await import("./projects-VO4PMVZY.js");
4263
4270
  const project = getProject2(req.params.id);
4264
4271
  if (!project) {
4265
4272
  return res.status(404).json({ error: "Project not found" });
@@ -4268,7 +4275,7 @@ async function createServerHandle(config4) {
4268
4275
  res.json({ success: true });
4269
4276
  });
4270
4277
  app.put("/api/projects/:id/star", async (req, res) => {
4271
- const { toggleStar } = await import("./projects-2HYIZC4Y.js");
4278
+ const { toggleStar } = await import("./projects-VO4PMVZY.js");
4272
4279
  const { isStarred } = req.body;
4273
4280
  if (typeof isStarred !== "boolean") {
4274
4281
  return res.status(400).json({ error: "isStarred is required and must be a boolean" });
@@ -4315,7 +4322,7 @@ async function createServerHandle(config4) {
4315
4322
  app.get("/api/sessions/:id", async (req, res) => {
4316
4323
  const { getEventStore: getEventStore2 } = await import("./events-4K52FKPR.js");
4317
4324
  const { buildMessagesFromStoredEvents } = await import("./folding-QIBNKYA6.js");
4318
- const { getPendingQuestionsForSession } = await import("./tools-Y7ZGLK7A.js");
4325
+ const { getPendingQuestionsForSession } = await import("./tools-QTEXQQ7Z.js");
4319
4326
  const session = sessionManager.getSession(req.params.id);
4320
4327
  if (!session) {
4321
4328
  return res.status(404).json({ error: "Session not found" });
@@ -4446,7 +4453,7 @@ async function createServerHandle(config4) {
4446
4453
  if (!callId || approved === void 0) {
4447
4454
  return res.status(400).json({ error: "callId and approved are required" });
4448
4455
  }
4449
- const { providePathConfirmation } = await import("./tools-Y7ZGLK7A.js");
4456
+ const { providePathConfirmation } = await import("./tools-QTEXQQ7Z.js");
4450
4457
  const result = providePathConfirmation(callId, approved, alwaysAllow);
4451
4458
  if (!result.found) {
4452
4459
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
@@ -4454,7 +4461,7 @@ async function createServerHandle(config4) {
4454
4461
  const { getEventStore: getEventStore2 } = await import("./events-4K52FKPR.js");
4455
4462
  const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-QIBNKYA6.js");
4456
4463
  const { createSessionStateMessage } = await import("./protocol-BKNLAEPJ.js");
4457
- const { getPendingQuestionsForSession } = await import("./tools-Y7ZGLK7A.js");
4464
+ const { getPendingQuestionsForSession } = await import("./tools-QTEXQQ7Z.js");
4458
4465
  const eventStore = getEventStore2();
4459
4466
  const events = eventStore.getEvents(sessionId);
4460
4467
  const messages = buildMessagesFromStoredEvents(events);
@@ -4475,7 +4482,7 @@ async function createServerHandle(config4) {
4475
4482
  if (!skip && typeof answer !== "string") {
4476
4483
  return res.status(400).json({ error: "answer is required when not skipping" });
4477
4484
  }
4478
- const { provideAnswer } = await import("./tools-Y7ZGLK7A.js");
4485
+ const { provideAnswer } = await import("./tools-QTEXQQ7Z.js");
4479
4486
  const found = provideAnswer(callId, answer ?? "", skip ?? false);
4480
4487
  if (!found) {
4481
4488
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -4511,8 +4518,8 @@ async function createServerHandle(config4) {
4511
4518
  if (!session) {
4512
4519
  return res.status(404).json({ error: "Session not found" });
4513
4520
  }
4514
- const { stopSessionExecution } = await import("./chat-handler-PC6OVDUR.js");
4515
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-Y7ZGLK7A.js");
4521
+ const { stopSessionExecution } = await import("./chat-handler-Z2C4372A.js");
4522
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-QTEXQQ7Z.js");
4516
4523
  const queuedMessages = sessionManager.getQueueState(sessionId);
4517
4524
  sessionManager.clearMessageQueue(sessionId);
4518
4525
  stopSessionExecution(sessionId, sessionManager);
@@ -4955,7 +4962,7 @@ async function createServerHandle(config4) {
4955
4962
  });
4956
4963
  async function rebuildMcpTools() {
4957
4964
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-B7QP6NLA.js");
4958
- const { setMcpTools: setMcpTools2 } = await import("./tools-Y7ZGLK7A.js");
4965
+ const { setMcpTools: setMcpTools2 } = await import("./tools-QTEXQQ7Z.js");
4959
4966
  const mcpTools = createMcpTools2(mcpManager);
4960
4967
  setMcpTools2(mcpTools);
4961
4968
  }
@@ -5267,7 +5274,7 @@ async function createServerHandle(config4) {
5267
5274
  const state = sessionManager.getContextState(sessionId);
5268
5275
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
5269
5276
  });
5270
- const { QueueProcessor } = await import("./processor-KWPYXPL7.js");
5277
+ const { QueueProcessor } = await import("./processor-GUUAJ24C.js");
5271
5278
  const queueProcessor = new QueueProcessor({
5272
5279
  sessionManager,
5273
5280
  providerManager,
@@ -5342,4 +5349,4 @@ export {
5342
5349
  createServerHandle,
5343
5350
  createServer
5344
5351
  };
5345
- //# sourceMappingURL=chunk-DQ6SV26Y.js.map
5352
+ //# sourceMappingURL=chunk-FERQPF5N.js.map
@@ -196,7 +196,7 @@ async function runCli(options) {
196
196
  if (!configExists) {
197
197
  await runNetworkSetup(mode);
198
198
  }
199
- const { runServe } = await import("./serve-HZXJXK6T.js");
199
+ const { runServe } = await import("./serve-Z5GO323T.js");
200
200
  const serveOptions = { mode };
201
201
  if (values.port) serveOptions.port = parseInt(values.port);
202
202
  if (values["no-browser"] === true) serveOptions.openBrowser = false;
@@ -208,4 +208,4 @@ async function runCli(options) {
208
208
  export {
209
209
  runCli
210
210
  };
211
- //# sourceMappingURL=chunk-OUK5IW26.js.map
211
+ //# sourceMappingURL=chunk-M6ELTMPZ.js.map
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  appendCompactionPrompt
3
- } from "./chunk-FWJ6YXGA.js";
3
+ } from "./chunk-VHWUZ7TO.js";
4
4
  import {
5
5
  injectWorkflowKickoffIfNeeded,
6
6
  runAgentTurn,
7
7
  runChatTurn
8
- } from "./chunk-63UEI4AF.js";
8
+ } from "./chunk-4MTSWBWH.js";
9
9
  import {
10
10
  applyDynamicContext,
11
11
  checkAborted,
@@ -22,11 +22,11 @@ import {
22
22
  loadAllAgentsDefault,
23
23
  saveItemToDir,
24
24
  spawnShellProcess
25
- } from "./chunk-JO6RF2U2.js";
25
+ } from "./chunk-FCSFHRKI.js";
26
26
  import {
27
27
  TurnMetrics,
28
28
  createMessageStartEvent
29
- } from "./chunk-L7TDUIQY.js";
29
+ } from "./chunk-DX37WNM7.js";
30
30
  import {
31
31
  getPlatformShell,
32
32
  onProcessEvent
@@ -1775,7 +1775,7 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
1775
1775
  const runtimeConfig = getRuntimeConfig();
1776
1776
  const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1777
1777
  const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
1778
- const { createToolRegistry } = await import("./tools-Y7ZGLK7A.js");
1778
+ const { createToolRegistry } = await import("./tools-QTEXQQ7Z.js");
1779
1779
  const allTools = createToolRegistry().definitions;
1780
1780
  const toolFingerprint = getToolFingerprint(allTools);
1781
1781
  const currentHash = computeDynamicContextHash(instructionContent, skills, toolFingerprint);
@@ -1848,7 +1848,7 @@ async function handleClientMessage(ws, client, message, _getLLMClient, _getActiv
1848
1848
  const runtimeConfig = getRuntimeConfig();
1849
1849
  const configDir = getGlobalConfigDir(runtimeConfig.mode ?? "production");
1850
1850
  const skills = await getEnabledSkillMetadata(configDir, runtimeConfig.workdir);
1851
- const { createToolRegistry } = await import("./tools-Y7ZGLK7A.js");
1851
+ const { createToolRegistry } = await import("./tools-QTEXQQ7Z.js");
1852
1852
  const allTools = createToolRegistry().definitions;
1853
1853
  const toolFingerprint = getToolFingerprint(allTools);
1854
1854
  const currentHash = computeDynamicContextHash(instructionContent, skills, toolFingerprint);
@@ -2069,4 +2069,4 @@ export {
2069
2069
  signalMcpReady,
2070
2070
  createWebSocketServer
2071
2071
  };
2072
- //# sourceMappingURL=chunk-WOTBK3QQ.js.map
2072
+ //# sourceMappingURL=chunk-MPSOO6KF.js.map
@@ -5,6 +5,10 @@ import {
5
5
  // src/server/db/projects.ts
6
6
  function createProject(name, workdir) {
7
7
  const db = getDatabase();
8
+ const existing = getProjectByWorkdir(workdir);
9
+ if (existing) {
10
+ return existing;
11
+ }
8
12
  const now = (/* @__PURE__ */ new Date()).toISOString();
9
13
  const id = crypto.randomUUID();
10
14
  db.prepare(
@@ -113,4 +117,4 @@ export {
113
117
  deleteProject,
114
118
  toggleStar
115
119
  };
116
- //# sourceMappingURL=chunk-XAMAYRDA.js.map
120
+ //# sourceMappingURL=chunk-O4TED6AJ.js.map