@mosse-ai/cli 0.1.0 → 0.1.2
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/dist/index.js +415 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22626,9 +22626,9 @@ var InboxWaitTool = {
|
|
|
22626
22626
|
summary: "Wait quietly for a realtime Inbox event for the signed-in user's ID (server checks ownership). Read Inbox before waiting and after every result, including timeout/reconnect, to recover missed events. Timeout is normal: do not send a chat update for it. This bounded call does not wake an idle host or schedule another turn. Coalesce new notifications; do not repeatedly report already handled items.",
|
|
22627
22627
|
input: external_exports.strictObject({ userId: external_exports.uuid(), timeoutMs: external_exports.number().int().min(1e3).max(25e3).default(25e3) }),
|
|
22628
22628
|
effect: "read",
|
|
22629
|
-
transport: { kind: "
|
|
22629
|
+
transport: { kind: "rest", method: "GET", path: "/api/inbox/wait" },
|
|
22630
22630
|
mcpName: "inbox_wait",
|
|
22631
|
-
|
|
22631
|
+
cli: { path: ["inbox", "wait"], example: "mosse inbox wait --timeout-ms 25000 --json" }
|
|
22632
22632
|
};
|
|
22633
22633
|
var SESSION_TOOLS = [
|
|
22634
22634
|
WorkspaceListTool,
|
|
@@ -23159,7 +23159,7 @@ function buildCommandTree(options = {}) {
|
|
|
23159
23159
|
}
|
|
23160
23160
|
|
|
23161
23161
|
// src/api.ts
|
|
23162
|
-
var CLI_VERSION = true ? "0.1.
|
|
23162
|
+
var CLI_VERSION = true ? "0.1.2" : "0.0.0";
|
|
23163
23163
|
var CLI_USER_AGENT = `mosse-cli/${CLI_VERSION}`;
|
|
23164
23164
|
async function callApi(request) {
|
|
23165
23165
|
const headers = {
|
|
@@ -23615,9 +23615,182 @@ function packagedSkillMd(version3 = CLI_VERSION) {
|
|
|
23615
23615
|
return renderSkillMd(buildCommandTree({ sessionTools: SESSION_TOOLS }), version3);
|
|
23616
23616
|
}
|
|
23617
23617
|
|
|
23618
|
+
// src/completions.ts
|
|
23619
|
+
var COMPLETION_SHELLS = ["bash", "zsh", "fish"];
|
|
23620
|
+
var LOCAL_COMMANDS = [
|
|
23621
|
+
"auth login",
|
|
23622
|
+
"auth logout",
|
|
23623
|
+
"auth status",
|
|
23624
|
+
"auth token",
|
|
23625
|
+
"auth whoami",
|
|
23626
|
+
"skill",
|
|
23627
|
+
"skill install",
|
|
23628
|
+
"skill status",
|
|
23629
|
+
"skill upgrade",
|
|
23630
|
+
"doctor",
|
|
23631
|
+
"completions",
|
|
23632
|
+
"update",
|
|
23633
|
+
"help",
|
|
23634
|
+
"inbox list",
|
|
23635
|
+
"inbox read",
|
|
23636
|
+
"workspace list"
|
|
23637
|
+
];
|
|
23638
|
+
var GLOBAL_FLAGS = [
|
|
23639
|
+
"--json",
|
|
23640
|
+
"--format",
|
|
23641
|
+
"--workspace",
|
|
23642
|
+
"--dry-run",
|
|
23643
|
+
"--yes",
|
|
23644
|
+
"--help",
|
|
23645
|
+
"--version",
|
|
23646
|
+
"--api-url",
|
|
23647
|
+
"--token"
|
|
23648
|
+
];
|
|
23649
|
+
function completionWords(tree) {
|
|
23650
|
+
const words = new Set(LOCAL_COMMANDS);
|
|
23651
|
+
for (const command of tree.commands) {
|
|
23652
|
+
for (let length = 1; length <= command.path.length; length += 1) words.add(command.path.slice(0, length).join(" "));
|
|
23653
|
+
}
|
|
23654
|
+
for (const flag of GLOBAL_FLAGS) words.add(flag);
|
|
23655
|
+
return [...words].sort((a, b) => a.localeCompare(b));
|
|
23656
|
+
}
|
|
23657
|
+
var quote = (value) => `'${value.replaceAll("'", `'\\''`)}'`;
|
|
23658
|
+
function bashScript(words) {
|
|
23659
|
+
const list = words.map(quote).join(" ");
|
|
23660
|
+
return `# bash completion for mosse (generated by \`mosse completions bash\`)
|
|
23661
|
+
_mosse_complete() {
|
|
23662
|
+
local cur prefix candidate rest next i
|
|
23663
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
23664
|
+
prefix=""
|
|
23665
|
+
for ((i = 1; i < COMP_CWORD; i++)); do
|
|
23666
|
+
prefix+="\${COMP_WORDS[i]} "
|
|
23667
|
+
done
|
|
23668
|
+
prefix="\${prefix% }"
|
|
23669
|
+
COMPREPLY=()
|
|
23670
|
+
for candidate in ${list}; do
|
|
23671
|
+
if [[ -z "$prefix" ]]; then
|
|
23672
|
+
rest="$candidate"
|
|
23673
|
+
else
|
|
23674
|
+
[[ "$candidate" == "$prefix "* ]] || continue
|
|
23675
|
+
rest="\${candidate#"$prefix "}"
|
|
23676
|
+
fi
|
|
23677
|
+
next="\${rest%% *}"
|
|
23678
|
+
[[ -z "$next" ]] && continue
|
|
23679
|
+
if [[ "$next" == "$cur"* ]]; then
|
|
23680
|
+
COMPREPLY+=("$next")
|
|
23681
|
+
fi
|
|
23682
|
+
done
|
|
23683
|
+
# \u53BB\u91CD(\u540C\u4E00\u5C42\u53EF\u80FD\u6765\u81EA\u591A\u6761\u547D\u4EE4)
|
|
23684
|
+
if ((\${#COMPREPLY[@]} > 0)); then
|
|
23685
|
+
COMPREPLY=($(printf '%s\\n' "\${COMPREPLY[@]}" | sort -u))
|
|
23686
|
+
fi
|
|
23687
|
+
}
|
|
23688
|
+
complete -o nosort -F _mosse_complete mosse
|
|
23689
|
+
`;
|
|
23690
|
+
}
|
|
23691
|
+
function zshScript(words) {
|
|
23692
|
+
const list = words.map(quote).join(" ");
|
|
23693
|
+
return `#compdef mosse (generated by \`mosse completions zsh\`)
|
|
23694
|
+
_mosse() {
|
|
23695
|
+
local -a candidates
|
|
23696
|
+
candidates=(${list})
|
|
23697
|
+
local prefix rest next cur
|
|
23698
|
+
cur="\${words[CURRENT]}"
|
|
23699
|
+
prefix=""
|
|
23700
|
+
local i
|
|
23701
|
+
for ((i = 2; i < CURRENT; i++)); do
|
|
23702
|
+
prefix+="\${words[i]} "
|
|
23703
|
+
done
|
|
23704
|
+
prefix="\${prefix% }"
|
|
23705
|
+
if [[ -z "$prefix" ]]; then
|
|
23706
|
+
_describe -t commands 'mosse command' candidates
|
|
23707
|
+
return
|
|
23708
|
+
fi
|
|
23709
|
+
local -a matches
|
|
23710
|
+
for candidate in "\${candidates[@]}"; do
|
|
23711
|
+
[[ "$candidate" == "$prefix "* ]] || continue
|
|
23712
|
+
rest="\${candidate#"$prefix "}"
|
|
23713
|
+
next="\${rest%% *}"
|
|
23714
|
+
[[ -z "$next" ]] && continue
|
|
23715
|
+
matches+=("$next")
|
|
23716
|
+
done
|
|
23717
|
+
if ((\${#matches[@]} > 0)); then
|
|
23718
|
+
compadd -a matches
|
|
23719
|
+
fi
|
|
23720
|
+
}
|
|
23721
|
+
_mosse "$@"
|
|
23722
|
+
`;
|
|
23723
|
+
}
|
|
23724
|
+
function fishScript(words) {
|
|
23725
|
+
const list = words.map(quote).join(" ");
|
|
23726
|
+
return `# fish completion for mosse (generated by \`mosse completions fish\`)
|
|
23727
|
+
function __mosse_complete
|
|
23728
|
+
set -l tokens (commandline -opc)
|
|
23729
|
+
set -e tokens[1]
|
|
23730
|
+
set -l prefix (string join " " $tokens)
|
|
23731
|
+
for candidate in ${list}
|
|
23732
|
+
if test -n "$prefix"
|
|
23733
|
+
string match -q -- "$prefix *" $candidate; or continue
|
|
23734
|
+
set -l rest (string replace -- "$prefix " "" $candidate)
|
|
23735
|
+
set -l next (string split -m 1 " " $rest)[1]
|
|
23736
|
+
echo $next
|
|
23737
|
+
else
|
|
23738
|
+
echo (string split -m 1 " " $candidate)[1]
|
|
23739
|
+
end
|
|
23740
|
+
end | sort -u
|
|
23741
|
+
end
|
|
23742
|
+
complete -c mosse -f -a '(__mosse_complete)'
|
|
23743
|
+
`;
|
|
23744
|
+
}
|
|
23745
|
+
function renderCompletions(tree, shell) {
|
|
23746
|
+
const words = completionWords(tree);
|
|
23747
|
+
if (shell === "bash") return bashScript(words);
|
|
23748
|
+
if (shell === "zsh") return zshScript(words);
|
|
23749
|
+
return fishScript(words);
|
|
23750
|
+
}
|
|
23751
|
+
|
|
23752
|
+
// src/help.ts
|
|
23753
|
+
function editDistance(a, b) {
|
|
23754
|
+
const rows = a.length + 1;
|
|
23755
|
+
const cols = b.length + 1;
|
|
23756
|
+
let prev = Array.from({ length: cols }, (_, i) => i);
|
|
23757
|
+
for (let i = 1; i < rows; i += 1) {
|
|
23758
|
+
const next = [i];
|
|
23759
|
+
for (let j = 1; j < cols; j += 1) {
|
|
23760
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
23761
|
+
next[j] = Math.min(prev[j] + 1, next[j - 1] + 1, prev[j - 1] + cost);
|
|
23762
|
+
}
|
|
23763
|
+
prev = next;
|
|
23764
|
+
}
|
|
23765
|
+
return prev[b.length];
|
|
23766
|
+
}
|
|
23767
|
+
function suggestCommands(tree, tokens, limit2 = 3) {
|
|
23768
|
+
const typed = tokens.join(" ");
|
|
23769
|
+
if (!typed) return [];
|
|
23770
|
+
const typedTokens = new Set(tokens);
|
|
23771
|
+
const scored = tree.commands.map((command) => {
|
|
23772
|
+
const path = command.path.join(" ");
|
|
23773
|
+
const overlap = command.path.filter((segment) => typedTokens.has(segment)).length;
|
|
23774
|
+
const distance = editDistance(typed, path);
|
|
23775
|
+
const startsWith = path.startsWith(typed) ? 1 : 0;
|
|
23776
|
+
return { command, score: distance - overlap * 2 - startsWith * 2 };
|
|
23777
|
+
}).filter((entry) => entry.score <= 4).sort((a, b) => a.score - b.score || a.command.path.length - b.command.path.length);
|
|
23778
|
+
return scored.slice(0, limit2).map((entry) => entry.command);
|
|
23779
|
+
}
|
|
23780
|
+
function searchCommands(tree, query) {
|
|
23781
|
+
const q = query.trim().toLowerCase();
|
|
23782
|
+
if (!q) return [];
|
|
23783
|
+
return tree.commands.filter(
|
|
23784
|
+
(command) => command.path.join(" ").includes(q) || command.summary.toLowerCase().includes(q)
|
|
23785
|
+
);
|
|
23786
|
+
}
|
|
23787
|
+
|
|
23618
23788
|
// src/cli.ts
|
|
23619
23789
|
var EXIT_USAGE = 2;
|
|
23620
23790
|
var EXIT_AUTH = 3;
|
|
23791
|
+
var EXIT_NOT_FOUND = 4;
|
|
23792
|
+
var INBOX_WAIT_DEFAULT_MS = 25e3;
|
|
23793
|
+
var INBOX_WAIT_MAX_MS = 25e3;
|
|
23621
23794
|
var UsageError = class extends Error {
|
|
23622
23795
|
};
|
|
23623
23796
|
function fullTree() {
|
|
@@ -23715,12 +23888,12 @@ function suggestFlag(name, flags) {
|
|
|
23715
23888
|
let best = null;
|
|
23716
23889
|
for (const flag of flags) {
|
|
23717
23890
|
const candidate = flag.name.replace(/^--/, "").replace(/-/g, "");
|
|
23718
|
-
const distance =
|
|
23891
|
+
const distance = editDistance2(target, candidate);
|
|
23719
23892
|
if (distance <= 2 && (!best || distance < best.distance)) best = { name: flag.name, distance };
|
|
23720
23893
|
}
|
|
23721
23894
|
return best ? `; did you mean ${best.name}?` : "";
|
|
23722
23895
|
}
|
|
23723
|
-
function
|
|
23896
|
+
function editDistance2(a, b) {
|
|
23724
23897
|
const rows = a.length + 1;
|
|
23725
23898
|
const cols = b.length + 1;
|
|
23726
23899
|
let prev = Array.from({ length: cols }, (_, j) => j);
|
|
@@ -23897,11 +24070,31 @@ async function runCli(argv, deps) {
|
|
|
23897
24070
|
}
|
|
23898
24071
|
const envWorkspace = deps.env.MOSSE_WORKSPACE?.trim();
|
|
23899
24072
|
const workspaceOf = () => globals.workspace ?? envWorkspace;
|
|
23900
|
-
const
|
|
24073
|
+
const effective = rest[0] === "workspace" && rest[1] === "list" ? ["auth", "whoami"].concat(rest.slice(2)) : rest;
|
|
24074
|
+
if (rest[0] === "workspace" && rest.length === 1) {
|
|
24075
|
+
deps.stdout(workspaceHelp(tree));
|
|
24076
|
+
return 0;
|
|
24077
|
+
}
|
|
24078
|
+
const { head, tail } = splitHead(effective);
|
|
24079
|
+
const rootHelp = () => `${tree.rootHelp}
|
|
24080
|
+
Local commands:
|
|
24081
|
+
auth <login|logout|status|token> credentials (not part of the tool surface)
|
|
24082
|
+
skill [install|status|upgrade] agent cheatsheet (mosse skill for the one-pager)
|
|
24083
|
+
doctor local environment check
|
|
24084
|
+
completions <bash|zsh|fish> shell completion script
|
|
24085
|
+
workspace list list workspaces (alias of auth whoami)
|
|
24086
|
+
inbox wait [--timeout-ms <ms>] long-poll one inbox notification (exit 4 on timeout)
|
|
24087
|
+
update check npm for a newer @mosse-ai/cli
|
|
24088
|
+
help [query] search commands by path / description
|
|
24089
|
+
`;
|
|
23901
24090
|
if (!head.length) {
|
|
23902
|
-
deps.stdout(
|
|
24091
|
+
deps.stdout(rootHelp());
|
|
23903
24092
|
return 0;
|
|
23904
24093
|
}
|
|
24094
|
+
if (head[0] === "inbox" && head[1] === "wait") return handleInboxWait(rest.slice(2), deps, config2, globals);
|
|
24095
|
+
if (head[0] === "update") return handleUpdate(rest.slice(1), deps, globals);
|
|
24096
|
+
if (head[0] === "help") return handleHelpSearch(rest.slice(1), deps, tree, rootHelp());
|
|
24097
|
+
if (head[0] === "completions") return handleCompletions(rest.slice(1), deps, tree, globals);
|
|
23905
24098
|
if (head[0] === "skill") return handleSkill(rest.slice(1), deps, configPath, config2, tree, globals);
|
|
23906
24099
|
if (head[0] === "doctor") return handleDoctor(deps, config2, globals);
|
|
23907
24100
|
if (head[0] === "auth" && (head[1] === void 0 || AUTH_SUBCOMMANDS.has(head[1])))
|
|
@@ -23912,7 +24105,11 @@ async function runCli(argv, deps) {
|
|
|
23912
24105
|
deps.stdout(renderGroupHelp(tree.commands, head));
|
|
23913
24106
|
return 0;
|
|
23914
24107
|
}
|
|
23915
|
-
|
|
24108
|
+
const suggestions = suggestCommands(tree, head);
|
|
24109
|
+
const hint = suggestions.length ? `; did you mean: ${suggestions.map((item) => `mosse ${item.path.join(" ")}`).join(", ")}` : "";
|
|
24110
|
+
deps.stderr(
|
|
24111
|
+
structuredError(globals, EXIT_USAGE, "unknown_command", `no such command: mosse ${head.join(" ")}${hint}`)
|
|
24112
|
+
);
|
|
23916
24113
|
deps.stderr(tree.rootHelp);
|
|
23917
24114
|
return EXIT_USAGE;
|
|
23918
24115
|
}
|
|
@@ -24075,6 +24272,216 @@ function sessionPath(tool, input2) {
|
|
|
24075
24272
|
return encodeURIComponent(String(value));
|
|
24076
24273
|
});
|
|
24077
24274
|
}
|
|
24275
|
+
async function handleUpdate(args, deps, globals) {
|
|
24276
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
24277
|
+
deps.stdout("mosse update\n\n\u68C0\u67E5 npm \u4E0A\u7684\u6700\u65B0\u7248;\u4E0D\u81EA\u52A8\u5B89\u88C5,\u53EA\u6253\u5370\u5347\u7EA7\u547D\u4EE4\u3002\n");
|
|
24278
|
+
return 0;
|
|
24279
|
+
}
|
|
24280
|
+
const registry2 = "https://registry.npmjs.org/@mosse-ai/cli/latest";
|
|
24281
|
+
let latest;
|
|
24282
|
+
try {
|
|
24283
|
+
const response = await deps.fetch(registry2, { headers: { accept: "application/json" } });
|
|
24284
|
+
if (!response.ok) throw new Error(`registry responded ${response.status}`);
|
|
24285
|
+
const body = await response.json();
|
|
24286
|
+
if (!body.version) throw new Error("registry response has no version");
|
|
24287
|
+
latest = body.version;
|
|
24288
|
+
} catch (error62) {
|
|
24289
|
+
deps.stderr(
|
|
24290
|
+
structuredError(
|
|
24291
|
+
globals,
|
|
24292
|
+
1,
|
|
24293
|
+
"update_check_failed",
|
|
24294
|
+
`could not check the npm registry: ${error62.message}`
|
|
24295
|
+
)
|
|
24296
|
+
);
|
|
24297
|
+
return 1;
|
|
24298
|
+
}
|
|
24299
|
+
const upToDate = compareVersions(latest, CLI_VERSION) <= 0;
|
|
24300
|
+
if (globals.json !== void 0) {
|
|
24301
|
+
deps.stdout(renderOutput({ current: CLI_VERSION, latest, upToDate }, outputOptions(globals)));
|
|
24302
|
+
} else {
|
|
24303
|
+
deps.stdout(
|
|
24304
|
+
upToDate ? `mosse ${CLI_VERSION} is up to date (latest ${latest})` : `mosse ${CLI_VERSION} \u2192 ${latest} available
|
|
24305
|
+
npm i -g @mosse-ai/cli@${latest}
|
|
24306
|
+
# or: npx @mosse-ai/cli@latest <command>`
|
|
24307
|
+
);
|
|
24308
|
+
}
|
|
24309
|
+
return 0;
|
|
24310
|
+
}
|
|
24311
|
+
function compareVersions(a, b) {
|
|
24312
|
+
const pa = a.split(".").map((part) => Number(part) || 0);
|
|
24313
|
+
const pb = b.split(".").map((part) => Number(part) || 0);
|
|
24314
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {
|
|
24315
|
+
const diff = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
24316
|
+
if (diff !== 0) return diff;
|
|
24317
|
+
}
|
|
24318
|
+
return 0;
|
|
24319
|
+
}
|
|
24320
|
+
async function handleHelpSearch(args, deps, tree, root) {
|
|
24321
|
+
const query = args.filter((arg) => !arg.startsWith("-")).join(" ").trim();
|
|
24322
|
+
if (!query) {
|
|
24323
|
+
deps.stdout(root);
|
|
24324
|
+
return 0;
|
|
24325
|
+
}
|
|
24326
|
+
const matches = searchCommands(tree, query);
|
|
24327
|
+
if (!matches.length) {
|
|
24328
|
+
deps.stderr(`no commands match "${query}" (try \`mosse --help\`)`);
|
|
24329
|
+
return 0;
|
|
24330
|
+
}
|
|
24331
|
+
deps.stdout(matches.map((command) => `mosse ${command.path.join(" ")}
|
|
24332
|
+
${command.summary}`).join("\n\n"));
|
|
24333
|
+
return 0;
|
|
24334
|
+
}
|
|
24335
|
+
async function handleInboxWait(args, deps, config2, globals) {
|
|
24336
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
24337
|
+
deps.stdout(
|
|
24338
|
+
[
|
|
24339
|
+
"mosse inbox wait [options]",
|
|
24340
|
+
"",
|
|
24341
|
+
"\u957F\u8F6E\u8BE2\u7B49\u4E00\u6761\u6536\u4EF6\u7BB1\u901A\u77E5(\u4E0E MCP \u7684 inbox_wait \u540C\u4E00\u8BED\u4E49)\u3002",
|
|
24342
|
+
"",
|
|
24343
|
+
"Options:",
|
|
24344
|
+
" --timeout-ms <ms> \u7B49\u5F85\u4E0A\u9650 1000\u201325000(\u9ED8\u8BA4 25000;--timeout \u662F\u522B\u540D)",
|
|
24345
|
+
" --user-id <uuid> token \u6240\u6709\u8005(\u7F3A\u7701\u81EA\u52A8\u4ECE token \u89E3\u6790)",
|
|
24346
|
+
" --workspace <id> \u5DE5\u4F5C\u533A(\u7F3A\u7701\u6309 token \u552F\u4E00 workspace \u63A8\u65AD)",
|
|
24347
|
+
"",
|
|
24348
|
+
"\u9000\u51FA\u7801:0 \u6536\u5230\u901A\u77E5 \xB7 2 \u7528\u6CD5 \xB7 3 \u8BA4\u8BC1/\u6743\u9650 \xB7 4 \u8D85\u65F6(\u672A\u6536\u5230\u901A\u77E5)",
|
|
24349
|
+
""
|
|
24350
|
+
].join("\n")
|
|
24351
|
+
);
|
|
24352
|
+
return 0;
|
|
24353
|
+
}
|
|
24354
|
+
let timeoutMs = INBOX_WAIT_DEFAULT_MS;
|
|
24355
|
+
let userId;
|
|
24356
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
24357
|
+
const arg = args[i];
|
|
24358
|
+
if (arg === "--timeout-ms" || arg === "--timeout") {
|
|
24359
|
+
const raw = args[i + 1];
|
|
24360
|
+
i += 1;
|
|
24361
|
+
timeoutMs = Number(raw);
|
|
24362
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 1e3 || timeoutMs > INBOX_WAIT_MAX_MS)
|
|
24363
|
+
return waitUsage(deps, globals, `--timeout-ms must be an integer between 1000 and ${INBOX_WAIT_MAX_MS}`);
|
|
24364
|
+
} else if (arg === "--user-id") {
|
|
24365
|
+
userId = args[i + 1];
|
|
24366
|
+
i += 1;
|
|
24367
|
+
if (!userId) return waitUsage(deps, globals, "--user-id needs a value");
|
|
24368
|
+
} else {
|
|
24369
|
+
return waitUsage(deps, globals, `unknown flag: ${arg}`);
|
|
24370
|
+
}
|
|
24371
|
+
}
|
|
24372
|
+
const apiUrl = globals.apiUrl ?? deps.env.MOSSE_API_URL?.trim() ?? config2.apiUrl ?? DEFAULT_API_URL;
|
|
24373
|
+
const token = globals.token ?? deps.env.MOSSE_TOKEN?.trim() ?? hostConfigOf(config2, apiUrl).token;
|
|
24374
|
+
if (!token) {
|
|
24375
|
+
deps.stderr(structuredError(globals, EXIT_AUTH, "unauthenticated", "run `mosse auth login` (or set MOSSE_TOKEN)"));
|
|
24376
|
+
return EXIT_AUTH;
|
|
24377
|
+
}
|
|
24378
|
+
let workspaceId = globals.workspace?.trim() || deps.env.MOSSE_WORKSPACE?.trim() || void 0;
|
|
24379
|
+
if (!userId || !workspaceId) {
|
|
24380
|
+
const listed = await callApi({ fetchImpl: deps.fetch, apiUrl, method: "GET", path: "/api/me/workspaces", token });
|
|
24381
|
+
if (!listed.ok) {
|
|
24382
|
+
const exit = exitCodeForStatus(listed.status);
|
|
24383
|
+
deps.stderr(structuredError(globals, exit, listed.error, withHttpHint(listed.message)));
|
|
24384
|
+
return exit;
|
|
24385
|
+
}
|
|
24386
|
+
const body = listed.body;
|
|
24387
|
+
userId = userId ?? body.userId;
|
|
24388
|
+
if (!userId) {
|
|
24389
|
+
deps.stderr(structuredError(globals, 1, "internal", "token lookup returned no userId"));
|
|
24390
|
+
return 1;
|
|
24391
|
+
}
|
|
24392
|
+
const workspaces = body.workspaces ?? [];
|
|
24393
|
+
if (!workspaceId) {
|
|
24394
|
+
if (workspaces.length === 1) workspaceId = workspaces[0].id;
|
|
24395
|
+
else if (workspaces.length === 0) {
|
|
24396
|
+
deps.stderr(structuredError(globals, EXIT_AUTH, "no_workspace", "this token cannot use any workspace"));
|
|
24397
|
+
return EXIT_AUTH;
|
|
24398
|
+
} else {
|
|
24399
|
+
const list = workspaces.map((workspace) => `${workspace.id} (${workspace.name})`).join(", ");
|
|
24400
|
+
deps.stderr(
|
|
24401
|
+
structuredError(
|
|
24402
|
+
globals,
|
|
24403
|
+
EXIT_USAGE,
|
|
24404
|
+
"workspace_required",
|
|
24405
|
+
`this token covers several workspaces; pass --workspace. Available: ${list}`
|
|
24406
|
+
)
|
|
24407
|
+
);
|
|
24408
|
+
return EXIT_USAGE;
|
|
24409
|
+
}
|
|
24410
|
+
}
|
|
24411
|
+
}
|
|
24412
|
+
const result = await callApi({
|
|
24413
|
+
fetchImpl: deps.fetch,
|
|
24414
|
+
apiUrl,
|
|
24415
|
+
method: "GET",
|
|
24416
|
+
path: `/api/inbox/wait?timeoutMs=${timeoutMs}`,
|
|
24417
|
+
token,
|
|
24418
|
+
...workspaceId ? { workspaceId } : {}
|
|
24419
|
+
});
|
|
24420
|
+
if (!result.ok) {
|
|
24421
|
+
const exit = exitCodeForStatus(result.status);
|
|
24422
|
+
deps.stderr(structuredError(globals, exit, result.error, withHttpHint(result.message)));
|
|
24423
|
+
return exit;
|
|
24424
|
+
}
|
|
24425
|
+
const status = result.body.status;
|
|
24426
|
+
if (globals.json !== void 0) deps.stdout(renderOutput(result.body, outputOptions(globals)));
|
|
24427
|
+
else deps.stdout(status === "notification" ? "notification" : "timeout");
|
|
24428
|
+
if (status === "timeout") {
|
|
24429
|
+
deps.stderr("inbox wait timed out (no notification)");
|
|
24430
|
+
return EXIT_NOT_FOUND;
|
|
24431
|
+
}
|
|
24432
|
+
return 0;
|
|
24433
|
+
}
|
|
24434
|
+
function waitUsage(deps, globals, message) {
|
|
24435
|
+
deps.stderr(structuredError(globals, EXIT_USAGE, "usage", message));
|
|
24436
|
+
return EXIT_USAGE;
|
|
24437
|
+
}
|
|
24438
|
+
function workspaceHelp(tree) {
|
|
24439
|
+
const whoami2 = tree.byPath.get("auth whoami");
|
|
24440
|
+
return [
|
|
24441
|
+
"mosse workspace \u2014 workspaces available to this token",
|
|
24442
|
+
"",
|
|
24443
|
+
" mosse workspace list [--json] list workspaces (alias of `mosse auth whoami`)",
|
|
24444
|
+
"",
|
|
24445
|
+
whoami2 ? whoami2.help.trim() : "",
|
|
24446
|
+
""
|
|
24447
|
+
].join("\n");
|
|
24448
|
+
}
|
|
24449
|
+
async function handleCompletions(args, deps, tree, globals) {
|
|
24450
|
+
const shell = args[0];
|
|
24451
|
+
if (!shell || shell === "--help" || shell === "-h") {
|
|
24452
|
+
deps.stdout(
|
|
24453
|
+
[
|
|
24454
|
+
"mosse completions <shell>",
|
|
24455
|
+
"",
|
|
24456
|
+
"\u6253\u5370 shell \u8865\u5168\u811A\u672C(\u547D\u4EE4\u8BCD\u8868\u4E0E help / skill \u540C\u6E90)\u3002",
|
|
24457
|
+
"",
|
|
24458
|
+
`Shells: ${COMPLETION_SHELLS.join(", ")}`,
|
|
24459
|
+
"",
|
|
24460
|
+
" # zsh",
|
|
24461
|
+
' mosse completions zsh > "${fpath[1]}/_mosse"',
|
|
24462
|
+
" # bash",
|
|
24463
|
+
" mosse completions bash > /etc/bash_completion.d/mosse",
|
|
24464
|
+
" # fish",
|
|
24465
|
+
" mosse completions fish > ~/.config/fish/completions/mosse.fish",
|
|
24466
|
+
""
|
|
24467
|
+
].join("\n")
|
|
24468
|
+
);
|
|
24469
|
+
return 0;
|
|
24470
|
+
}
|
|
24471
|
+
if (!COMPLETION_SHELLS.includes(shell)) {
|
|
24472
|
+
deps.stderr(
|
|
24473
|
+
structuredError(
|
|
24474
|
+
globals,
|
|
24475
|
+
EXIT_USAGE,
|
|
24476
|
+
"usage",
|
|
24477
|
+
`unknown shell: ${shell} (expected ${COMPLETION_SHELLS.join("|")})`
|
|
24478
|
+
)
|
|
24479
|
+
);
|
|
24480
|
+
return EXIT_USAGE;
|
|
24481
|
+
}
|
|
24482
|
+
deps.stdout(renderCompletions(tree, shell));
|
|
24483
|
+
return 0;
|
|
24484
|
+
}
|
|
24078
24485
|
async function handleSkill(tokens, deps, configPath, _config, tree, globals) {
|
|
24079
24486
|
const flagValue = (name) => {
|
|
24080
24487
|
for (let i = 0; i < tokens.length; i += 1) {
|