moshcode 0.24.2 → 0.25.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.
package/bin/moshcode.mjs CHANGED
@@ -546,7 +546,15 @@ async function main() {
546
546
  } catch (e) { console.error(String(e.message || e)); process.exitCode = 1; }
547
547
  return;
548
548
  }
549
- if (cmd === "whoami") { await whoami(); return; }
549
+ if (cmd === "whoami") {
550
+ if (rest.length > 1 || (rest.length === 1 && rest[0] !== "--json")) {
551
+ console.error("usage: moshcode whoami [--json]");
552
+ process.exitCode = 1;
553
+ return;
554
+ }
555
+ await whoami({ json: rest[0] === "--json" });
556
+ return;
557
+ }
550
558
  if (cmd === "logout") { logout(); return; }
551
559
  if (cmd === "run") {
552
560
  let max = 3, dryRun = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moshcode",
3
- "version": "0.24.2",
3
+ "version": "0.25.0",
4
4
  "type": "module",
5
5
  "description": "moshcode — a metal wrapper for coding engines and native UGig/CoinPay workflow CLIs, with OpenPRD and moshscript",
6
6
  "repository": {
@@ -12,8 +12,8 @@
12
12
  "url": "https://github.com/moshcoder/moshcode/issues"
13
13
  },
14
14
  "bin": {
15
- "moshcode": "./bin/moshcode.mjs",
16
- "moshscript": "./bin/moshscript.mjs"
15
+ "moshcode": "bin/moshcode.mjs",
16
+ "moshscript": "bin/moshscript.mjs"
17
17
  },
18
18
  "scripts": {
19
19
  "start": "node bin/moshcode.mjs",
package/src/auth.mjs CHANGED
@@ -167,22 +167,88 @@ export async function loginAuto({ device = false, browser = false } = {}) {
167
167
  }
168
168
 
169
169
  /** Print who is logged in (verified against the app). */
170
- export async function whoami() {
170
+ export async function whoami({ json = false } = {}) {
171
171
  const creds = loadCreds();
172
- if (!creds?.token) { console.log("not logged in — run: moshcode login"); return; }
172
+ if (!creds?.token) {
173
+ if (json) {
174
+ console.log(JSON.stringify({
175
+ status: "not_logged_in",
176
+ verified: false,
177
+ api: API(),
178
+ user: null,
179
+ }, null, 2));
180
+ } else {
181
+ console.log("not logged in — run: moshcode login");
182
+ }
183
+ return;
184
+ }
185
+ const api = creds.api || API();
186
+ const localUser = {
187
+ id: creds.id ?? null,
188
+ email: creds.email ?? null,
189
+ name: null,
190
+ credits: null,
191
+ };
192
+ const printJson = (value) => console.log(JSON.stringify(value, null, 2));
173
193
  try {
174
- const res = await fetch(`${creds.api || API()}/api/me`, { headers: { authorization: `Bearer ${creds.token}` } });
175
- if (res.status === 401) { console.log("session expired — run: moshcode login"); return; }
194
+ const res = await fetch(`${api}/api/me`, { headers: { authorization: `Bearer ${creds.token}` } });
195
+ if (res.status === 401) {
196
+ if (json) {
197
+ printJson({
198
+ status: "expired",
199
+ verified: false,
200
+ api,
201
+ user: localUser,
202
+ error: { type: "auth", status: 401 },
203
+ });
204
+ }
205
+ else console.log("session expired — run: moshcode login");
206
+ return;
207
+ }
176
208
  // Any other error status still has a body, and it isn't an account — reading
177
209
  // it as one prints a made-up identity for a session the app just refused.
178
210
  if (!res.ok) {
179
- console.log(`${creds.email || "logged in"} @ ${creds.api || API()} (couldn't verify — the app returned ${res.status})`);
211
+ if (json) {
212
+ printJson({
213
+ status: "unverified",
214
+ verified: false,
215
+ api,
216
+ user: localUser,
217
+ error: { type: "http", status: res.status },
218
+ });
219
+ } else {
220
+ console.log(`${creds.email || "logged in"} @ ${api} (couldn't verify — the app returned ${res.status})`);
221
+ }
180
222
  return;
181
223
  }
182
224
  const me = await res.json();
183
- console.log(`${me.email || me.name || "moshcoder"} 🤘 (${me.credits ?? "?"} credits) @ ${creds.api || API()}`);
225
+ if (json) {
226
+ printJson({
227
+ status: "authenticated",
228
+ verified: true,
229
+ api,
230
+ user: {
231
+ id: me.id ?? creds.id ?? null,
232
+ email: me.email ?? creds.email ?? null,
233
+ name: me.name ?? null,
234
+ credits: me.credits ?? null,
235
+ },
236
+ });
237
+ } else {
238
+ console.log(`${me.email || me.name || "moshcoder"} 🤘 (${me.credits ?? "?"} credits) @ ${api}`);
239
+ }
184
240
  } catch {
185
- console.log(`${creds.email || "logged in"} @ ${creds.api || API()} (couldn't reach the app to verify)`);
241
+ if (json) {
242
+ printJson({
243
+ status: "unreachable",
244
+ verified: false,
245
+ api,
246
+ user: localUser,
247
+ error: { type: "network" },
248
+ });
249
+ } else {
250
+ console.log(`${creds.email || "logged in"} @ ${api} (couldn't reach the app to verify)`);
251
+ }
186
252
  }
187
253
  }
188
254
 
@@ -161,7 +161,9 @@ export const CORE_CLI_COMMANDS = [
161
161
  name: "whoami",
162
162
  group: "account",
163
163
  description: "show the logged-in account",
164
- synopsis: [["moshcode whoami", ""]],
164
+ synopsis: [["moshcode whoami [--json]", ""]],
165
+ flags: [["--json", "print account status as machine-readable JSON", ""]],
166
+ examples: [["moshcode whoami --json", "inspect the current session from a script"]],
165
167
  seeAlso: ["login", "logout"],
166
168
  },
167
169
  {
@@ -215,7 +215,7 @@ Register-ArgumentCompleter -Native -CommandName moshcode -ScriptBlock {
215
215
  }
216
216
  }
217
217
  'login' { if ($wordToComplete.StartsWith('-')) { $choices = $script:MoshcodeCompletionLogin } }
218
- { $_ -in @('engines', 'tools', 'commands') } {
218
+ { $_ -in @('whoami', 'engines', 'tools', 'commands') } {
219
219
  if ($wordToComplete.StartsWith('-')) { $choices = $script:MoshcodeCompletionJson }
220
220
  }
221
221
  'run' { if ($wordToComplete.StartsWith('-')) { $choices = $script:MoshcodeCompletionRun } }
@@ -321,7 +321,7 @@ _moshcode_completion() {
321
321
  login)
322
322
  [[ "$cur" == -* ]] && choices="--browser -b --device -d"
323
323
  ;;
324
- engines|tools|commands)
324
+ whoami|engines|tools|commands)
325
325
  [[ "$cur" == -* ]] && choices="--json"
326
326
  ;;
327
327
  run)
@@ -464,7 +464,7 @@ _moshcode() {
464
464
  login)
465
465
  _values "login option" --browser -b --device -d
466
466
  ;;
467
- engines|tools|commands)
467
+ whoami|engines|tools|commands)
468
468
  _values "option" --json
