u-foo 1.0.6 → 1.1.9

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 (149) hide show
  1. package/README.md +44 -4
  2. package/SKILLS/ufoo/SKILL.md +17 -2
  3. package/SKILLS/uinit/SKILL.md +8 -3
  4. package/bin/ucode-core.js +15 -0
  5. package/bin/ucode.js +125 -0
  6. package/bin/ufoo-assistant-agent.js +5 -0
  7. package/bin/ufoo-engine.js +25 -0
  8. package/bin/ufoo.js +4 -0
  9. package/modules/AGENTS.template.md +14 -4
  10. package/modules/bus/README.md +8 -5
  11. package/modules/bus/SKILLS/ubus/SKILL.md +5 -4
  12. package/modules/context/SKILLS/uctx/SKILL.md +3 -1
  13. package/modules/online/SKILLS/ufoo-online/SKILL.md +144 -0
  14. package/package.json +12 -3
  15. package/scripts/import-pi-mono.js +124 -0
  16. package/scripts/postinstall.js +20 -49
  17. package/scripts/sync-claude-skills.sh +21 -0
  18. package/src/agent/cliRunner.js +524 -31
  19. package/src/agent/internalRunner.js +76 -9
  20. package/src/agent/launcher.js +97 -45
  21. package/src/agent/normalizeOutput.js +1 -1
  22. package/src/agent/notifier.js +144 -4
  23. package/src/agent/ptyRunner.js +480 -10
  24. package/src/agent/ptyWrapper.js +28 -3
  25. package/src/agent/readyDetector.js +16 -0
  26. package/src/agent/ucode.js +443 -0
  27. package/src/agent/ucodeBootstrap.js +113 -0
  28. package/src/agent/ucodeBuild.js +67 -0
  29. package/src/agent/ucodeDoctor.js +184 -0
  30. package/src/agent/ucodeRuntimeConfig.js +129 -0
  31. package/src/agent/ufooAgent.js +11 -2
  32. package/src/assistant/agent.js +260 -0
  33. package/src/assistant/bridge.js +172 -0
  34. package/src/assistant/engine.js +252 -0
  35. package/src/assistant/stdio.js +58 -0
  36. package/src/assistant/ufooEngineCli.js +306 -0
  37. package/src/bus/activate.js +27 -11
  38. package/src/bus/daemon.js +133 -5
  39. package/src/bus/index.js +137 -80
  40. package/src/bus/inject.js +47 -17
  41. package/src/bus/message.js +145 -17
  42. package/src/bus/nickname.js +3 -1
  43. package/src/bus/queue.js +6 -1
  44. package/src/bus/store.js +189 -0
  45. package/src/bus/subscriber.js +20 -4
  46. package/src/bus/utils.js +9 -3
  47. package/src/chat/agentBar.js +117 -0
  48. package/src/chat/agentDirectory.js +88 -0
  49. package/src/chat/agentSockets.js +225 -0
  50. package/src/chat/agentViewController.js +298 -0
  51. package/src/chat/chatLogController.js +115 -0
  52. package/src/chat/commandExecutor.js +700 -0
  53. package/src/chat/commands.js +132 -0
  54. package/src/chat/completionController.js +414 -0
  55. package/src/chat/cronScheduler.js +160 -0
  56. package/src/chat/daemonConnection.js +166 -0
  57. package/src/chat/daemonCoordinator.js +64 -0
  58. package/src/chat/daemonMessageRouter.js +257 -0
  59. package/src/chat/daemonReconnect.js +41 -0
  60. package/src/chat/daemonTransport.js +36 -0
  61. package/src/chat/daemonTransportDefaults.js +10 -0
  62. package/src/chat/dashboardKeyController.js +480 -0
  63. package/src/chat/dashboardView.js +154 -0
  64. package/src/chat/index.js +935 -2909
  65. package/src/chat/inputHistoryController.js +105 -0
  66. package/src/chat/inputListenerController.js +304 -0
  67. package/src/chat/inputMath.js +104 -0
  68. package/src/chat/inputSubmitHandler.js +171 -0
  69. package/src/chat/layout.js +165 -0
  70. package/src/chat/pasteController.js +81 -0
  71. package/src/chat/rawKeyMap.js +42 -0
  72. package/src/chat/settingsController.js +132 -0
  73. package/src/chat/statusLineController.js +177 -0
  74. package/src/chat/streamTracker.js +138 -0
  75. package/src/chat/text.js +70 -0
  76. package/src/chat/transport.js +61 -0
  77. package/src/cli/busCoreCommands.js +59 -0
  78. package/src/cli/ctxCoreCommands.js +199 -0
  79. package/src/cli/onlineCoreCommands.js +379 -0
  80. package/src/cli.js +741 -238
  81. package/src/code/README.md +29 -0
  82. package/src/code/UCODE_PROMPT.md +32 -0
  83. package/src/code/agent.js +1651 -0
  84. package/src/code/cli.js +158 -0
  85. package/src/code/config +0 -0
  86. package/src/code/dispatch.js +42 -0
  87. package/src/code/index.js +70 -0
  88. package/src/code/nativeRunner.js +1213 -0
  89. package/src/code/runtime.js +154 -0
  90. package/src/code/sessionStore.js +162 -0
  91. package/src/code/taskDecomposer.js +269 -0
  92. package/src/code/tools/bash.js +53 -0
  93. package/src/code/tools/common.js +42 -0
  94. package/src/code/tools/edit.js +70 -0
  95. package/src/code/tools/read.js +44 -0
  96. package/src/code/tools/write.js +35 -0
  97. package/src/code/tui.js +1580 -0
  98. package/src/config.js +47 -1
  99. package/src/context/decisions.js +12 -2
  100. package/src/context/index.js +18 -1
  101. package/src/context/sync.js +127 -0
  102. package/src/daemon/agentProcessManager.js +74 -0
  103. package/src/daemon/cronOps.js +241 -0
  104. package/src/daemon/index.js +661 -488
  105. package/src/daemon/ipcServer.js +99 -0
  106. package/src/daemon/ops.js +417 -179
  107. package/src/daemon/promptLoop.js +319 -0
  108. package/src/daemon/promptRequest.js +101 -0
  109. package/src/daemon/providerSessions.js +32 -17
  110. package/src/daemon/reporting.js +90 -0
  111. package/src/daemon/run.js +2 -5
  112. package/src/daemon/status.js +24 -1
  113. package/src/init/index.js +68 -14
  114. package/src/online/bridge.js +663 -0
  115. package/src/online/client.js +245 -0
  116. package/src/online/runner.js +253 -0
  117. package/src/online/server.js +992 -0
  118. package/src/online/tokens.js +103 -0
  119. package/src/report/store.js +331 -0
  120. package/src/shared/eventContract.js +35 -0
  121. package/src/shared/ptySocketContract.js +21 -0
  122. package/src/status/index.js +50 -17
  123. package/src/terminal/adapterContract.js +87 -0
  124. package/src/terminal/adapterRouter.js +84 -0
  125. package/src/terminal/adapters/externalAdapter.js +14 -0
  126. package/src/terminal/adapters/internalAdapter.js +13 -0
  127. package/src/terminal/adapters/internalPtyAdapter.js +42 -0
  128. package/src/terminal/adapters/internalQueueAdapter.js +37 -0
  129. package/src/terminal/adapters/terminalAdapter.js +31 -0
  130. package/src/terminal/adapters/tmuxAdapter.js +30 -0
  131. package/src/ufoo/agentsStore.js +69 -3
  132. package/src/utils/banner.js +5 -2
  133. package/scripts/.archived/bash-to-js-migration/README.md +0 -46
  134. package/scripts/.archived/bash-to-js-migration/banner.sh +0 -89
  135. package/scripts/.archived/bash-to-js-migration/bus-alert.sh +0 -6
  136. package/scripts/.archived/bash-to-js-migration/bus-autotrigger.sh +0 -6
  137. package/scripts/.archived/bash-to-js-migration/bus-daemon.sh +0 -231
  138. package/scripts/.archived/bash-to-js-migration/bus-inject.sh +0 -176
  139. package/scripts/.archived/bash-to-js-migration/bus-listen.sh +0 -6
  140. package/scripts/.archived/bash-to-js-migration/bus.sh +0 -986
  141. package/scripts/.archived/bash-to-js-migration/context-decisions.sh +0 -167
  142. package/scripts/.archived/bash-to-js-migration/context-doctor.sh +0 -72
  143. package/scripts/.archived/bash-to-js-migration/context-lint.sh +0 -110
  144. package/scripts/.archived/bash-to-js-migration/doctor.sh +0 -22
  145. package/scripts/.archived/bash-to-js-migration/init.sh +0 -247
  146. package/scripts/.archived/bash-to-js-migration/skills.sh +0 -113
  147. package/scripts/.archived/bash-to-js-migration/status.sh +0 -125
  148. package/scripts/banner.sh +0 -2
  149. package/src/bus/API_DESIGN.md +0 -204
