@sealant/mend 0.33.0 → 0.34.4

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 (80) hide show
  1. package/README.md +74 -13
  2. package/dist/{chunk-GJFMD7XF.js → chunk-AAAXHRWL.js} +457 -87
  3. package/dist/{dashboard-NWHR7I5W.js → dashboard-DWXXYFPE.js} +41 -13
  4. package/dist/main.js +916 -322
  5. package/man/mend-accounts.1 +1 -1
  6. package/man/mend-adopt.1 +1 -1
  7. package/man/mend-attach.1 +1 -1
  8. package/man/mend-codex.1 +1 -1
  9. package/man/mend-completions.1 +1 -1
  10. package/man/mend-connect.1 +1 -1
  11. package/man/mend-continue.1 +1 -1
  12. package/man/mend-doctor.1 +2 -2
  13. package/man/mend-dotfiles-repo.1 +1 -1
  14. package/man/mend-dotfiles-sync.1 +1 -1
  15. package/man/mend-dotfiles.1 +1 -1
  16. package/man/mend-env-cluster.1 +1 -1
  17. package/man/mend-env-load.1 +1 -1
  18. package/man/mend-env-show.1 +1 -1
  19. package/man/mend-folder-create.1 +1 -1
  20. package/man/mend-folder-list.1 +1 -1
  21. package/man/mend-folder-push.1 +1 -1
  22. package/man/mend-folder-rm.1 +1 -1
  23. package/man/mend-git-author.1 +1 -1
  24. package/man/mend-help.1 +1 -1
  25. package/man/mend-invite.1 +1 -1
  26. package/man/mend-keys-init.1 +1 -1
  27. package/man/mend-keys-mode.1 +1 -1
  28. package/man/mend-keys-share.1 +1 -1
  29. package/man/mend-keys-show.1 +1 -1
  30. package/man/mend-land.1 +1 -1
  31. package/man/mend-login.1 +1 -1
  32. package/man/mend-logout.1 +1 -1
  33. package/man/mend-man.1 +1 -1
  34. package/man/mend-members.1 +1 -1
  35. package/man/mend-operator-exposure.1 +1 -1
  36. package/man/mend-operator-gate.1 +1 -1
  37. package/man/mend-operator-grant-owner.1 +1 -1
  38. package/man/mend-operator-org-create.1 +1 -1
  39. package/man/mend-operator-org-invite-owner.1 +1 -1
  40. package/man/mend-operator-org-list.1 +1 -1
  41. package/man/mend-operator-org-rename.1 +1 -1
  42. package/man/mend-operator-reset-link.1 +1 -1
  43. package/man/mend-pair.1 +1 -1
  44. package/man/mend-projects.1 +1 -1
  45. package/man/mend-pull.1 +1 -1
  46. package/man/mend-refresh.1 +1 -1
  47. package/man/mend-rejoin.1 +1 -1
  48. package/man/mend-resume.1 +1 -1
  49. package/man/mend-run.1 +1 -1
  50. package/man/mend-server-logs.1 +1 -1
  51. package/man/mend-server-restart.1 +1 -1
  52. package/man/mend-server-setup.1 +1 -1
  53. package/man/mend-server-start.1 +1 -1
  54. package/man/mend-server-status.1 +1 -1
  55. package/man/mend-server-stop.1 +1 -1
  56. package/man/mend-server-upgrade.1 +1 -1
  57. package/man/mend-server.1 +1 -1
  58. package/man/mend-service-add.1 +1 -1
  59. package/man/mend-service-connect.1 +1 -1
  60. package/man/mend-service-init.1 +1 -1
  61. package/man/mend-service-list.1 +1 -1
  62. package/man/mend-service-logs.1 +1 -1
  63. package/man/mend-service-restart.1 +1 -1
  64. package/man/mend-service-run.1 +1 -1
  65. package/man/mend-service-stop.1 +1 -1
  66. package/man/mend-session-share.1 +1 -1
  67. package/man/mend-sessions.1 +1 -1
  68. package/man/mend-shell.1 +1 -1
  69. package/man/mend-skills-push.1 +1 -1
  70. package/man/mend-skills.1 +1 -1
  71. package/man/mend-snake.1 +1 -1
  72. package/man/mend-ssh-setup.1 +1 -1
  73. package/man/mend-ssh.1 +1 -1
  74. package/man/mend-stop.1 +1 -1
  75. package/man/mend-ui.1 +1 -1
  76. package/man/mend-uninstall.1 +1 -1
  77. package/man/mend-version.1 +1 -1
  78. package/man/mend-worktrees.1 +1 -1
  79. package/man/mend.1 +1 -1
  80. package/package.json +3 -3
