@sealant/mend 0.16.0 → 0.18.0

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 (51) hide show
  1. package/dist/dashboard-model.js +8 -0
  2. package/dist/dashboard.js +12 -3
  3. package/dist/help.js +824 -0
  4. package/dist/main.js +129 -127
  5. package/dist/version.js +48 -0
  6. package/man/mend-accounts.1 +11 -0
  7. package/man/mend-adopt.1 +27 -0
  8. package/man/mend-attach.1 +13 -0
  9. package/man/mend-codex.1 +60 -0
  10. package/man/mend-completions.1 +14 -0
  11. package/man/mend-connect.1 +25 -0
  12. package/man/mend-continue.1 +11 -0
  13. package/man/mend-doctor.1 +11 -0
  14. package/man/mend-dotfiles-sync.1 +15 -0
  15. package/man/mend-dotfiles.1 +11 -0
  16. package/man/mend-env-cluster.1 +26 -0
  17. package/man/mend-env-load.1 +21 -0
  18. package/man/mend-env-show.1 +15 -0
  19. package/man/mend-help.1 +11 -0
  20. package/man/mend-keys-init.1 +11 -0
  21. package/man/mend-keys-share.1 +11 -0
  22. package/man/mend-keys-show.1 +11 -0
  23. package/man/mend-login.1 +20 -0
  24. package/man/mend-logout.1 +11 -0
  25. package/man/mend-man.1 +11 -0
  26. package/man/mend-pair.1 +15 -0
  27. package/man/mend-projects.1 +11 -0
  28. package/man/mend-refresh.1 +11 -0
  29. package/man/mend-rejoin.1 +15 -0
  30. package/man/mend-resume.1 +15 -0
  31. package/man/mend-run.1 +18 -0
  32. package/man/mend-service-add.1 +21 -0
  33. package/man/mend-service-connect.1 +15 -0
  34. package/man/mend-service-init.1 +15 -0
  35. package/man/mend-service-list.1 +11 -0
  36. package/man/mend-service-logs.1 +15 -0
  37. package/man/mend-service-restart.1 +11 -0
  38. package/man/mend-service-run.1 +38 -0
  39. package/man/mend-service-stop.1 +11 -0
  40. package/man/mend-sessions.1 +27 -0
  41. package/man/mend-shell.1 +13 -0
  42. package/man/mend-skills-push.1 +21 -0
  43. package/man/mend-skills.1 +15 -0
  44. package/man/mend-ssh-setup.1 +15 -0
  45. package/man/mend-ssh.1 +11 -0
  46. package/man/mend-stop.1 +22 -0
  47. package/man/mend-ui.1 +13 -0
  48. package/man/mend-version.1 +11 -0
  49. package/man/mend-worktrees.1 +18 -0
  50. package/man/mend.1 +165 -0
  51. package/package.json +8 -3
@@ -208,6 +208,14 @@ export const foldGroupStatus = (group) => {
208
208
  * Null = nothing attachable; opening a new shell is then honest.
209
209
  */
210
210
  export const liveShellOf = (processes) => processes.findLast((process) => process.kind === "shell" && process.exitedAt === null) ?? null;
211
+ /**
212
+ * The session's live protocol agent — a phone pickup driving the same
213
+ * conversation over stream-json. It holds the workspace with no PTY behind it,
214
+ * so a terminal "get me in" must take it over (hand back to a TUI) rather than
215
+ * report the attach unavailable or open a bare shell. Null = no pickup to take.
216
+ */
217
+ export const liveProtocolOf = (processes) => processes.find((process) => process.kind === "agent-protocol" && process.exitedAt === null) ??
218
+ null;
211
219
  /**
212
220
  * The optimistic stop: the row settles AND its live process/service fact
213
221
  * lines drop in the same paint — the server's refetch only confirms.
package/dist/dashboard.js CHANGED
@@ -3,7 +3,7 @@ import { CliRenderEvents, createCliRenderer } from "@opentui/core";
3
3
  import { createRoot, useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/react";
4
4
  import { QueryClient, QueryClientProvider, useMutation, useQuery, useQueryClient, } from "@tanstack/react-query";
5
5
  import { useEffect, useRef, useState } from "react";
6
- import { deriveHarnesses, deriveProjects, advanceFromBase, deriveRows, deriveWorktrees, filterBranches, foldGroupStatus, labelIsIdentity, rowKeyOf, worktreeDisplayName, fetchWorkbench, liveShellOf, mapWorkbenchSessions, markSessionStopped, removeWorktreeGroup, prependSession, removeSession, replaceSession, WORKBENCH_KEY, } from "./dashboard-model.js";
6
+ import { deriveHarnesses, deriveProjects, advanceFromBase, deriveRows, deriveWorktrees, filterBranches, foldGroupStatus, labelIsIdentity, rowKeyOf, worktreeDisplayName, fetchWorkbench, liveProtocolOf, liveShellOf, mapWorkbenchSessions, markSessionStopped, removeWorktreeGroup, prependSession, removeSession, replaceSession, WORKBENCH_KEY, } from "./dashboard-model.js";
7
7
  import { reviewTargetForSession } from "./review-workflow.js";
8
8
  import { ReviewScreen } from "./review.js";
9
9
  import { cwdFacts, HARNESS_COMMANDS, isPendingId, LIVE_STATUSES, matchProjectByCwd, normalizeProjectName, pendingId, } from "./shared.js";
@@ -261,8 +261,17 @@ const App = ({ ctx, onQuit }) => {
261
261
  // one when nothing is attachable (stacking a new bash per attempt is
262
262
  // how a session ends up held open by orphan shells).
263
263
  const detail = await ctx.api("GET", `/sessions/${session.id}`);
264
+ const liveProtocol = liveProtocolOf(detail.processes);
264
265
  const existing = liveShellOf(detail.processes);
265
- if (existing !== null) {
266
+ if (liveProtocol !== null) {
267
+ // A phone pickup holds the session in protocol mode — no PTY behind
268
+ // it. Take it over: end the protocol agent, resume the same
269
+ // conversation as a TUI, then attach to that.
270
+ process.stdout.write(`taking over from the protocol session — same conversation…\n\n`);
271
+ await ctx.api("POST", `/sessions/${session.id}/handoff`, { to: "pty" });
272
+ outcome = await ctx.attachTty(session.id, session.harness);
273
+ }
274
+ else if (existing !== null) {
266
275
  process.stdout.write(`no live terminal — rejoining the open shell\n\n`);
267
276
  outcome = await ctx.attachTty(session.id, "shell", existing.id);
268
277
  }
@@ -997,7 +1006,7 @@ const App = ({ ctx, onQuit }) => {
997
1006
  ? " ↑↓ move · enter start · esc cancel"
998
1007
  : focus === "projects"
999
1008
  ? " ↑↓ move · enter/l sessions · ⇥ panes · r refresh · q quit"
1000
- : " ↑↓ move · enter attach/resume · n new worktree · s session here · x stop · ⇧D remove · v review · e rename · o web · q quit";
1009
+ : " ↑↓ move · enter attach/resume · n new worktree · s session here · ⇧K kill · ⇧D remove · v review · e rename · o web · q quit";
1001
1010
  const loadFailure = data === undefined && failureReason !== null
1002
1011
  ? failureReason instanceof Error
1003
1012
  ? failureReason.message