@h-rig/cli 0.0.6-alpha.82 → 0.0.6-alpha.84

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 (206) hide show
  1. package/dist/bin/build-rig-binaries.js +40 -8
  2. package/dist/bin/rig.js +23402 -14577
  3. package/dist/src/app/board.js +217 -41
  4. package/dist/src/app-opentui/adapters/command.d.ts +2 -0
  5. package/dist/src/app-opentui/adapters/command.js +329 -0
  6. package/dist/src/app-opentui/adapters/common.js +2 -2
  7. package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
  8. package/dist/src/app-opentui/adapters/doctor.js +64 -39
  9. package/dist/src/app-opentui/adapters/family.d.ts +62 -0
  10. package/dist/src/app-opentui/adapters/family.js +14305 -0
  11. package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
  12. package/dist/src/app-opentui/adapters/fleet.js +90 -60
  13. package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
  14. package/dist/src/app-opentui/adapters/inbox.js +137 -78
  15. package/dist/src/app-opentui/adapters/init.d.ts +0 -2
  16. package/dist/src/app-opentui/adapters/init.js +85 -47
  17. package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
  18. package/dist/src/app-opentui/adapters/inspect.js +1024 -0
  19. package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
  20. package/dist/src/app-opentui/adapters/pi-attach.js +442 -125
  21. package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
  22. package/dist/src/app-opentui/adapters/pi.js +363 -0
  23. package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
  24. package/dist/src/app-opentui/adapters/plugin.js +544 -0
  25. package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
  26. package/dist/src/app-opentui/adapters/repo.js +186 -0
  27. package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
  28. package/dist/src/app-opentui/adapters/run-detail.js +180 -63
  29. package/dist/src/app-opentui/adapters/server.d.ts +10 -2
  30. package/dist/src/app-opentui/adapters/server.js +191 -45
  31. package/dist/src/app-opentui/adapters/tasks.d.ts +11 -2
  32. package/dist/src/app-opentui/adapters/tasks.js +1123 -143
  33. package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
  34. package/dist/src/app-opentui/adapters/workspace.js +333 -0
  35. package/dist/src/app-opentui/autocomplete.d.ts +20 -0
  36. package/dist/src/app-opentui/autocomplete.js +576 -0
  37. package/dist/src/app-opentui/bootstrap.d.ts +1 -6
  38. package/dist/src/app-opentui/bootstrap.js +25252 -16474
  39. package/dist/src/app-opentui/command-palette.d.ts +3 -0
  40. package/dist/src/app-opentui/command-palette.js +1010 -0
  41. package/dist/src/app-opentui/command-pty-host.d.ts +62 -0
  42. package/dist/src/app-opentui/command-pty-host.js +248 -0
  43. package/dist/src/app-opentui/drone.js +8 -6
  44. package/dist/src/app-opentui/events.js +1 -1
  45. package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
  46. package/dist/src/app-opentui/fleet-stats.js +114 -0
  47. package/dist/src/app-opentui/focus-manager.d.ts +14 -0
  48. package/dist/src/app-opentui/focus-manager.js +24 -0
  49. package/dist/src/app-opentui/index.js +5431 -2797
  50. package/dist/src/app-opentui/intent.js +179 -50
  51. package/dist/src/app-opentui/keymap.d.ts +21 -0
  52. package/dist/src/app-opentui/keymap.js +1748 -0
  53. package/dist/src/app-opentui/launch-routing.d.ts +16 -0
  54. package/dist/src/app-opentui/launch-routing.js +55 -0
  55. package/dist/src/app-opentui/layout.d.ts +7 -0
  56. package/dist/src/app-opentui/layout.js +13 -6
  57. package/dist/src/app-opentui/list-search.d.ts +24 -0
  58. package/dist/src/app-opentui/list-search.js +88 -1
  59. package/dist/src/app-opentui/pi-host-child.js +99 -17
  60. package/dist/src/app-opentui/pi-pty-host.d.ts +14 -0
  61. package/dist/src/app-opentui/pi-pty-host.js +30 -14
  62. package/dist/src/app-opentui/react/App.d.ts +9 -0
  63. package/dist/src/app-opentui/react/App.js +5144 -0
  64. package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
  65. package/dist/src/app-opentui/react/Backdrop.js +1834 -0
  66. package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
  67. package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
  68. package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
  69. package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
  70. package/dist/src/app-opentui/react/context.d.ts +17 -0
  71. package/dist/src/app-opentui/react/context.js +37 -0
  72. package/dist/src/app-opentui/react/launch.d.ts +2 -0
  73. package/dist/src/app-opentui/react/launch.js +5743 -0
  74. package/dist/src/app-opentui/react/nav.d.ts +18 -0
  75. package/dist/src/app-opentui/react/nav.js +54 -0
  76. package/dist/src/app-opentui/react/scroll.d.ts +12 -0
  77. package/dist/src/app-opentui/react/scroll.js +21 -0
  78. package/dist/src/app-opentui/react/syntax.d.ts +2 -0
  79. package/dist/src/app-opentui/react/syntax.js +64 -0
  80. package/dist/src/app-opentui/registry.js +20428 -4828
  81. package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
  82. package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
  83. package/dist/src/app-opentui/render/constants.d.ts +31 -0
  84. package/dist/src/app-opentui/render/constants.js +66 -0
  85. package/dist/src/app-opentui/render/graphics.d.ts +2 -1
  86. package/dist/src/app-opentui/render/graphics.js +228 -46
  87. package/dist/src/app-opentui/render/image-visual-layer-worker.js +469 -930
  88. package/dist/src/app-opentui/render/image-visual-layer.d.ts +25 -10
  89. package/dist/src/app-opentui/render/image-visual-layer.js +448 -329
  90. package/dist/src/app-opentui/render/native-host.d.ts +37 -0
  91. package/dist/src/app-opentui/render/native-host.js +179 -0
  92. package/dist/src/app-opentui/render/panel-layout.d.ts +38 -0
  93. package/dist/src/app-opentui/render/panel-layout.js +48 -0
  94. package/dist/src/app-opentui/render/panels.d.ts +2 -0
  95. package/dist/src/app-opentui/render/panels.js +78 -38
  96. package/dist/src/app-opentui/render/preloader.d.ts +10 -0
  97. package/dist/src/app-opentui/render/preloader.js +165 -0
  98. package/dist/src/app-opentui/render/scene.d.ts +53 -1
  99. package/dist/src/app-opentui/render/scene.js +195 -6
  100. package/dist/src/app-opentui/render/text.d.ts +7 -1
  101. package/dist/src/app-opentui/render/text.js +15 -8
  102. package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
  103. package/dist/src/app-opentui/render/type-bar.js +113 -39
  104. package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
  105. package/dist/src/app-opentui/runtime-resources.js +62 -0
  106. package/dist/src/app-opentui/runtime.d.ts +44 -1
  107. package/dist/src/app-opentui/runtime.js +5415 -2738
  108. package/dist/src/app-opentui/scenes/command.d.ts +3 -0
  109. package/dist/src/app-opentui/scenes/command.js +117 -0
  110. package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
  111. package/dist/src/app-opentui/scenes/doctor.js +221 -17
  112. package/dist/src/app-opentui/scenes/error.js +60 -20
  113. package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
  114. package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
  115. package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
  116. package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
  117. package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
  118. package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
  119. package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
  120. package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
  121. package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
  122. package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
  123. package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
  124. package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
  125. package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
  126. package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
  127. package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
  128. package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
  129. package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
  130. package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
  131. package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
  132. package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
  133. package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
  134. package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
  135. package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
  136. package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
  137. package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
  138. package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
  139. package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
  140. package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
  141. package/dist/src/app-opentui/scenes/family.d.ts +3 -0
  142. package/dist/src/app-opentui/scenes/family.js +2144 -0
  143. package/dist/src/app-opentui/scenes/fleet.js +552 -43
  144. package/dist/src/app-opentui/scenes/handoff.js +342 -35
  145. package/dist/src/app-opentui/scenes/help.js +640 -56
  146. package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
  147. package/dist/src/app-opentui/scenes/inbox.js +329 -21
  148. package/dist/src/app-opentui/scenes/init.d.ts +2 -1
  149. package/dist/src/app-opentui/scenes/init.js +120 -34
  150. package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
  151. package/dist/src/app-opentui/scenes/inspect.js +793 -0
  152. package/dist/src/app-opentui/scenes/main.d.ts +2 -1
  153. package/dist/src/app-opentui/scenes/main.js +264 -29
  154. package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
  155. package/dist/src/app-opentui/scenes/pi.js +508 -0
  156. package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
  157. package/dist/src/app-opentui/scenes/plugin.js +486 -0
  158. package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
  159. package/dist/src/app-opentui/scenes/repo.js +424 -0
  160. package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
  161. package/dist/src/app-opentui/scenes/run-detail.js +362 -35
  162. package/dist/src/app-opentui/scenes/server.d.ts +2 -1
  163. package/dist/src/app-opentui/scenes/server.js +243 -26
  164. package/dist/src/app-opentui/scenes/tasks.js +518 -41
  165. package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
  166. package/dist/src/app-opentui/scenes/workspace.js +426 -0
  167. package/dist/src/app-opentui/selectable.d.ts +19 -0
  168. package/dist/src/app-opentui/selectable.js +79 -0
  169. package/dist/src/app-opentui/state.js +129 -36
  170. package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
  171. package/dist/src/app-opentui/surface-catalog.js +540 -0
  172. package/dist/src/app-opentui/terminal-capabilities.d.ts +7 -0
  173. package/dist/src/app-opentui/terminal-capabilities.js +15 -0
  174. package/dist/src/app-opentui/theme.d.ts +28 -6
  175. package/dist/src/app-opentui/theme.js +61 -8
  176. package/dist/src/app-opentui/types.d.ts +130 -5
  177. package/dist/src/commands/_authority-runs.d.ts +1 -1
  178. package/dist/src/commands/_authority-runs.js +2 -12
  179. package/dist/src/commands/_doctor-checks.js +62 -13
  180. package/dist/src/commands/_help-catalog.js +95 -15
  181. package/dist/src/commands/_operator-view.js +97 -15
  182. package/dist/src/commands/_pi-frontend.d.ts +2 -0
  183. package/dist/src/commands/_pi-frontend.js +97 -13
  184. package/dist/src/commands/_preflight.js +64 -14
  185. package/dist/src/commands/_server-client.js +82 -18
  186. package/dist/src/commands/_server-events.d.ts +26 -0
  187. package/dist/src/commands/_server-events.js +310 -0
  188. package/dist/src/commands/_snapshot-upload.js +62 -13
  189. package/dist/src/commands/agent.js +2 -12
  190. package/dist/src/commands/connect.js +7 -1
  191. package/dist/src/commands/doctor.js +62 -13
  192. package/dist/src/commands/github.js +144 -23
  193. package/dist/src/commands/inbox.js +62 -13
  194. package/dist/src/commands/init.js +82 -18
  195. package/dist/src/commands/inspect.js +62 -13
  196. package/dist/src/commands/run.js +100 -15
  197. package/dist/src/commands/server.js +71 -26
  198. package/dist/src/commands/setup.js +62 -13
  199. package/dist/src/commands/stats.js +157 -28
  200. package/dist/src/commands/task-run-driver.js +64 -25
  201. package/dist/src/commands/task.js +196 -43
  202. package/dist/src/commands.js +419 -123
  203. package/dist/src/index.js +426 -130
  204. package/package.json +11 -10
  205. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
  206. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1484