@@ -4,16 +4,18 @@ import {
4
4
  RepositoryCloneUrl,
5
5
  agentIsLive,
6
6
  agentOutcome,
7
+ captureLineOf,
7
8
  createSseParser,
8
9
  cwdFacts,
9
10
  eventFamilies,
10
11
  isPendingId,
11
12
  matchProjectByCwd,
13
+ mayStillBeWorking,
12
14
  normalizeProjectName,
13
15
  pendingId,
14
16
  repositoryCloneUrlIssue,
15
17
  servicesHoldLine
16
- } from "./chunk-GJFMD7XF.js";
18
+ } from "./chunk-AAAXHRWL.js";
17
19
 
18
20
  // src/dashboard.tsx
19
21
  import { CliRenderEvents, createCliRenderer } from "@opentui/core";
@@ -242,6 +244,7 @@ var liveProtocolOf = (processes) => processes.find((process2) => process2.kind =
242
244
  var planAttach = (session) => {
243
245
  if (session === null) return { kind: "none" };
244
246
  if (isPendingId(session.id)) return { kind: "pending", session };
247
+ if (session.status === "stopping") return { kind: "stopping", session };
245
248
  if (!LIVE_STATUSES.has(session.status)) return { kind: "settled", session };
246
249
  if (session.status === "starting") return { kind: "starting", session };
247
250
  return { kind: "attach", session };
@@ -285,6 +288,8 @@ var markServicesStopped = (data, sessionId) => {
285
288
  };
286
289
  var AGENT_WORKING = /* @__PURE__ */ new Set(["starting", "running", "waiting"]);
287
290
  var sessionHold = (item) => {
291
+ const capture = captureLineOf(item.session);
292
+ if (capture !== null) return capture;
288
293
  const agent = item.annotation?.currentAgent ?? null;
289
294
  const agentProcessLive = item.processes.some(
290
295
  (process2) => process2.kind !== "shell" && process2.exitedAt === null
@@ -2408,6 +2413,15 @@ var StatusLine = ({
2408
2413
  return /* @__PURE__ */ jsx3("text", { height: 1, fg: INK_2, bg: "transparent", children: text });
2409
2414
  };
2410
2415
  var errorText = (error) => error instanceof Error ? error.message : String(error);
2416
+ var startedOrStarting = async (start, starting) => {
2417
+ try {
2418
+ return await start;
2419
+ } catch (error) {
2420
+ if (mayStillBeWorking(error)) return { ...starting, status: "starting" };
2421
+ throw error;
2422
+ }
2423
+ };
2424
+ var startedLine = (session) => session.status === "starting" ? `still starting \xB7 ${sessionDisplayName(session)} \u2014 a attaches once the row reads running` : `started \xB7 ${sessionDisplayName(session)} \u2014 a attaches`;
2411
2425
  var keepSpanVisible = (scroll, top, height, viewRows) => {
2412
2426
  if (scroll === null || viewRows <= 0) return;
2413
2427
  const viewH = Math.max(1, viewRows);
@@ -2593,7 +2607,7 @@ var App = ({ ctx, onQuit }) => {
2593
2607
  `).join("");
2594
2608
  process.stdout.write(
2595
2609
  `
2596
- attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
2610
+ attaching \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
2597
2611
  ${tunneled}
2598
2612
  `
2599
2613
  );
@@ -2637,7 +2651,7 @@ ${tunneled}
2637
2651
  lockRef.current = false;
2638
2652
  }
2639
2653
  say(
2640
- outcome === "unavailable" ? "attach unavailable \u2014 could not connect" : outcome === "detached" || outcome === "interrupted" ? `detached \u2014 ${short} keeps running` : outcome === "dropped" ? `disconnected \xB7 ${short} \u2014 refreshing session status` : `terminal ended \xB7 ${short} \u2014 refreshing session status`
2654
+ outcome === "unavailable" ? "attach unavailable \u2014 could not connect" : outcome === "no-answer" ? `no answer \u2014 the server did not open ${short}'s terminal; it keeps running \xB7 a tries again` : outcome === "detached" || outcome === "interrupted" ? `detached \u2014 ${short} keeps running` : outcome === "dropped" ? `disconnected \xB7 ${short} \u2014 refreshing session status` : `terminal ended \xB7 ${short} \u2014 refreshing session status`
2641
2655
  );
2642
2656
  refetch();
2643
2657
  };
@@ -2659,8 +2673,10 @@ ${tunneled}
2659
2673
  name: vars.name,
2660
2674
  base: vars.base
2661
2675
  });
2662
- await ctx.api("POST", `/sessions/${session.id}/launch`, { argv });
2663
- return session;
2676
+ return startedOrStarting(
2677
+ ctx.api("POST", `/sessions/${session.id}/launch`, { argv }),
2678
+ session
2679
+ );
2664
2680
  },
2665
2681
  onMutate: async (vars) => {
2666
2682
  await queryClient.cancelQueries({ queryKey: WORKBENCH_KEY });
@@ -2696,7 +2712,7 @@ ${tunneled}
2696
2712
  );
2697
2713
  setSessionKey((current) => current === vars.pendingKey ? session.id : current);
2698
2714
  setBusy(null);
2699
- say(`started \xB7 ${sessionDisplayName(session)} \u2014 a attaches`);
2715
+ say(startedLine(session));
2700
2716
  },
2701
2717
  onSettled: (_data, _error, vars) => {
2702
2718
  gate.release(vars.gateKey);
@@ -2704,9 +2720,12 @@ ${tunneled}
2704
2720
  }
2705
2721
  });
