openfox 2.0.115 → 2.0.116

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 (95) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/CHANGELOG.md +22 -0
  3. package/dist/{ask-ZYPCJKZD.js → ask-UBIRH3SO.js} +2 -2
  4. package/dist/{auth-YY5PJYSC.js → auth-GTGIGX5X.js} +2 -2
  5. package/dist/{auto-config-T5GR2N6X.js → auto-config-AAUO4PKW.js} +2 -2
  6. package/dist/{backend-LVYHLGQJ.js → backend-67OLCS5O.js} +2 -2
  7. package/dist/{branch.api-XVTYACSH.js → branch.api-UMKSQMSA.js} +2 -2
  8. package/dist/changelog-FZUE6OSG.js +63 -0
  9. package/dist/{chat-handler-5SP265CR.js → chat-handler-Z6BEY66U.js} +17 -17
  10. package/dist/{chunk-OCBBAEMT.js → chunk-4E52GUXJ.js} +179 -137
  11. package/dist/{chunk-I7FY2LTR.js → chunk-4GHLULHB.js} +18 -2
  12. package/dist/{chunk-JFK4GKQD.js → chunk-4HV3PDEK.js} +58 -90
  13. package/dist/{chunk-TGLVWAFC.js → chunk-6XHDNSA3.js} +5 -5
  14. package/dist/{chunk-4H427UBV.js → chunk-AGXJ5O63.js} +2 -2
  15. package/dist/{chunk-OKVHMKE2.js → chunk-BH3BBUGB.js} +19 -17
  16. package/dist/{chunk-OCSTEGK7.js → chunk-EQ5CGNOT.js} +2 -2
  17. package/dist/{chunk-YX3OQBNX.js → chunk-EQ7DK2TG.js} +9 -5
  18. package/dist/{chunk-BVVCRIVM.js → chunk-GZTMCTUS.js} +3 -3
  19. package/dist/chunk-HNHSUQCN.js +7 -0
  20. package/dist/{chunk-3QQAIUZI.js → chunk-HYPXL7K5.js} +175 -30
  21. package/dist/{chunk-6RGACY4E.js → chunk-HZSKKJHQ.js} +4 -3
  22. package/dist/{chunk-VWEATA7R.js → chunk-KLQEL2DZ.js} +7 -1
  23. package/dist/{chunk-JGWHRYWG.js → chunk-MKWS7TQH.js} +2 -2
  24. package/dist/{chunk-37QLXLML.js → chunk-QJWTBVJO.js} +14 -14
  25. package/dist/{chunk-6KPJLELC.js → chunk-QQVPUZQB.js} +156 -20
  26. package/dist/{chunk-TFF5T3K3.js → chunk-SQLJRO3J.js} +3 -3
  27. package/dist/{chunk-ERNWAKUB.js → chunk-TGVDUK4N.js} +2 -2
  28. package/dist/{chunk-3NPLERPQ.js → chunk-U4HMAYAD.js} +9 -8
  29. package/dist/{chunk-V4IE7HJY.js → chunk-W7VIYHPQ.js} +2 -2
  30. package/dist/{chunk-BWVO5WFK.js → chunk-X3XKYGUN.js} +3 -3
  31. package/dist/{chunk-5WRI5ZAA.js → chunk-YLJ4XMA6.js} +6 -2
  32. package/dist/{chunk-X25Q6RAV.js → chunk-ZKLE2Q3I.js} +1 -1
  33. package/dist/cli/dev.js +3 -3
  34. package/dist/cli/index.js +3 -3
  35. package/dist/{client-KE7EDI2D.js → client-KCNTDTIR.js} +4 -4
  36. package/dist/{client-pure-66Z6FWS6.js → client-pure-B5DHEKQJ.js} +2 -2
  37. package/dist/command-defaults/mark-done.command.md +6 -6
  38. package/dist/{compactor-SKVC2VNL.js → compactor-LAXZLPPA.js} +7 -7
  39. package/dist/{config-EAB3V4QK.js → config-TUCHLIWD.js} +2 -2
  40. package/dist/{dynamic-context-QNB4ELLP.js → dynamic-context-YHWFFP53.js} +3 -3
  41. package/dist/{events-5PLO4QJU.js → events-IVPAMMR5.js} +4 -4
  42. package/dist/{folding-CJWYFUKD.js → folding-RTGU63BW.js} +2 -2
  43. package/dist/{http-client-KLODRQC2.js → http-client-IPUW2MSW.js} +2 -2
  44. package/dist/{inspect-proxy-K6QKEYDT.js → inspect-proxy-WPEDMCG7.js} +2 -2
  45. package/dist/{install-CPOPMCSE.js → install-VA2F6X6Z.js} +2 -2
  46. package/dist/{launch-EOXVWLOP.js → launch-PAVQAWGP.js} +17 -17
  47. package/dist/{manager-LZ3JQ443.js → manager-EMLSLMMT.js} +2 -2
  48. package/dist/{model-overrides-5UVW3KTE.js → model-overrides-7F2EOA4U.js} +2 -2
  49. package/dist/{oauth-provider-52YILVUJ.js → oauth-provider-DGBC2YM6.js} +2 -2
  50. package/dist/{oauth-store-XCFXV2VM.js → oauth-store-KECHUT54.js} +2 -2
  51. package/dist/{openFolder-HX7X356L.js → openFolder-XCMSU3OI.js} +2 -2
  52. package/dist/{orchestrator-ED3KFPXO.js → orchestrator-CS3KXLZE.js} +16 -16
  53. package/dist/package.json +5 -2
  54. package/dist/{path-security-B6EZC63L.js → path-security-JTCHWYG3.js} +7 -7
  55. package/dist/{paths-F27V3S4I.js → paths-BHR7CZ7I.js} +2 -2
  56. package/dist/{permissions-K6YEA2ZZ.js → permissions-UKR524ZB.js} +2 -2
  57. package/dist/{platform-6RPPBHKH.js → platform-ECDDYMAR.js} +2 -2
  58. package/dist/{processor-226ZOTRI.js → processor-RZD4JRDX.js} +16 -16
  59. package/dist/profiles-GYHXBWPV.js +10 -0
  60. package/dist/{project-creator-VBFE35NI.js → project-creator-PMQ65NKN.js} +2 -2
  61. package/dist/{projects-AXHZOBR2.js → projects-NDPNOV6D.js} +2 -2
  62. package/dist/{protocol-JdxRpPxM.d.ts → protocol-CfUkCYxF.d.ts} +11 -2
  63. package/dist/{protocol-RKSWKNXI.js → protocol-HYA5BYVN.js} +8 -4
  64. package/dist/{provider-DL4ZWQY7.js → provider-Q7J4UFTS.js} +7 -7
  65. package/dist/{provider-manager-6CLRMGDE.js → provider-manager-TMBO4DFG.js} +5 -5
  66. package/dist/{pwa-XPHP3PY2.js → pwa-2GRFSXD7.js} +3 -3
  67. package/dist/{registry-5XI5NDBF.js → registry-5QL3BOWN.js} +2 -2
  68. package/dist/{serve-DARV4NJG.js → serve-KR22J37W.js} +22 -22
  69. package/dist/server/index.d.ts +15 -2
  70. package/dist/server/index.js +21 -21
  71. package/dist/{server-LQJ7MBDS.js → server-ESKTIZL5.js} +20 -20
  72. package/dist/{service-4JKTGPRG.js → service-M7XJHAK4.js} +6 -6
  73. package/dist/{service-CXWJQFOZ.js → service-WKABQHKL.js} +2 -2
  74. package/dist/{session-overrides-AZKV6BRD.js → session-overrides-CWBKPHMF.js} +4 -4
  75. package/dist/{sessions-752IZIIK.js → sessions-I7ELDIIP.js} +5 -3
  76. package/dist/{settings-2AHDKCD7.js → settings-FGXQHKUH.js} +2 -2
  77. package/dist/shared/index.d.ts +1 -1
  78. package/dist/shared/index.js +2 -2
  79. package/dist/{store-SARB6V2N.js → store-JYPZ2RXB.js} +2 -2
  80. package/dist/{tasks-XJXHU623.js → tasks-X5H5HM4J.js} +6 -6
  81. package/dist/{tool-adapter-FEAHWU5C.js → tool-adapter-FJAFLDZA.js} +2 -2
  82. package/dist/{tools-QYYNFMGU.js → tools-KBS6X3EN.js} +14 -14
  83. package/dist/{update-2REP2WB6.js → update-TDS6LP5N.js} +4 -4
  84. package/dist/{update-server-LOOXIXDW.js → update-server-SVPV6ZJZ.js} +2 -2
  85. package/dist/{url-utils-SAJP7AEX.js → url-utils-C5BM7NF7.js} +2 -2
  86. package/dist/web/assets/index-ChtRS33s.js +324 -0
  87. package/dist/web/assets/{index-BmILAZrT.css → index-c43YT-4A.css} +1 -1
  88. package/dist/web/index.html +2 -2
  89. package/dist/web/sw.js +1 -1
  90. package/dist/workflow-defaults/default.workflow.json +2 -2
  91. package/dist/{workspace-RMZVTFJD.js → workspace-IQLLHMYR.js} +2 -2
  92. package/package.json +5 -2
  93. package/dist/chunk-5V3BF67X.js +0 -7
  94. package/dist/profiles-5J7F4BML.js +0 -10
  95. package/dist/web/assets/index-M7ToECa4.js +0 -324
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  runAgentTurn
3
- } from "./chunk-3NPLERPQ.js";
3
+ } from "./chunk-U4HMAYAD.js";
4
4
  import {
5
5
  executeSubAgent,
6
6
  getToolRegistryForAgent
7
- } from "./chunk-JFK4GKQD.js";
7
+ } from "./chunk-4HV3PDEK.js";
8
8
  import {
9
9
  TurnMetrics,
10
10
  createMessageStartEvent
11
- } from "./chunk-YX3OQBNX.js";
11
+ } from "./chunk-EQ7DK2TG.js";
12
12
  import {
13
13
  checkAborted,
14
14
  decodeUtf8,
@@ -27,21 +27,24 @@ import {
27
27
  loadProjectWorkflows,
28
28
  loadUserWorkflows,
29
29
  normalizeWorkflowScope
30
- } from "./chunk-6RGACY4E.js";
30
+ } from "./chunk-HZSKKJHQ.js";
31
31
  import {
32
32
  getCurrentContextWindowId,
33
33
  getEventStore
34
- } from "./chunk-ERNWAKUB.js";
34
+ } from "./chunk-TGVDUK4N.js";
35
35
  import {
36
36
  createChatMessageMessage,
37
37
  createSessionRunningMessage
38
- } from "./chunk-I7FY2LTR.js";
38
+ } from "./chunk-4GHLULHB.js";
39
39
  import {
40
40
  findAgentById,
41
41
  getRuntimeConfig,
42
42
  loadAllAgentsDefault,
43
43
  resolveDefaultAgentId
44
44
  } from "./chunk-LNNBLB6G.js";