@@ -1,14 +1,23 @@
1
1
  // @bun
2
2
  // packages/cli/src/app-opentui/intent.ts
3
3
  var NAV_SCENES = new Map([
4
- ["", "fleet"],
5
- ["main", "fleet"],
6
- ["home", "fleet"],
4
+ ["", "main"],
5
+ ["main", "main"],
6
+ ["home", "main"],
7
7
  ["fleet", "fleet"],
8
8
  ["runs", "fleet"],
9
9
  ["run", "fleet"],
10
10
  ["tasks", "tasks"],
11
11
  ["task", "tasks"],
12
+ ["inbox", "inbox"],
13
+ ["server", "server"],
14
+ ["init", "init"],
15
+ ["doctor", "doctor"],
16
+ ["pi", "pi"],
17
+ ["plugin", "plugin"],
18
+ ["repo", "repo"],
19
+ ["workspace", "workspace"],
20
+ ["inspect", "inspect"],
12
21
  ["help", "help"]
13
22
  ]);
14
23
  var TASK_VIEW_COMMANDS = new Set([
@@ -30,8 +39,29 @@ var TASK_VIEW_COMMANDS = new Set([
30
39
  "search",
31
40
  "q"
32
41
  ]);
42
+ var HOLLOW_FAMILIES = new Set([
43
+ "browser",
44
+ "stats",
45
+ "dist",
46
+ "agent",
47
+ "queue",
48
+ "remote",
49
+ "harness",
50
+ "git",
51
+ "setup",
52
+ "profile",
53
+ "review",
54
+ "inspector",
55
+ "test"
56
+ ]);
57
+ function familyIntent(family, argv, raw) {
58
+ return intent("family", argv, "refresh", { family }, `Opening ${family}`, raw);
59
+ }
60
+ function isHelpCommand(command) {
61
+ return command === "help" || command === "--help" || command === "-h";
62
+ }
33
63
  function isTaskViewCommand(command) {
34
- return !command || TASK_VIEW_COMMANDS.has(command) || command.startsWith("-");
64
+ return !command || TASK_VIEW_COMMANDS.has(command) || command.startsWith("-") && !isHelpCommand(command);
35
65
  }
36
66
  function intent(scene, argv, kind, payload, label, raw) {
37
67
  return {
@@ -45,9 +75,9 @@ function intent(scene, argv, kind, payload, label, raw) {
45
75
  }
46
76
  };
47
77
  }
48
- function unsupportedPlainCliIntent(argv, raw) {
49
- const command = argv.join(" ").trim() || "command";
50
- return intent("help", argv, "none", { unsupported: command }, `${command} is on the plain CLI path; exit Rig shell or rerun with RIG_PLAIN=1`, raw);
78
+ function commandRunIntent(argv, raw, reason) {
79
+ const command = argv.join(" ").trim();
80
+ return intent("command", argv, "command-run", { argv: [...argv], ...reason ? { reason } : {} }, command ? `Running rig ${command}` : "Running rig", raw);
51
81
  }
52
82
  function firstValueAfter(args, option) {
53
83
  const index = args.indexOf(option);
@@ -56,11 +86,54 @@ function firstValueAfter(args, option) {
56
86
  function firstNonOption(args) {
57
87
  return args.find((part) => part.trim() && !part.startsWith("-"));
58
88
  }
59
- function explicitTaskIdArg(args) {
60
- const taskValue = firstValueAfter(args, "--task");
61
- if (taskValue && !taskValue.startsWith("-"))
62
- return taskValue;
63
- return args.find((part) => part.trim() && part !== "next" && part !== "--next" && part !== "--task" && !part.startsWith("-"));
89
+ function inboxActionIntent(argv, command, rest, raw) {
90
+ const requestId = firstNonOption(rest);
91
+ if (command === "approve" || command === "approvals") {
92
+ return requestId ? intent("inbox", argv, "inbox-approve", { requestId }, `Approving ${requestId}`, raw) : intent("inbox", argv, "refresh", undefined, "Loading approvals", raw);
93
+ }
94
+ if (command === "reject") {
95
+ return requestId ? intent("inbox", argv, "inbox-reject", { requestId }, `Rejecting ${requestId}`, raw) : intent("inbox", argv, "refresh", undefined, "Loading approvals", raw);
96
+ }
97
+ if (command === "answer" || command === "inputs" || command === "respond") {
98
+ const answer = rest.slice(requestId ? 1 : 0).join(" ").trim();
99
+ return requestId && answer ? intent("inbox", argv, "inbox-answer", { requestId, answer }, `Answering ${requestId}`, raw) : intent("inbox", argv, "refresh", undefined, "Loading inbox", raw);
100
+ }
101
+ return intent("inbox", argv, "refresh", undefined, "Loading inbox", raw);
102
+ }
103
+ function parseSimpleTaskRunArgs(args) {
104
+ let next = false;
105
+ let task;
106
+ let detach = false;
107
+ for (let index = 0;index < args.length; index += 1) {
108
+ const arg = args[index];
109
+ if (arg === "next" || arg === "--next") {
110
+ next = true;
111
+ continue;
112
+ }
113
+ if (arg === "--detach") {
114
+ detach = true;
115
+ continue;
116
+ }
117
+ if (arg === "--task") {
118
+ const value = args[index + 1];
119
+ if (!value || value.startsWith("-"))
120
+ return { ok: false, reason: "task run --task needs an id" };
121
+ if (task)
122
+ return { ok: false, reason: "task run received more than one task id" };
123
+ task = value;
124
+ index += 1;
125
+ continue;
126
+ }
127
+ if (arg.startsWith("-")) {
128
+ return { ok: false, reason: `task run option ${arg} uses the command workspace` };
129
+ }
130
+ if (task)
131
+ return { ok: false, reason: "task run received more than one task id" };
132
+ task = arg;
133
+ }
134
+ if (next && task)
135
+ return { ok: false, reason: "task run cannot combine next with a task id" };
136
+ return { ok: true, next, ...task ? { task } : {}, detach };
64
137
  }
65
138
  function taskViewPayload(command, rest) {
66
139
  const normalized = command.toLowerCase();
@@ -114,85 +187,141 @@ function taskViewIntent(argv, command = "", rest = [], raw) {
114
187
  const { payload, label } = taskViewPayload(command, rest);
115
188
  return intent("tasks", argv, "refresh", payload, label, raw);
116
189
  }
190
+ function routeServer(argv, command, raw, checkingLabel) {
191
+ if (!command || command === "status") {
192
+ return intent("server", argv, "refresh", undefined, command ? checkingLabel : "Loading server", raw);
193
+ }
194
+ return commandRunIntent(argv, raw);
195
+ }
196
+ function routeGithub(argv, command, rest, raw) {
197
+ if (command === "auth" && (rest[0]?.toLowerCase() ?? "status") === "status" && rest.length <= 1) {
198
+ return intent("server", argv, "refresh", undefined, "Checking GitHub auth", raw);
199
+ }
200
+ return commandRunIntent(argv, raw);
201
+ }
202
+ function routeDoctor(argv, command, raw) {
203
+ return command ? commandRunIntent(argv, raw) : intent("doctor", argv, "doctor-run", undefined, "Running doctor", raw);
204
+ }
205
+ function routeInbox(argv, command, rest, raw) {
206
+ if (command === "watch")
207
+ return commandRunIntent(argv, raw);
208
+ if ((command === "approvals" || command === "inputs") && rest.length > 0)
209
+ return commandRunIntent(argv, raw);
210
+ return command && command !== "approvals" && command !== "inputs" ? commandRunIntent(argv, raw) : inboxActionIntent(argv, command, rest, raw);
211
+ }
117
212
  function intentFromArgv(argv) {
118
213
  const [group = "", command = "", ...rest] = argv;
119
214
  const normalizedGroup = group.toLowerCase();
120
215
  const normalizedCommand = command.toLowerCase();
121
216
  if (!normalizedGroup)
122
- return intent("fleet", argv, "refresh", undefined, "Opening runs");
217
+ return intent("main", argv, "none", undefined, "Project menu");
123
218
  if (normalizedGroup === "--help" || normalizedGroup === "-h" || normalizedGroup === "help") {
124
- return argv.length === 1 ? intent("help", argv, "none", undefined, "Help") : unsupportedPlainCliIntent(argv);
219
+ return argv.length === 1 ? intent("help", argv, "none", undefined, "Help") : commandRunIntent(argv);
125
220
  }
126
221
  if (normalizedGroup === "task") {
127
- if (normalizedCommand === "run") {
128
- if (rest.includes("--next") || rest.includes("next")) {
129
- return intent("tasks", argv, "task-run-next", undefined, "Dispatching next task");
130
- }
131
- const task = explicitTaskIdArg(rest);
132
- if (task)
133
- return intent("tasks", argv, "task-run-id", { task }, `Dispatching ${task}`);
134
- return intent("tasks", argv, "refresh", undefined, "Select a task, then press Enter; or use run next");
135
- }
222
+ if (normalizedCommand === "run" || normalizedCommand === "ready" || normalizedCommand === "status")
223
+ return commandRunIntent(argv);
136
224
  if (!isTaskViewCommand(normalizedCommand))
137
- return unsupportedPlainCliIntent(argv);
225
+ return commandRunIntent(argv);
138
226
  return taskViewIntent(argv, normalizedCommand, rest);
139
227
  }
140
228
  if (normalizedGroup === "tasks") {
141
229
  if (!isTaskViewCommand(normalizedCommand))
142
- return unsupportedPlainCliIntent(argv);
230
+ return commandRunIntent(argv);
143
231
  return taskViewIntent(argv, normalizedCommand, rest);
144
232
  }
145
233
  if (normalizedGroup === "run") {
146
234
  if (normalizedCommand === "attach") {
147
235
  const runId = firstNonOption(rest);
148
- return intent("handoff", argv, "run-attach", { runId }, runId ? `Attaching ${runId}` : "Attaching run");
236
+ const nativeOnly = Boolean(runId) && rest.filter((part) => part.trim()).length === 1;
237
+ return nativeOnly ? intent("handoff", argv, "run-attach", { runId }, `Attaching ${runId}`) : commandRunIntent(argv);
149
238
  }
150
- if (!normalizedCommand)
239
+ if (!normalizedCommand || normalizedCommand === "list" || normalizedCommand === "status")
151
240
  return intent("fleet", argv, "refresh", undefined, "Loading fleet");
152
- return unsupportedPlainCliIntent(argv);
241
+ if (normalizedCommand === "stop") {
242
+ const runId = firstNonOption(rest);
243
+ return runId && rest.filter((part) => part.trim()).length === 1 ? intent("fleet", argv, "run-stop", { runId }, "Stopping run") : commandRunIntent(argv);
244
+ }
245
+ return commandRunIntent(argv);
153
246
  }
247
+ if (normalizedGroup === "server")
248
+ return routeServer(argv, normalizedCommand, undefined, "Checking server");
249
+ if (normalizedGroup === "github")
250
+ return routeGithub(argv, normalizedCommand, rest);
251
+ if (normalizedGroup === "init")
252
+ return commandRunIntent(argv);
253
+ if (normalizedGroup === "doctor")
254
+ return routeDoctor(argv, normalizedCommand);
255
+ if (normalizedGroup === "inbox")
256
+ return routeInbox(argv, normalizedCommand, rest);
154
257
  if (normalizedGroup === "attach") {
155
- const runId = firstNonOption([command, ...rest]);
156
- return intent("handoff", argv, "run-attach", { runId }, runId ? `Attaching ${runId}` : "Attaching run");
258
+ const attachArgs = [command, ...rest].filter((part) => part.trim());
259
+ const runId = firstNonOption(attachArgs);
260
+ return runId && attachArgs.length === 1 ? intent("handoff", argv, "run-attach", { runId }, `Attaching ${runId}`) : commandRunIntent(argv);
261
+ }
262
+ if (HOLLOW_FAMILIES.has(normalizedGroup)) {
263
+ if (!normalizedCommand || isHelpCommand(normalizedCommand))
264
+ return familyIntent(normalizedGroup, argv);
265
+ return commandRunIntent(argv);
157
266
  }
158
267
  const nav = NAV_SCENES.get(normalizedGroup);
159
- if (nav)
268
+ if (nav && argv.length === 1)
160
269
  return intent(nav, argv, "navigate", undefined, `Opening ${nav}`);
161
- return unsupportedPlainCliIntent(argv);
270
+ return commandRunIntent(argv);
162
271
  }
163
272
  function intentFromTypeBar(value) {
164
273
  const raw = value.trim();
165
274
  if (!raw)
166
- return intent("fleet", [], "refresh", undefined, "Opening runs", value);
275
+ return intent("main", [], "none", undefined, "Project menu", value);
167
276
  const parts = raw.split(/\s+/).filter(Boolean);
168
277
  const [first = "", second = "", ...rest] = parts;
169
278
  const firstScene = NAV_SCENES.get(first.toLowerCase());
170
279
  if (first === "tasks" || first === "task") {
171
- if (second === "run") {
172
- const task = explicitTaskIdArg(rest);
173
- if (rest.includes("--next") || task === "next")
174
- return intent("tasks", parts, "task-run-next", undefined, "Dispatching next task", value);
175
- if (task)
176
- return intent("tasks", parts, "task-run-id", { task }, `Dispatching ${task}`, value);
177
- return intent("tasks", parts, "refresh", undefined, "Select a task, then press Enter; or use run next", value);
178
- }
280
+ if (second === "run" || first === "task" && (second === "ready" || second === "status"))
281
+ return commandRunIntent(parts, value);
179
282
  if (!isTaskViewCommand(second.toLowerCase()))
180
- return unsupportedPlainCliIntent(parts, value);
283
+ return commandRunIntent(parts, value);
181
284
  return taskViewIntent(parts, second, rest, value);
182
285
  }
183
286
  if (first === "run") {
184
- if (second === "next" || second === "--next")
185
- return intent("tasks", parts, "task-run-next", undefined, "Dispatching next task", value);
186
- if (second === "--task") {
187
- const task = explicitTaskIdArg([second, ...rest]);
188
- if (task)
189
- return intent("tasks", parts, "task-run-id", { task }, `Dispatching ${task}`, value);
287
+ if (second === "attach") {
288
+ const runId = firstNonOption(rest);
289
+ return runId && rest.filter((part) => part.trim()).length === 1 ? intent("handoff", parts, "run-attach", { runId }, "Attaching run", value) : commandRunIntent(parts, value);
290
+ }
291
+ if (second === "stop") {
292
+ const runId = firstNonOption(rest);
293
+ return runId && rest.filter((part) => part.trim()).length === 1 ? intent("fleet", parts, "run-stop", { runId }, "Stopping run", value) : commandRunIntent(parts, value);
294
+ }
295
+ if (second === "next" || second === "--next" || second === "--task") {
296
+ const parsed = parseSimpleTaskRunArgs([second, ...rest]);
297
+ if (!parsed.ok)
298
+ return commandRunIntent(parts, value, parsed.reason);
299
+ const payload = parsed.detach ? { detach: true } : undefined;
300
+ if (parsed.next)
301
+ return intent("tasks", parts, "task-run-next", payload, parsed.detach ? "Dispatching next task detached" : "Dispatching next task", value);
302
+ if (parsed.task)
303
+ return intent("tasks", parts, "task-run-id", { ...payload ?? {}, task: parsed.task }, parsed.detach ? `Dispatching ${parsed.task} detached` : `Dispatching ${parsed.task}`, value);
190
304
  return intent("tasks", parts, "refresh", undefined, "Select a task, then press Enter; or use run next", value);
191
305
  }
192
- if (second && !second.startsWith("-"))
306
+ if (second && !second.startsWith("-")) {
307
+ if (rest.length > 0)
308
+ return commandRunIntent(parts, value);
193
309
  return intent("tasks", parts, "task-run-id", { task: second }, `Dispatching ${second}`, value);
310
+ }
311
+ if (second?.startsWith("-"))
312
+ return commandRunIntent(parts, value);
194
313
  return intent("tasks", parts, "refresh", undefined, "Select a task, then press Enter; or use run next", value);
195
314
  }
315
+ if (first === "init")
316
+ return commandRunIntent(parts, value);
317
+ if (first === "doctor")
318
+ return routeDoctor(parts, second, value);
319
+ if (first === "server")
320
+ return routeServer(parts, second, value, "Loading server");
321
+ if (first === "github")
322
+ return routeGithub(parts, second, rest, value);
323
+ if (first === "inbox")
324
+ return routeInbox(parts, second, rest, value);
196
325
  if (firstScene && parts.length === 1) {
197
326
  return intent(firstScene, parts, "navigate", undefined, `Opening ${firstScene}`, value);
198
327
  }
@@ -201,7 +330,7 @@ function intentFromTypeBar(value) {
201
330
  if (first === "attach") {
202
331
  if (!second)
203
332
  return intent("handoff", parts, "navigate", undefined, "Select a run to attach", value);
204
- return intent("handoff", parts, "run-attach", { runId: second }, `Attaching ${second}`, value);
333
+ return parts.length === 2 ? intent("handoff", parts, "run-attach", { runId: second }, `Attaching ${second}`, value) : commandRunIntent(parts, value);
205
334
  }
206
335
  return intentFromArgv(parts);
207
336
  }
@@ -0,0 +1,21 @@
1
+ import type { CliRenderer, KeyEvent } from "@opentui/core";
2
+ import type { TypeBarRenderables } from "./render/type-bar";
3
+ import type { AppIntent, AppRuntime, AppSceneId, AppSelectableItem, AppState, AppTypeBarState } from "./types";
4
+ export type AppKeymapContext = {
5
+ readonly renderer: () => CliRenderer | null;
6
+ readonly runtime: AppRuntime;
7
+ readonly getState: () => AppState;
8
+ readonly getTypeBar: () => TypeBarRenderables | null;
9
+ readonly getRenderedSelectableItems: () => readonly AppSelectableItem[];
10
+ readonly emitTypeBarPatch: (patch: Partial<AppTypeBarState>) => void;
11
+ readonly runAppAction: (label: string, action: () => Promise<unknown>) => void;
12
+ readonly primaryNavIntent: (scene: AppSceneId) => AppIntent;
13
+ readonly nextPrimaryScene: (scene: AppSceneId, delta: number) => AppSceneId;
14
+ readonly moveSelection: (delta: number, renderedItems?: readonly AppSelectableItem[]) => boolean;
15
+ readonly activateSelection: (renderedItems?: readonly AppSelectableItem[]) => Promise<boolean>;
16
+ /** Scroll the active content body (the visible scroll panel AND the native
17
+ * code/diff/table overlay) by `delta` rows — keyboard scroll for long content
18
+ * (PageUp/Down/Home/End/Ctrl-D/U) that selection nav can't reach. */
19
+ readonly scrollActiveBody: (delta: number) => void;
20
+ };
21
+ export declare function handleAppKeyPress(context: AppKeymapContext, key: KeyEvent): void;