2706
2722
  const resumeMutation = useMutation2({
2707
- mutationFn: (vars) => ctx.api("POST", `/sessions/${vars.session.id}/resume`, {
2708
- harness: vars.harness
2709
- }),
2723
+ mutationFn: (vars) => startedOrStarting(
2724
+ ctx.api("POST", `/sessions/${vars.session.id}/resume`, {
2725
+ harness: vars.harness
2726
+ }),
2727
+ vars.session
2728
+ ),
2710
2729
  onMutate: async (vars) => {
2711
2730
  await queryClient.cancelQueries({ queryKey: WORKBENCH_KEY });
2712
2731
  patchWorkbench(
@@ -2731,7 +2750,9 @@ ${tunneled}
2731
2750
  (current) => replaceSession(current, vars.projectId, vars.session.id, resumed)
2732
2751
  );
2733
2752
  setBusy(null);
2734
- say(`resumed \xB7 ${sessionDisplayName(resumed)} \u2014 a attaches`);
2753
+ say(
2754
+ resumed.status === "starting" ? `still resuming \xB7 ${sessionDisplayName(resumed)} \u2014 a attaches once the row reads running` : `resumed \xB7 ${sessionDisplayName(resumed)} \u2014 a attaches`
2755
+ );
2735
2756
  },
2736
2757
  onSettled: (_data, _error, vars) => {
2737
2758
  gate.release(vars.gateKey);
@@ -2842,8 +2863,10 @@ ${tunneled}
2842
2863
  harness: vars.harness,
2843
2864
  label: null
2844
2865
  });
2845
- await ctx.api("POST", `/sessions/${session.id}/launch`, { argv });
2846
- return session;
2866
+ return startedOrStarting(
2867
+ ctx.api("POST", `/sessions/${session.id}/launch`, { argv }),
2868
+ session
2869
+ );
2847
2870
  },
2848
2871
  onMutate: async (vars) => {
2849
2872
  await queryClient.cancelQueries({ queryKey: WORKBENCH_KEY });
@@ -2876,7 +2899,7 @@ ${tunneled}
2876
2899
  );
2877
2900
  setSessionKey((current) => current === vars.pendingKey ? session.id : current);
2878
2901
  setBusy(null);
2879
- say(`started \xB7 ${sessionDisplayName(session)} \u2014 a attaches`);
2902
+ say(startedLine(session));
2880
2903
  },
2881
2904
  onSettled: (_data, _error, vars) => {
2882
2905
  gate.release(vars.gateKey);
@@ -3121,6 +3144,11 @@ ${tunneled}
3121
3144
  case "settled":
3122
3145
  say(`settled \xB7 ${sessionDisplayName(plan.session)} \u2014 r resumes it, \u21E7D removes it`);
3123
3146
  return;
3147
+ case "stopping":
3148
+ say(
3149
+ `stopping \xB7 ${sessionDisplayName(plan.session)} \xB7 ${captureLineOf(plan.session) ?? "saving"}`
3150
+ );
3151
+ return;
3124
3152
  case "pending":
3125
3153
  say("still provisioning \u2014 the row fills in when the workspace answers");
3126
3154
  return;