469
469
  ;;
470
470
  run)
@@ -556,7 +556,7 @@ complete -c moshcode -n '__moshcode_nested_is mcp list' -l json -d 'print JSON'
556
556
  complete -c moshcode -n '__moshcode_nested_is skill list; or __moshcode_nested_is skills list' -l json -d 'print JSON'
557
557
  complete -c moshcode -n '__moshcode_command_is login' -l browser -s b -d 'use browser authentication'
558
558
  complete -c moshcode -n '__moshcode_command_is login' -l device -s d -d 'use device-code authentication'
559
- complete -c moshcode -n '${atSecondToken("agents engines tools commands")}' -l json -d 'print JSON'
559
+ complete -c moshcode -n '${atSecondToken("agents whoami engines tools commands")}' -l json -d 'print JSON'
560
560
  complete -c moshcode -n '__moshcode_command_is run' -l dry-run -d 'show actions without executing'
561
561
  complete -c moshcode -n '__moshcode_command_is run' -l max -s n -r -d 'maximum loop count'
562
562
  complete -c moshcode -n '__moshcode_command_is uninstall remove' -l yes -s y -d 'confirm deleting a binary'
package/src/tui.mjs CHANGED
@@ -539,7 +539,14 @@ export async function tui() {
539
539
  catch (e) { console.log(err(String(e.message || e))); }
540
540
  continue;
541
541
  }
542
- if (cmd === "whoami") { await whoami(); continue; }
542
+ if (cmd === "whoami") {
543
+ if (rest.length > 1 || (rest.length === 1 && rest[0] !== "--json")) {
544
+ console.log(err("usage: /whoami [--json]"));
545
+ continue;
546
+ }
547
+ await whoami({ json: rest[0] === "--json" });
548
+ continue;
549
+ }
543
550
  if (cmd === "logout") { logout(); continue; }
544
551
  if (cmd === "run") {
545
552
  await runFile(rest);