45
+ import {
46
+ LLMError
47
+ } from "./chunk-LTYL6ZGH.js";
45
48
  import {
46
49
  logger
47
50
  } from "./chunk-K44MW7JJ.js";
@@ -50,11 +53,19 @@ import {
50
53
  } from "./chunk-VUQCQXXJ.js";
51
54
  import {
52
55
  createServerMessage
53
- } from "./chunk-X25Q6RAV.js";
56
+ } from "./chunk-ZKLE2Q3I.js";
54
57
  import {
55
58
  getGlobalConfigDir
56
59
  } from "./chunk-CQGTEGKL.js";
57
60
 
61
+ // src/server/runner/types.ts
62
+ var DEFAULT_LLM_RETRY_POLICY = {
63
+ backoffMs: [1e3, 5e3, 3e4],
64
+ minIntervalMs: 6e4,
65
+ maxDurationMs: 30 * 6e4,
66
+ maxAttempts: 40
67
+ };
68
+
58
69
  // src/server/workflows/types.ts
59
70
  var TERMINAL_DONE = "$done";
60
71
  var TERMINAL_BLOCKED = "$blocked";
@@ -336,6 +347,64 @@ function getCurrentWindowMessageOptions(sessionId) {
336
347
  const contextWindowId = getCurrentContextWindowId(sessionId);
337
348
  return contextWindowId ? { contextWindowId } : void 0;
338
349
  }