@@ -0,0 +1,379 @@
1
+ "use strict";
2
+
3
+ function createUnknownOnlineError(subcmd) {
4
+ const err = new Error(`Unknown online subcommand: ${subcmd}`);
5
+ err.code = "UFOO_ONLINE_UNKNOWN";
6
+ return err;
7
+ }
8
+
9
+ function getFallbackOpt(argv, name) {
10
+ const idx = argv.indexOf(name);
11
+ if (idx === -1) return "";
12
+ return argv[idx + 1] || "";
13
+ }
14
+
15
+ function hasFallbackFlag(argv, name) {
16
+ return argv.includes(name);
17
+ }
18
+
19
+ function buildAuthHeaders(onlineAuthHeaders, opts) {
20
+ if (typeof onlineAuthHeaders === "function") {
21
+ return onlineAuthHeaders(opts);
22
+ }
23
+ return {};
24
+ }
25
+
26
+ async function runOnlineServer(opts = {}) {
27
+ const OnlineServer = require("../online/server");
28
+ const host = opts.host || "127.0.0.1";
29
+ const port = Number.isFinite(opts.port) ? opts.port : parseInt(opts.port || "8787", 10);
30
+ const idleTimeoutMs = Number.isFinite(opts.idleTimeoutMs)
31
+ ? opts.idleTimeoutMs
32
+ : parseInt(opts.idleTimeoutMs || opts.idleTimeout || "30000", 10);
33
+ const tokenFile = opts.tokenFile || undefined;
34
+ const insecure = !!opts.insecure;
35
+ const tlsCert = opts.tlsCert || null;
36
+ const tlsKey = opts.tlsKey || null;
37
+
38
+ const server = new OnlineServer({
39
+ host,
40
+ port,
41
+ tokenFile,
42
+ idleTimeoutMs,
43
+ insecure,
44
+ tlsCert,
45
+ tlsKey,
46
+ });
47
+
48
+ const isTls = !!(tlsCert && tlsKey);
49
+ const wsProto = isTls ? "wss" : "ws";
50
+ const httpProto = isTls ? "https" : "http";
51
+
52
+ await server.start();
53
+ console.log(`ufoo-online relay listening on ${host}:${server.port}`);
54
+ console.log(` WebSocket: ${wsProto}://${host}:${server.port}/ufoo/online`);
55
+ console.log(` HTTP API: ${httpProto}://${host}:${server.port}/ufoo/online/rooms`);
56
+ console.log(` ${httpProto}://${host}:${server.port}/ufoo/online/channels`);
57
+ if (server.insecure) console.log(" Auth: INSECURE mode (any token accepted)");
58
+ if (isTls) console.log(" TLS: enabled");
59
+ }
60
+
61
+ async function runOnlineToken(subscriber, opts = {}) {
62
+ if (!subscriber) {
63
+ throw new Error("online token requires <subscriber>");
64
+ }
65
+ const { generateToken, setToken, defaultTokensPath } = require("../online/tokens");
66
+ const filePath = opts.file || defaultTokensPath();
67
+ const token = generateToken();
68
+ const entry = setToken(filePath, subscriber, token, opts.server || "", {
69
+ nickname: opts.nickname || "",
70
+ });
71
+ console.log(JSON.stringify({
72
+ subscriber,
73
+ token,
74
+ token_hash: entry.token_hash,
75
+ server: entry.server,
76
+ nickname: entry.nickname,
77
+ file: filePath,
78
+ }, null, 2));
79
+ }
80
+
81
+ async function runOnlineRoom(action, opts = {}, onlineAuthHeaders) {
82
+ const base = opts.server || "http://127.0.0.1:8787";
83
+ const endpoint = `${base.replace(/\/$/, "")}/ufoo/online/rooms`;
84
+ const authHeaders = buildAuthHeaders(onlineAuthHeaders, {
85
+ authToken: opts.authToken,
86
+ tokenFile: opts.tokenFile,
87
+ subscriber: opts.subscriber,
88
+ nickname: opts.nickname,
89
+ });
90
+
91
+ if (action === "list") {
92
+ const res = await fetch(endpoint, { headers: { ...authHeaders } });
93
+ const data = await res.json();
94
+ console.log(JSON.stringify(data, null, 2));
95
+ return;
96
+ }
97
+ if (action === "create") {
98
+ const payload = {
99
+ name: opts.name,
100
+ type: opts.type,
101
+ password: opts.password,
102
+ };
103
+ if (!payload.type) {
104
+ throw new Error("online room create requires --type");
105
+ }
106
+ const res = await fetch(endpoint, {
107
+ method: "POST",
108
+ headers: { "Content-Type": "application/json", ...authHeaders },
109
+ body: JSON.stringify(payload),
110
+ });
111
+ const data = await res.json();
112
+ console.log(JSON.stringify(data, null, 2));
113
+ return;
114
+ }
115
+ throw new Error("online room requires action create|list");
116
+ }
117
+
118
+ async function runOnlineChannel(action, opts = {}, onlineAuthHeaders) {
119
+ const base = opts.server || "http://127.0.0.1:8787";
120
+ const endpoint = `${base.replace(/\/$/, "")}/ufoo/online/channels`;
121
+ const authHeaders = buildAuthHeaders(onlineAuthHeaders, {
122
+ authToken: opts.authToken,
123
+ tokenFile: opts.tokenFile,
124
+ subscriber: opts.subscriber,
125
+ nickname: opts.nickname,
126
+ });
127
+
128
+ if (action === "list") {
129
+ const res = await fetch(endpoint, { headers: { ...authHeaders } });
130
+ const data = await res.json();
131
+ console.log(JSON.stringify(data, null, 2));
132
+ return;
133
+ }
134
+ if (action === "create") {
135
+ const payload = {
136
+ name: opts.name,
137
+ type: opts.type,
138
+ };
139
+ if (!payload.name) {
140
+ throw new Error("online channel create requires --name");
141
+ }
142
+ const res = await fetch(endpoint, {
143
+ method: "POST",
144
+ headers: { "Content-Type": "application/json", ...authHeaders },
145
+ body: JSON.stringify(payload),
146
+ });
147
+ const data = await res.json();
148
+ console.log(JSON.stringify(data, null, 2));
149
+ return;
150
+ }
151
+ throw new Error("online channel requires action create|list");
152
+ }
153
+
154
+ async function runOnlineConnect(opts = {}) {
155
+ if (!opts.nickname) {
156
+ throw new Error("online connect requires --nickname");
157
+ }
158
+ const OnlineConnect = require("../online/bridge");
159
+ const conn = new OnlineConnect({
160
+ projectRoot: opts.projectRoot || process.cwd(),
161
+ nickname: opts.nickname,
162
+ subscriberId: opts.subscriber || "",
163
+ url: opts.url || "ws://127.0.0.1:8787/ufoo/online",
164
+ token: opts.token || "",
165
+ tokenHash: opts.tokenHash || "",
166
+ tokenFile: opts.tokenFile || "",
167
+ world: opts.world || "default",
168
+ pingMs: opts.pingMs ? parseInt(opts.pingMs, 10) : 0,
169
+ channel: opts.join || "",
170
+ room: opts.room || "",
171
+ roomPassword: opts.roomPassword || "",
172
+ pollIntervalMs: opts.interval ? parseInt(opts.interval, 10) : 1500,
173
+ allowInsecureWs: !!opts.allowInsecureWs,
174
+ trustRemote: !!opts.trustRemote,
175
+ allowFrom: opts.allowFrom || [],
176
+ });
177
+ await conn.start();
178
+ }
179
+
180
+ function runOnlineSend(opts = {}) {
181
+ const { send } = require("../online/runner");
182
+ if (!opts.nickname || !opts.text) {
183
+ throw new Error("online send requires --nickname and --text");
184
+ }
185
+ send(opts.nickname, {
186
+ text: opts.text,
187
+ channel: opts.channel || "",
188
+ room: opts.room || "",
189
+ });
190
+ }
191
+
192
+ function runOnlineInbox(nickname, opts = {}) {
193
+ const { checkInbox } = require("../online/runner");
194
+ if (!nickname || nickname.startsWith("--")) {
195
+ throw new Error("online inbox requires <nickname>");
196
+ }
197
+ checkInbox(nickname, {
198
+ clear: !!opts.clear,
199
+ unread: !!opts.unread,
200
+ });
201
+ }
202
+
203
+ async function runOnlineCommand(subcmd, payload = {}, options = {}) {
204
+ const mode = options.mode || "commander";
205
+ const onlineAuthHeaders = options.onlineAuthHeaders;
206
+
207
+ if (mode === "commander") {
208
+ const opts = payload.opts || {};
209
+ switch (subcmd) {
210
+ case "server":
211
+ return runOnlineServer({
212
+ host: opts.host,
213
+ port: parseInt(opts.port, 10),
214
+ tokenFile: opts.tokenFile || undefined,
215
+ idleTimeoutMs: parseInt(opts.idleTimeout, 10),
216
+ insecure: opts.insecure || false,
217
+ tlsCert: opts.tlsCert || null,
218
+ tlsKey: opts.tlsKey || null,
219
+ });
220
+ case "token":
221
+ return runOnlineToken(payload.subscriber, {
222
+ nickname: opts.nickname || "",
223
+ server: opts.server || "",
224
+ file: opts.file || "",
225
+ });
226
+ case "room":
227
+ return runOnlineRoom(payload.action, {
228
+ server: opts.server || "http://127.0.0.1:8787",
229
+ authToken: opts.authToken || "",
230
+ tokenFile: opts.tokenFile || "",
231
+ subscriber: opts.subscriber || "",
232
+ nickname: opts.nickname || "",
233
+ name: opts.name,
234
+ type: opts.type,
235
+ password: opts.password,
236
+ }, onlineAuthHeaders);
237
+ case "channel":
238
+ return runOnlineChannel(payload.action, {
239
+ server: opts.server || "http://127.0.0.1:8787",
240
+ authToken: opts.authToken || "",
241
+ tokenFile: opts.tokenFile || "",
242
+ subscriber: opts.subscriber || "",
243
+ nickname: opts.nickname || "",
244
+ name: opts.name,
245
+ type: opts.type,
246
+ }, onlineAuthHeaders);
247
+ case "connect":
248
+ return runOnlineConnect({
249
+ projectRoot: options.projectRoot || process.cwd(),
250
+ nickname: opts.nickname,
251
+ subscriber: opts.subscriber || "",
252
+ url: opts.url,
253
+ token: opts.token || "",
254
+ tokenHash: opts.tokenHash || "",
255
+ tokenFile: opts.tokenFile || "",
256
+ world: opts.world,
257
+ pingMs: opts.pingMs,
258
+ join: opts.join || "",
259
+ room: opts.room || "",
260
+ roomPassword: opts.roomPassword || "",
261
+ interval: opts.interval,
262
+ allowInsecureWs: opts.allowInsecureWs,
263
+ trustRemote: opts.trustRemote,
264
+ allowFrom: opts.allowFrom || [],
265
+ });
266
+ case "send":
267
+ return runOnlineSend({
268
+ nickname: opts.nickname,
269
+ text: opts.text,
270
+ channel: opts.channel || "",
271
+ room: opts.room || "",
272
+ });
273
+ case "inbox":
274
+ return runOnlineInbox(payload.nickname, {
275
+ clear: opts.clear,
276
+ unread: opts.unread,
277
+ });
278
+ default:
279
+ throw createUnknownOnlineError(subcmd);
280
+ }
281
+ }
282
+
283
+ const argv = payload.argv || [];
284
+ switch (subcmd) {
285
+ case "server": {
286
+ return runOnlineServer({
287
+ host: getFallbackOpt(argv, "--host") || "127.0.0.1",
288
+ port: parseInt(getFallbackOpt(argv, "--port") || "8787", 10),
289
+ tokenFile: getFallbackOpt(argv, "--token-file") || undefined,
290
+ idleTimeoutMs: parseInt(getFallbackOpt(argv, "--idle-timeout") || "30000", 10),
291
+ insecure: hasFallbackFlag(argv, "--insecure"),
292
+ tlsCert: getFallbackOpt(argv, "--tls-cert") || null,
293
+ tlsKey: getFallbackOpt(argv, "--tls-key") || null,
294
+ });
295
+ }
296
+ case "token": {
297
+ const subscriber = argv[1];
298
+ return runOnlineToken(subscriber, {
299
+ nickname: getFallbackOpt(argv, "--nickname"),
300
+ server: getFallbackOpt(argv, "--server"),
301
+ file: getFallbackOpt(argv, "--file"),
302
+ });
303
+ }
304
+ case "room": {
305
+ const action = argv[1] || "";
306
+ return runOnlineRoom(action, {
307
+ server: getFallbackOpt(argv, "--server") || "http://127.0.0.1:8787",
308
+ authToken: getFallbackOpt(argv, "--auth-token"),
309
+ tokenFile: getFallbackOpt(argv, "--token-file"),
310
+ subscriber: getFallbackOpt(argv, "--subscriber"),
311
+ nickname: getFallbackOpt(argv, "--nickname"),
312
+ name: getFallbackOpt(argv, "--name"),
313
+ type: getFallbackOpt(argv, "--type"),
314
+ password: getFallbackOpt(argv, "--password"),
315
+ }, onlineAuthHeaders);
316
+ }
317
+ case "channel": {
318
+ const action = argv[1] || "";
319
+ const defaultChannelType = options.defaultChannelType || "public";
320
+ return runOnlineChannel(action, {
321
+ server: getFallbackOpt(argv, "--server") || "http://127.0.0.1:8787",
322
+ authToken: getFallbackOpt(argv, "--auth-token"),
323
+ tokenFile: getFallbackOpt(argv, "--token-file"),
324
+ subscriber: getFallbackOpt(argv, "--subscriber"),
325
+ nickname: getFallbackOpt(argv, "--nickname"),
326
+ name: getFallbackOpt(argv, "--name"),
327
+ type: getFallbackOpt(argv, "--type") || defaultChannelType,
328
+ }, onlineAuthHeaders);
329
+ }
330
+ case "connect": {
331
+ const allowFrom = (() => {
332
+ const collectOptionValues = options.collectOptionValues;
333
+ const collectOption = options.collectOption;
334
+ if (typeof collectOptionValues !== "function" || typeof collectOption !== "function") return [];
335
+ return collectOptionValues(argv, "--allow-from")
336
+ .reduce((acc, value) => collectOption(value, acc), []);
337
+ })();
338
+ return runOnlineConnect({
339
+ projectRoot: options.projectRoot || process.cwd(),
340
+ nickname: getFallbackOpt(argv, "--nickname"),
341
+ subscriber: getFallbackOpt(argv, "--subscriber"),
342
+ url: getFallbackOpt(argv, "--url") || "ws://127.0.0.1:8787/ufoo/online",
343
+ token: getFallbackOpt(argv, "--token"),
344
+ tokenHash: getFallbackOpt(argv, "--token-hash"),
345
+ tokenFile: getFallbackOpt(argv, "--token-file"),
346
+ world: getFallbackOpt(argv, "--world") || "default",
347
+ pingMs: getFallbackOpt(argv, "--ping-ms") ? parseInt(getFallbackOpt(argv, "--ping-ms"), 10) : 0,
348
+ join: getFallbackOpt(argv, "--join"),
349
+ room: getFallbackOpt(argv, "--room"),
350
+ roomPassword: getFallbackOpt(argv, "--room-password"),
351
+ interval: getFallbackOpt(argv, "--interval") ? parseInt(getFallbackOpt(argv, "--interval"), 10) : 1500,
352
+ allowInsecureWs: hasFallbackFlag(argv, "--allow-insecure-ws"),
353
+ trustRemote: hasFallbackFlag(argv, "--trust-remote"),
354
+ allowFrom,
355
+ });
356
+ }
357
+ case "send": {
358
+ return runOnlineSend({
359
+ nickname: getFallbackOpt(argv, "--nickname"),
360
+ text: getFallbackOpt(argv, "--text"),
361
+ channel: getFallbackOpt(argv, "--channel"),
362
+ room: getFallbackOpt(argv, "--room"),
363
+ });
364
+ }
365
+ case "inbox": {
366
+ return runOnlineInbox(argv[1], {
367
+ clear: hasFallbackFlag(argv, "--clear"),
368
+ unread: hasFallbackFlag(argv, "--unread"),
369
+ });
370
+ }
371
+ default:
372
+ throw createUnknownOnlineError(subcmd);
373
+ }
374
+ }
375
+
376
+ module.exports = {
377
+ runOnlineCommand,
378
+ createUnknownOnlineError,
379
+ };