350
+ function sleepWithSignal(ms, signal) {
351
+ return new Promise((resolve, reject) => {
352
+ if (signal?.aborted) {
353
+ reject(new Error("Aborted"));
354
+ return;
355
+ }
356
+ const onAbort = () => {
357
+ clearTimeout(timer);
358
+ signal?.removeEventListener("abort", onAbort);
359
+ reject(new Error("Aborted"));
360
+ };
361
+ const timer = setTimeout(() => {
362
+ signal?.removeEventListener("abort", onAbort);
363
+ resolve();
364
+ }, ms);
365
+ signal?.addEventListener("abort", onAbort, { once: true });
366
+ });
367
+ }
368
+ function evaluateLLMRetry(failures, firstFailureAt, now, policy) {
369
+ if (now - firstFailureAt >= policy.maxDurationMs) return { retry: false };
370
+ if (failures >= policy.maxAttempts) return { retry: false };
371
+ const delayMs = failures <= policy.backoffMs.length ? policy.backoffMs[failures - 1] : policy.minIntervalMs;
372
+ return { retry: true, delayMs, attempt: failures + 1 };
373
+ }
374
+ function rollbackFailedAttempt(sessionId, turnStartSeq) {
375
+ const eventStore = getEventStore();
376
+ const fromSeq = Math.max(1, turnStartSeq);
377
+ const events = eventStore.getEvents(sessionId, fromSeq + 1);
378
+ const assistantIds = new Set(
379
+ events.filter((e) => e.type === "message.start" && e.data.role === "assistant").map((e) => e.data.messageId)
380
+ );
381
+ const tombstoneSeqs = events.filter((e) => {
382
+ switch (e.type) {
383
+ case "message.start":
384
+ return e.data.role === "assistant";
385
+ case "message.delta":
386
+ case "message.thinking":
387
+ case "message.done":
388
+ case "chat.done":
389
+ return assistantIds.has(e.data.messageId);
390
+ case "chat.error":
391
+ case "pattern.retry":
392
+ case "tool.preparing":
393
+ case "tool.call":
394
+ case "tool.output":
395
+ case "tool.result":
396
+ return true;
397
+ default:
398
+ return false;
399
+ }
400
+ }).map((e) => e.seq);
401
+ if (tombstoneSeqs.length > 0) {
402
+ eventStore.tombstoneEvents(sessionId, tombstoneSeqs);
403
+ }
404
+ if (assistantIds.size > 0) {
405
+ eventStore.append(sessionId, { type: "message.removed", data: { messageIds: [...assistantIds] } });
406
+ }
407
+ }
339
408
  function buildReason(metadataEntries) {
340
409
  const entries = metadataEntries?.["criteria"] ?? [];
341
410
  const remaining = entries.filter((e) => e.status !== "passed");
@@ -353,6 +422,8 @@ async function executeWorkflow(workflow, options, subGroup) {
353
422
  let currentStepId = isResume ? resumeFromStep : subGroup ? activeSteps[0]?.id ?? workflow.entryStep : workflow.entryStep;
354
423
  let lastStepOutput = options.initialStepOutput ?? {};
355
424
  const firstEntryForStep = /* @__PURE__ */ new Set();
425
+ const stepLLMFailures = /* @__PURE__ */ new Map();
426
+ const stepLLMDeadlines = /* @__PURE__ */ new Map();
356
427
  const messagesBeforeWorkflow = sessionManager.requireSession(sessionId).messages.length;
357
428
  const activeStepIds = new Set(activeSteps.map((s) => s.id));
358
429
  const activeSubGroups = /* @__PURE__ */ new Set();
@@ -497,9 +568,10 @@ async function executeWorkflow(workflow, options, subGroup) {
497
568
  const agentStep = step;
498
569
  const STEP_DONE_PROMPT = "\n\nOnce you're done, call step_done()";
499
570
  const STEP_DONE_NUDGE = "You haven't called step_done(). If you haven't finished the task, continue and when you're finished call step_done()";
571
+ const isResumingCurrentStep = isResume && step.id === resumeFromStep && !resumeConsumed;
572
+ const isLLMFailedRetry = firstEntryForStep.has(step.id) && (stepLLMFailures.get(step.id) ?? 0) > 0;
500
573
  let promptContent;
501
574
  let nudgeContent;
502
- const isResumingCurrentStep = isResume && step.id === resumeFromStep && !resumeConsumed;
503
575
  if (!firstEntryForStep.has(step.id) && agentStep.prompt && !isResumingCurrentStep) {
504
576
  const resolvedPrompt = resolveTemplate(agentStep.prompt, templateCtx);
505
577
  promptContent = resolvedPrompt + STEP_DONE_PROMPT;
@@ -528,7 +600,7 @@ async function executeWorkflow(workflow, options, subGroup) {
528
600
  })
529
601
  );
530
602
  }
531
- } else if (firstEntryForStep.has(step.id) && !isResumingCurrentStep) {
603
+ } else if (firstEntryForStep.has(step.id) && !isResumingCurrentStep && !isLLMFailedRetry) {
532
604
  const parts = [];
533
605
  if (agentStep.nudgePrompt) {
534
606
  const resolvedNudge = resolveTemplate(agentStep.nudgePrompt, templateCtx);
@@ -538,32 +610,105 @@ async function executeWorkflow(workflow, options, subGroup) {
538
610
  nudgeContent = parts.join("\n\n");
539
611
  emitWorkflowMessage(eventStore, sessionId, nudgeContent, currentWindowMessageOptions, onMessage);
540
612
  }
613
+ const turnStartSeq = eventStore.getLatestSeq(sessionId) ?? 0;
614
+ let retryBlocked = null;
615
+ let blockedReason = "";
616
+ const retryPolicy = { ...DEFAULT_LLM_RETRY_POLICY, ...options.llmRetryPolicy };
617
+ const handleLLMFailure = async (errorMessage) => {
618
+ const failures = (stepLLMFailures.get(step.id) ?? 0) + 1;
619
+ stepLLMFailures.set(step.id, failures);
620
+ const firstFailureAt = stepLLMDeadlines.get(step.id) ?? Date.now();
621
+ stepLLMDeadlines.set(step.id, firstFailureAt);
622
+ const decision = evaluateLLMRetry(failures, firstFailureAt, Date.now(), retryPolicy);
623
+ if (decision.retry) {
624
+ rollbackFailedAttempt(sessionId, turnStartSeq);
625
+ firstEntryForStep.add(step.id);
626
+ resumeConsumed = true;
627
+ eventStore.append(sessionId, {
628
+ type: "workflow.step_retry",
629
+ data: { stepName: step.name, attempt: decision.attempt, retryInMs: decision.delayMs }
630
+ });
631
+ retryBlocked = "retry";
632
+ await sleepWithSignal(decision.delayMs, signal);
633
+ return;
634
+ }
635
+ rollbackFailedAttempt(sessionId, turnStartSeq);
636
+ sessionManager.setPhase(sessionId, "blocked");
637
+ if (executionId) {
638
+ sessionManager.blockWorkflow(
639
+ sessionId,
640
+ executionId,
641
+ workflow.metadata.id,
642
+ workflow.metadata.name,
643
+ workflow.metadata.color
644
+ );
645
+ }
646
+ blockedReason = `Step "${step.name}" failed after ${failures} attempts: ${errorMessage}`;
647
+ eventStore.append(sessionId, { type: "chat.error", data: { error: blockedReason, recoverable: false } });
648
+ retryBlocked = "blocked";
649
+ };
541
650
  const turnMetrics = new TurnMetrics();
542
651
  const es = getEventStore();
543
652
  const append = (event) => es.append(sessionId, event);
544
653
  let stepDoneCalled = false;
545
- const agentResult = await runAgentTurn(
546
- {
547
- sessionManager,
548
- sessionId,
549
- llmClient,
550
- ...options.statsIdentity ? { statsIdentity: options.statsIdentity } : {},
551
- ...signal ? { signal } : {},
552
- ...onMessage ? { onMessage } : {}
553
- },
554
- turnMetrics,
555
- agentStep.agentId ?? resolveDefaultAgentId(),
556
- append,
557
- {
558
- ...!firstEntryForStep.has(step.id) && !agentStep.prompt && !isResumingCurrentStep ? { injectKickoff: () => injectGenericKickoff(sessionId) } : {},
559
- onToolExecuted: (toolCall, toolResult) => {
560
- if (toolCall.name === "step_done" && toolResult.success) {
561
- stepDoneCalled = true;
654
+ let agentResult;
655
+ try {
656
+ agentResult = await runAgentTurn(
657
+ {
658
+ sessionManager,
659
+ sessionId,
660
+ llmClient,
661
+ ...options.statsIdentity ? { statsIdentity: options.statsIdentity } : {},
662
+ ...signal ? { signal } : {},
663
+ ...onMessage ? { onMessage } : {},
664
+ suppressRecoverableErrors: true,
665
+ ...isLLMFailedRetry || isResumingCurrentStep ? { skipAgentReminder: true } : {}
666
+ },
667
+ turnMetrics,
668
+ agentStep.agentId ?? resolveDefaultAgentId(),
669
+ append,
670
+ {
671
+ ...!firstEntryForStep.has(step.id) && !agentStep.prompt && !isResumingCurrentStep ? { injectKickoff: () => injectGenericKickoff(sessionId) } : {},
672
+ onToolExecuted: (toolCall, toolResult) => {
673
+ if (toolCall.name === "step_done" && toolResult.success) {
674
+ stepDoneCalled = true;
675
+ }
562
676
  }
563
677
  }
678
+ );
679
+ } catch (error) {
680
+ if (error instanceof Error && error.message === "Aborted") {
681
+ throw error;
564
682
  }
565
- );
683
+ if (!(error instanceof LLMError)) {
684
+ throw error;
685
+ }
686
+ await handleLLMFailure(error.message);
687
+ if (retryBlocked === "retry") {
688
+ iterations -= 1;
689
+ continue;
690
+ }
691
+ return {
692
+ finalAction: { type: "BLOCKED", reason: blockedReason, blockedCriteria: [] },
693
+ iterations,
694
+ totalTime: (performance.now() - startTime) / 1e3
695
+ };
696
+ }
697
+ if (agentResult.failed) {
698
+ await handleLLMFailure(agentResult.failed.error);
699
+ if (retryBlocked === "retry") {
700
+ iterations -= 1;
701
+ continue;
702
+ }
703
+ return {
704
+ finalAction: { type: "BLOCKED", reason: blockedReason, blockedCriteria: [] },
705
+ iterations,
706
+ totalTime: (performance.now() - startTime) / 1e3
707
+ };
708
+ }
566
709
  firstEntryForStep.add(step.id);
710
+ stepLLMFailures.delete(step.id);
711
+ stepLLMDeadlines.delete(step.id);
567
712
  resumeConsumed = true;
568
713
  const agentReturnValue = agentResult.returnValueResult ?? "completed";
569
714
  lastStepOutput = {
@@ -894,9 +1039,9 @@ function launchWorkflowRun(deps, payload) {
894
1039
  ...payload.stepOutput ? { initialStepOutput: payload.stepOutput } : {},
895
1040
  ...payload.userChoice ? { userChoice: payload.userChoice } : {},
896
1041
  ...payload.resumeFrom ? (() => {
897
- const exec = sessionManager.getActiveWorkflowExecution(sessionId);
1042
+ const exec = sessionManager.getLatestWorkflowExecution(sessionId);
898
1043
  if (!exec) return {};
899
- if (exec.status === "waiting") {
1044
+ if (exec.status === "waiting" || exec.status === "blocked") {
900
1045
  const resumed = sessionManager.resumeWorkflow(
901
1046
  sessionId,
902
1047
  exec.id,
@@ -954,4 +1099,4 @@ export {
954
1099
  abortRunnerRun,
955
1100
  launchWorkflowRun
956
1101
  };
957
- //# sourceMappingURL=chunk-3QQAIUZI.js.map
1102
+ //# sourceMappingURL=chunk-HYPXL7K5.js.map
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-3PG65AXG.js";
12
12
  import {
13
13
  parseDefaultModelSelection
14
- } from "./chunk-BVVCRIVM.js";
14
+ } from "./chunk-GZTMCTUS.js";
15
15
  import {
16
16
  getDatabase
17
17
  } from "./chunk-5PT4UMRR.js";
@@ -342,10 +342,11 @@ async function resolveSlashLaunch(configDir, projectDir, prompt) {
342
342
  }
343
343
 
344
344
  // src/server/db/tasks.ts
345
+ import { randomBytes } from "crypto";
345
346
  function createTask(projectId, input) {
346
347
  const db = getDatabase();
347
348
  const now = (/* @__PURE__ */ new Date()).toISOString();
348
- const id = crypto.randomUUID();
349
+ const id = randomBytes(8).toString("hex");
349
350
  const position = db.prepare(`SELECT COALESCE(MAX(position), -1) + 1 AS pos FROM tasks WHERE project_id = ? AND status = 'todo'`).get(projectId);
350
351
  db.prepare(
351
352
  `INSERT INTO tasks (id, project_id, prompt, attachments, status, run_state, position, version, agent_id, provider_id, model, created_at, updated_at)
@@ -1078,4 +1079,4 @@ export {
1078
1079
  isTaskGateError,
1079
1080
  createTasksService
1080
1081
  };
1081
- //# sourceMappingURL=chunk-6RGACY4E.js.map
1082
+ //# sourceMappingURL=chunk-HZSKKJHQ.js.map
@@ -396,6 +396,11 @@ function getActiveWorkflowExecution(sessionId) {
396
396
  ).get(sessionId);
397
397
  return row;
398
398
  }
399
+ function getLatestWorkflowExecution(sessionId) {
400
+ const db = getDatabase();
401
+ const row = db.prepare(`SELECT * FROM workflow_executions WHERE session_id = ? ORDER BY updated_at DESC LIMIT 1`).get(sessionId);
402
+ return row;
403
+ }
399
404
  function clearWorkflowExecution(executionId) {
400
405
  const db = getDatabase();
401
406
  const now = Date.now();
@@ -427,6 +432,7 @@ export {
427
432
  createWorkflowExecution,
428
433
  updateWorkflowExecutionStatus,
429
434
  getActiveWorkflowExecution,
435
+ getLatestWorkflowExecution,
430
436
  clearWorkflowExecution
431
437
  };
432
- //# sourceMappingURL=chunk-VWEATA7R.js.map
438
+ //# sourceMappingURL=chunk-KLQEL2DZ.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getModelProfile
3
- } from "./chunk-V4IE7HJY.js";
3
+ } from "./chunk-W7VIYHPQ.js";
4
4
  import {
5
5
  getBackendCapabilities
6
6
  } from "./chunk-AZHWLLPP.js";
@@ -310,4 +310,4 @@ function createLLMClient(config, initialBackend = "unknown") {
310
310
  export {
311
311
  createLLMClient
312
312
  };
313
- //# sourceMappingURL=chunk-JGWHRYWG.js.map
313
+ //# sourceMappingURL=chunk-MKWS7TQH.js.map
@@ -3,7 +3,7 @@ import {
3
3
  isCancel,
4
4
  password,
5
5
  select
6
- } from "./chunk-4H427UBV.js";
6
+ } from "./chunk-AGXJ5O63.js";
7
7
 
8
8
  // src/cli/main.ts
9
9
  import { parseArgs } from "util";
@@ -36,9 +36,9 @@ Options:
36
36
  `);
37
37
  }
38
38
  async function runNetworkSetup(mode) {
39
- const { loadAuthConfig, saveAuthConfig, encryptPassword } = await import("./auth-YY5PJYSC.js");
40
- const { saveGlobalConfig } = await import("./config-EAB3V4QK.js");
41
- const { getAuthKeyPath } = await import("./paths-F27V3S4I.js");
39
+ const { loadAuthConfig, saveAuthConfig, encryptPassword } = await import("./auth-GTGIGX5X.js");
40
+ const { saveGlobalConfig } = await import("./config-TUCHLIWD.js");
41
+ const { getAuthKeyPath } = await import("./paths-BHR7CZ7I.js");
42
42
  const existingAuth = await loadAuthConfig(mode);
43
43
  if (existingAuth) {
44
44
  return;
@@ -104,8 +104,8 @@ async function runNetworkSetup(mode) {
104
104
  console.log("\u2713 Configuration saved!\n");
105
105
  }
106
106
  async function runConfig(mode) {
107
- const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-EAB3V4QK.js");
108
- const { getGlobalConfigPath } = await import("./paths-F27V3S4I.js");
107
+ const { loadGlobalConfig, getActiveProvider, getDefaultModel } = await import("./config-TUCHLIWD.js");
108
+ const { getGlobalConfigPath } = await import("./paths-BHR7CZ7I.js");
109
109
  const config = await loadGlobalConfig(mode);
110
110
  const configPath = getGlobalConfigPath(mode);
111
111
  const activeProvider = getActiveProvider(config);
@@ -163,13 +163,13 @@ async function runCli(options) {
163
163
  break;
164
164
  }
165
165
  case "provider": {
166
- const { runProviderCommand } = await import("./provider-DL4ZWQY7.js");
166
+ const { runProviderCommand } = await import("./provider-Q7J4UFTS.js");
167
167
  const [, subcommand] = positionals;
168
168
  await runProviderCommand(mode, subcommand);
169
169
  break;
170
170
  }
171
171
  case "service": {
172
- const { runServiceCommand } = await import("./service-CXWJQFOZ.js");
172
+ const { runServiceCommand } = await import("./service-WKABQHKL.js");
173
173
  const [, subcommand, ...serviceArgs] = positionals;
174
174
  if (values.follow) {
175
175
  serviceArgs.push("-f");
@@ -182,7 +182,7 @@ async function runCli(options) {
182
182
  break;
183
183
  }
184
184
  case "pwa": {
185
- const { runPwaCommand, printPwaHelp } = await import("./pwa-XPHP3PY2.js");
185
+ const { runPwaCommand, printPwaHelp } = await import("./pwa-2GRFSXD7.js");
186
186
  const [, subcommand] = positionals;
187
187
  if (subcommand === "--help" || subcommand === "-h" || values.help) {
188
188
  printPwaHelp();
@@ -192,7 +192,7 @@ async function runCli(options) {
192
192
  break;
193
193
  }
194
194
  case "install": {
195
- const { runInstall } = await import("./install-CPOPMCSE.js");
195
+ const { runInstall } = await import("./install-VA2F6X6Z.js");
196
196
  const code = await runInstall({ check: values.check === true });
197
197
  if (code !== 0) {
198
198
  process.exit(code);
@@ -200,7 +200,7 @@ async function runCli(options) {
200
200
  break;
201
201
  }
202
202
  case "update": {
203
- const { runUpdate } = await import("./update-2REP2WB6.js");
203
+ const { runUpdate } = await import("./update-TDS6LP5N.js");
204
204
  const code = await runUpdate();
205
205
  if (code !== 0) {
206
206
  process.exit(code);
@@ -208,12 +208,12 @@ async function runCli(options) {
208
208
  break;
209
209
  }
210
210
  default: {
211
- const { configFileExists } = await import("./config-EAB3V4QK.js");
211
+ const { configFileExists } = await import("./config-TUCHLIWD.js");
212
212
  const configExists = await configFileExists(mode);
213
213
  if (!configExists) {
214
214
  await runNetworkSetup(mode);
215
215
  }
216
- const { runServe } = await import("./serve-DARV4NJG.js");
216
+ const { runServe } = await import("./serve-KR22J37W.js");
217
217
  const serveOptions = { mode };
218
218
  if (values.port) serveOptions.port = parseInt(values.port);
219
219
  if (values["no-browser"] === true) serveOptions.openBrowser = false;
@@ -225,4 +225,4 @@ async function runCli(options) {
225
225
  export {
226
226
  runCli
227
227
  };
228
- //# sourceMappingURL=chunk-37QLXLML.js.map
228
+ //# sourceMappingURL=chunk-QJWTBVJO.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getEventStore
3
- } from "./chunk-ERNWAKUB.js";
3
+ } from "./chunk-TGVDUK4N.js";
4
4
  import {
5
5
  createChatPathConfirmationMessage
6
- } from "./chunk-I7FY2LTR.js";
6
+ } from "./chunk-4GHLULHB.js";
7
7
  import {
8
8
  getPlatformShell
9
9
  } from "./chunk-AESOGRFK.js";
@@ -140,6 +140,151 @@ function normalizeExtracted(path) {
140
140
  function isPlaceholderToken(str) {
141
141
  return str.includes("__URL__") || str.includes("__FILEURL__") || str.includes("__SED__") || str.includes("__COMMIT_MSG__");
142
142
  }
143
+ var REGEX_TOOL_RE = /\b(?:sed|awk|gawk|mawk|perl|ruby|raku)\b/;
144
+ var SHELL_TOKEN_END_RE = /[\s'"`|&;,<>()]/;
145
+ function isRegexAddress(command, start, end, hasRegexTool, quote) {
146
+ const content = command.slice(start + 1, end);
147
+ if (looksLikeRegex(content)) return true;
148
+ if (command[end + 1] === ",") return true;
149
+ if (quote === null && command[start - 1] === "~" && (command[start - 2] === "=" || command[start - 2] === "!")) {
150
+ return true;
151
+ }
152
+ const action = command[end + 1];
153
+ if (action !== void 0 && /[a-zA-Z]/.test(action)) {
154
+ const after = command[end + 2];
155
+ const terminated = quote === null ? SHELL_TOKEN_END_RE.test(after ?? "") : after === quote;
156
+ if (terminated) return true;
157
+ }
158
+ return hasRegexTool && quote !== null && !/\s/.test(content);
159
+ }
160
+ function maskRegexAddresses(command) {
161
+ const work = command.replace(/(?:=|!)~\s+/g, " __SED__ ");
162
+ if (!work.includes("/")) return work;
163
+ const hasRegexTool = REGEX_TOOL_RE.test(work);
164
+ const out = [];
165
+ let quote = null;
166
+ let i = 0;
167
+ const n = work.length;
168
+ const maskSpan = (end) => {
169
+ if (out[out.length - 1] === "~" && (out[out.length - 2] === "=" || out[out.length - 2] === "!")) {
170
+ out.pop();
171
+ out.pop();
172
+ }
173
+ out.push(" __SED__ ");
174
+ i = end + 1;
175
+ };
176
+ while (i < n) {
177
+ const ch = work[i];
178
+ if (quote !== null) {
179
+ if (ch === "\\" && quote !== "'") {
180
+ out.push(ch, work[i + 1] ?? "");
181
+ i += 2;
182
+ continue;
183
+ }
184
+ if (ch === quote) {
185
+ out.push(ch);
186
+ quote = null;
187
+ i += 1;
188
+ continue;
189
+ }
190
+ if (ch === "/") {
191
+ let j = i + 1;
192
+ while (j < n) {
193
+ if (work[j] === "\\" && quote !== "'") {
194
+ j += 2;
195
+ continue;
196
+ }
197
+ if (work[j] === quote || work[j] === "/") break;
198
+ j += 1;
199
+ }
200
+ if (j < n && work[j] === "/" && isRegexAddress(work, i, j, hasRegexTool, quote)) {
201
+ maskSpan(j);
202
+ continue;
203
+ }
204
+ }
205
+ out.push(ch);
206
+ i += 1;
207
+ continue;
208
+ }
209
+ if (ch === "'" || ch === '"' || ch === "`") {
210
+ quote = ch;
211
+ out.push(ch);
212
+ i += 1;
213
+ continue;
214
+ }
215
+ if (ch === "/") {
216
+ let j = i + 1;
217
+ while (j < n && work[j] !== "/" && !/[\s|&;<>()'"`]/.test(work[j])) j += 1;
218
+ if (j < n && work[j] === "/" && isRegexAddress(work, i, j, hasRegexTool, null)) {
219
+ maskSpan(j);
220
+ continue;
221
+ }
222
+ }
223
+ out.push(ch);
224
+ i += 1;
225
+ }
226
+ return out.join("");
227
+ }
228
+ function extractUnquotedTildePaths(command, home) {
229
+ const paths = [];
230
+ let quote = null;
231
+ let i = 0;
232
+ const n = command.length;
233
+ while (i < n) {
234
+ const ch = command[i];
235
+ if (quote !== null) {
236
+ if (ch === "\\" && quote !== "'") {
237
+ i += 2;
238
+ continue;
239
+ }
240
+ if (ch === quote) {
241
+ quote = null;
242
+ i += 1;
243
+ continue;
244
+ }
245
+ i += 1;
246
+ continue;
247
+ }
248
+ if (ch === "'" || ch === '"' || ch === "`") {
249
+ quote = ch;
250
+ i += 1;
251
+ continue;
252
+ }
253
+ if (ch === "~" && (i === 0 || /[\s=(]/.test(command[i - 1]))) {
254
+ let j = i + 1;
255
+ while (j < n && !/[\s'"()]/.test(command[j])) j += 1;
256
+ const tail = command.slice(i + 1, j);
257
+ if (tail === "" || tail.startsWith("/")) {
258
+ const resolved = normalize(resolve(home + tail));
259
+ if (!isSafePath(resolved)) {
260
+ paths.push(resolved);
261
+ }
262
+ }
263
+ i = j;
264
+ continue;
265
+ }
266
+ i += 1;
267
+ }
268
+ return paths;
269
+ }
270
+ var TRAVERSAL_SEGMENT_RE = /(?:^|\/)\.\.(?:\/|$)/;
271
+ function extractRelativeTraversals(command) {
272
+ const out = [];
273
+ const isTraversal = (token) => TRAVERSAL_SEGMENT_RE.test(token);
274
+ const quotedPattern = /["']([^"']+)["']/g;
275
+ let m;
276
+ while ((m = quotedPattern.exec(command)) !== null) {
277
+ const content = m[1];
278
+ if (!content || content.startsWith("/") || content.startsWith("~") || isWindowsAbsolutePath(content)) continue;
279
+ if (isTraversal(content)) out.push(content);
280
+ }
281
+ const bare = command.replace(/["'][^"']*["']/g, " ").split(/[\s|&;<>()]+/);
282
+ for (const token of bare) {
283
+ if (!token || token.startsWith("/") || token.startsWith("~")) continue;
284
+ if (isTraversal(token)) out.push(token);
285
+ }
286
+ return [...new Set(out)];
287
+ }
143
288
  function extractAbsolutePathsFromCommand(command) {
144
289
  if (!command.trim()) {
145
290
  return [];
@@ -151,6 +296,7 @@ function extractAbsolutePathsFromCommand(command) {
151
296
  sanitized = sanitized.replace(/(?<!\w)s\/[^/]*\/[^/]*\/[gip]*/g, " __SED__ ");
152
297
  sanitized = sanitized.replace(/(?<!\w)s\|[^|]*\|[^|]*\|[gip]*/g, " __SED__ ");
153
298
  sanitized = sanitized.replace(/(?<!\w)s:[^:]*:[^:]*:[gip]*/g, " __SED__ ");
299
+ sanitized = maskRegexAddresses(sanitized);
154
300
  sanitized = sanitized.replace(
155
301
  /git\s+commit\b.*?(?:-(?:[a-zA-Z]*m)(?=\s)|--message)\s+(["'])(?:(?!\1).)*\1/g,
156
302
  (match2) => match2.replace(/\/[^\s"'|&;<>`()]+/g, " __COMMIT_MSG__ ")
@@ -163,17 +309,9 @@ function extractAbsolutePathsFromCommand(command) {
163
309
  }
164
310
  }
165
311
  sanitized = sanitized.replace(/file:\/\/[^\s'"]+/g, " __FILEURL__ ");
166
- const tildePattern = /(?:^|[\s='"(])~(\/[^\s'"()]*)?(?=[\s'"()]|$)/g;
167
- let match;
168
- while ((match = tildePattern.exec(sanitized)) !== null) {
169
- const pathPart = match[1] ?? "";
170
- const fullPath = home + pathPart;
171
- const resolved = normalize(resolve(fullPath));
172
- if (!isSafePath(resolved)) {
173
- paths.push(resolved);
174
- }
175
- }
312
+ paths.push(...extractUnquotedTildePaths(sanitized, home));
176
313
  const quotedPattern = /["']([^"']+)["']/g;
314
+ let match;
177
315
  while ((match = quotedPattern.exec(sanitized)) !== null) {
178
316
  const content = match[1];
179
317
  if (content.startsWith("/") && content.endsWith("/")) {
@@ -192,13 +330,6 @@ function extractAbsolutePathsFromCommand(command) {
192
330
  if (!isSafePath(resolved)) {
193
331
  paths.push(resolved);
194
332
  }
195
- } else if (content.startsWith("~")) {
196
- const pathPart = content.slice(1);
197
- const fullPath = join(home, pathPart);
198
- const resolved = normalize(resolve(fullPath));
199
- if (!isSafePath(resolved)) {
200
- paths.push(resolved);
201
- }
202
333
  }
203
334
  }
204
335
  if (isWindows()) {
@@ -214,6 +345,10 @@ function extractAbsolutePathsFromCommand(command) {
214
345
  }
215
346
  if (posixShell) {
216
347
  const absolutePattern = /(?:^|[\s=(])(\/[^\s"'|&;<>`()]+)/g;
348
+ const rootPattern = /(?:^|[\s=(])\/(?=$|[\s'"`|&;,<()])/g;
349
+ if (rootPattern.test(sanitized)) {
350
+ paths.push("/");
351
+ }
217
352
  while ((match = absolutePattern.exec(sanitized)) !== null) {
218
353
  const candidate = match[1];
219
354
  if (isPlaceholderToken(candidate)) continue;
@@ -225,6 +360,7 @@ function extractAbsolutePathsFromCommand(command) {
225
360
  }
226
361
  }
227
362
  }
363
+ paths.push(...extractRelativeTraversals(sanitized));
228
364
  return [...new Set(paths)];
229
365
  }
230
366
  function extractSensitivePathsFromCommand(command) {
@@ -535,4 +671,4 @@ export {
535
671
  getConfirmationSessionId,
536
672
  getPendingConfirmationsBySession
537
673
  };
538
- //# sourceMappingURL=chunk-6KPJLELC.js.map
674
+ //# sourceMappingURL=chunk-QQVPUZQB.js.map