@divergeai/cli 0.1.22 → 0.1.23
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/README.md +6 -0
- package/dist/diverge.mjs +171 -80
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,12 @@ diverge tools list --organization-id <id>
|
|
|
13
13
|
|
|
14
14
|
Node 22 or later. Linux and macOS are supported; Windows is best-effort.
|
|
15
15
|
|
|
16
|
+
`diverge --help`, `diverge <command> --help` and `diverge <command> <verb>
|
|
17
|
+
--help` print the usage, and that usage is the CLI's command table: a
|
|
18
|
+
command, verb or option that does not exist is answered with the closest ones
|
|
19
|
+
it lists, by spelling or by what their description says (`diverge whoami` →
|
|
20
|
+
`diverge status`, `tools search` → `tools list --filter`), and exits 1.
|
|
21
|
+
|
|
16
22
|
## Sign in
|
|
17
23
|
|
|
18
24
|
`diverge login` runs the browser sign-in (authorization code with PKCE on a
|
package/dist/diverge.mjs
CHANGED
|
@@ -7423,7 +7423,7 @@ function tokenSource(env, baseUrl) {
|
|
|
7423
7423
|
}
|
|
7424
7424
|
|
|
7425
7425
|
// src/version.ts
|
|
7426
|
-
var VERSION = true ? "0.1.
|
|
7426
|
+
var VERSION = true ? "0.1.23" : "dev";
|
|
7427
7427
|
var USER_AGENT = `diverge/${VERSION}`;
|
|
7428
7428
|
|
|
7429
7429
|
// src/http.ts
|
|
@@ -7849,6 +7849,146 @@ async function revokeRefreshToken(baseUrl, clientId2, refreshToken) {
|
|
|
7849
7849
|
if (!response.ok) throw new CliError(`Revoke endpoint returned HTTP ${response.status}`);
|
|
7850
7850
|
}
|
|
7851
7851
|
|
|
7852
|
+
// src/usage.ts
|
|
7853
|
+
function usageEntries(usage2) {
|
|
7854
|
+
const entries = [];
|
|
7855
|
+
let current = null;
|
|
7856
|
+
for (const line of usage2.split("\n")) {
|
|
7857
|
+
if (/^ {2}\S/.test(line)) {
|
|
7858
|
+
const label = line.trim().split(/ {2,}/)[0];
|
|
7859
|
+
const verbs = [];
|
|
7860
|
+
for (const word of label.split(" ")) {
|
|
7861
|
+
if (!/^[a-z][a-z-]*$/.test(word)) break;
|
|
7862
|
+
verbs.push(word);
|
|
7863
|
+
}
|
|
7864
|
+
current = { verbs, summary: line.trim().slice(label.length).trim(), lines: [line] };
|
|
7865
|
+
entries.push(current);
|
|
7866
|
+
} else if (current && /^ {3,}\S/.test(line)) {
|
|
7867
|
+
current.lines.push(line);
|
|
7868
|
+
} else {
|
|
7869
|
+
current = null;
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
return entries;
|
|
7873
|
+
}
|
|
7874
|
+
function startsWith(words, prefix) {
|
|
7875
|
+
return prefix.every((word, index) => words[index] === word);
|
|
7876
|
+
}
|
|
7877
|
+
function verbPath(usage2, args) {
|
|
7878
|
+
let best = [];
|
|
7879
|
+
for (const entry of usageEntries(usage2)) {
|
|
7880
|
+
let shared = 0;
|
|
7881
|
+
while (shared < entry.verbs.length && args[shared] === entry.verbs[shared]) shared++;
|
|
7882
|
+
if (shared > best.length) best = entry.verbs.slice(0, shared);
|
|
7883
|
+
}
|
|
7884
|
+
return best;
|
|
7885
|
+
}
|
|
7886
|
+
function groupOptions(usage2) {
|
|
7887
|
+
return usage2.split("\n", 1)[0].match(/\[--[^\]]+\]/g) ?? [];
|
|
7888
|
+
}
|
|
7889
|
+
function verbUsage(command, usage2, path15) {
|
|
7890
|
+
const lines = usageEntries(usage2).filter((entry) => startsWith(entry.verbs, path15)).flatMap((entry) => entry.lines);
|
|
7891
|
+
if (path15.length === 0 || lines.length === 0) return usage2;
|
|
7892
|
+
const shared = groupOptions(usage2);
|
|
7893
|
+
return [`diverge ${command} ${path15.join(" ")} ...`, "", ...lines, ...shared.length ? ["", `Every ${command} command also takes ${shared.join(" ")}.`] : []].join("\n");
|
|
7894
|
+
}
|
|
7895
|
+
var COMMON_WORDS = /* @__PURE__ */ new Set(["the", "and", "you", "for", "its", "with", "not", "one", "are", "all", "any", "from", "that", "this", "own", "per", "into", "out", "else", "each", "what", "when", "your"]);
|
|
7896
|
+
function distance(a, b) {
|
|
7897
|
+
const d = Array.from({ length: a.length + 1 }, (_, i) => Array.from({ length: b.length + 1 }, (_2, j) => i === 0 ? j : j === 0 ? i : 0));
|
|
7898
|
+
for (let i = 1; i <= a.length; i++) {
|
|
7899
|
+
for (let j = 1; j <= b.length; j++) {
|
|
7900
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
7901
|
+
d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
|
|
7902
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
|
|
7903
|
+
}
|
|
7904
|
+
}
|
|
7905
|
+
return d[a.length][b.length];
|
|
7906
|
+
}
|
|
7907
|
+
function namesIt(word, guess) {
|
|
7908
|
+
if (word.length < 3 || COMMON_WORDS.has(word)) return false;
|
|
7909
|
+
return word === guess || guess.length >= 3 && word.startsWith(guess) || guess.startsWith(word) || guess.endsWith(word);
|
|
7910
|
+
}
|
|
7911
|
+
function prose(line) {
|
|
7912
|
+
return line.toLowerCase().replace(/\[[^\]]*\]|--?[a-z][a-z-]*/g, " ");
|
|
7913
|
+
}
|
|
7914
|
+
function closest(guess, candidates, rest = [], limit = 3) {
|
|
7915
|
+
const target = guess.toLowerCase().replace(/^-+/, "");
|
|
7916
|
+
const threshold = Math.max(1, Math.floor(target.length / 3));
|
|
7917
|
+
const matches = [];
|
|
7918
|
+
for (const candidate of candidates) {
|
|
7919
|
+
const first = candidate.summary ?? "";
|
|
7920
|
+
const name = candidate.name.toLowerCase();
|
|
7921
|
+
if (name && rest.includes(candidate.name)) {
|
|
7922
|
+
matches.push({ candidate, score: 0, hint: first });
|
|
7923
|
+
continue;
|
|
7924
|
+
}
|
|
7925
|
+
const edits = name ? distance(target, name) : Infinity;
|
|
7926
|
+
if (edits <= threshold || name && target.length >= 2 && name.startsWith(target)) {
|
|
7927
|
+
matches.push({ candidate, score: Math.min(edits, threshold), hint: first });
|
|
7928
|
+
continue;
|
|
7929
|
+
}
|
|
7930
|
+
const line = candidate.lines.find((text) => (prose(text).match(/[a-z]+/g) ?? []).some((word) => namesIt(word, target)));
|
|
7931
|
+
if (line) matches.push({ candidate, score: threshold + 1, hint: line });
|
|
7932
|
+
}
|
|
7933
|
+
return matches.sort((a, b) => a.score - b.score).slice(0, limit);
|
|
7934
|
+
}
|
|
7935
|
+
function didYouMean(matches) {
|
|
7936
|
+
if (matches.length === 0) return "";
|
|
7937
|
+
const shown = (match) => {
|
|
7938
|
+
const hint = match.hint.trim();
|
|
7939
|
+
return hint && hint !== match.candidate.invocation ? `${match.candidate.invocation} (${hint})` : match.candidate.invocation;
|
|
7940
|
+
};
|
|
7941
|
+
if (matches.length === 1) return ` Did you mean: ${shown(matches[0])}?`;
|
|
7942
|
+
return ` Did you mean one of:
|
|
7943
|
+
${matches.map((match) => ` ${shown(match)}`).join("\n")}`;
|
|
7944
|
+
}
|
|
7945
|
+
function verbCandidates(command, usage2, path15) {
|
|
7946
|
+
const byName = /* @__PURE__ */ new Map();
|
|
7947
|
+
for (const entry of usageEntries(usage2)) {
|
|
7948
|
+
if (!startsWith(entry.verbs, path15)) continue;
|
|
7949
|
+
const name = entry.verbs[path15.length] ?? "";
|
|
7950
|
+
const invocation = ["diverge", command, ...path15, ...name ? [name] : []].join(" ");
|
|
7951
|
+
const lines = [entry.summary, ...entry.lines.slice(1).map((line) => line.trim())].filter(Boolean);
|
|
7952
|
+
const known = byName.get(name);
|
|
7953
|
+
if (known) known.lines.push(...lines);
|
|
7954
|
+
else byName.set(name, { invocation, name, summary: entry.summary, lines });
|
|
7955
|
+
}
|
|
7956
|
+
return [...byName.values()];
|
|
7957
|
+
}
|
|
7958
|
+
function unknownVerb(command, usage2, path15, verb, rest = []) {
|
|
7959
|
+
const candidates = verbCandidates(command, usage2, path15);
|
|
7960
|
+
const where = [command, ...path15].join(" ");
|
|
7961
|
+
if (!verb) return new CliError(`${where} needs one of: ${candidates.map((candidate) => candidate.name).filter(Boolean).join(", ")}
|
|
7962
|
+
|
|
7963
|
+
${usage2}`);
|
|
7964
|
+
return new CliError(`Unknown ${where} verb: ${verb}.${didYouMean(closest(verb, candidates, rest))}
|
|
7965
|
+
|
|
7966
|
+
${usage2}`);
|
|
7967
|
+
}
|
|
7968
|
+
function optionCandidates(usage2, path15) {
|
|
7969
|
+
const entries = usageEntries(usage2);
|
|
7970
|
+
const [header = "", ...body] = usage2.split("\n");
|
|
7971
|
+
const described = entries.length === 0 || path15.length === 0 ? body : entries.filter((entry) => startsWith(entry.verbs, path15)).flatMap((entry) => entry.lines);
|
|
7972
|
+
const byName = /* @__PURE__ */ new Map();
|
|
7973
|
+
const add = (line, describes) => {
|
|
7974
|
+
for (const [flag] of line.matchAll(/--[a-z][a-z-]*/g)) {
|
|
7975
|
+
const candidate = byName.get(flag) ?? { invocation: flag, name: flag.slice(2), lines: [] };
|
|
7976
|
+
byName.set(flag, candidate);
|
|
7977
|
+
if (describes && !candidate.lines.includes(line.trim())) candidate.lines.push(line.trim());
|
|
7978
|
+
}
|
|
7979
|
+
};
|
|
7980
|
+
add(header, false);
|
|
7981
|
+
for (const line of described) add(line, true);
|
|
7982
|
+
return [...byName.values()];
|
|
7983
|
+
}
|
|
7984
|
+
function unknownOption(error, usage2, args) {
|
|
7985
|
+
if (!(error instanceof Error) || error.name !== "TypeError") return null;
|
|
7986
|
+
const option = /^Unknown option '([^']+)'/.exec(error.message)?.[1];
|
|
7987
|
+
if (!option) return null;
|
|
7988
|
+
const path15 = verbPath(usage2, args);
|
|
7989
|
+
return `Unknown option: ${option}.${didYouMean(closest(option, optionCandidates(usage2, path15)))}`;
|
|
7990
|
+
}
|
|
7991
|
+
|
|
7852
7992
|
// src/commands/login.ts
|
|
7853
7993
|
import { parseArgs } from "node:util";
|
|
7854
7994
|
|
|
@@ -8647,9 +8787,7 @@ async function runSkills(args, io) {
|
|
|
8647
8787
|
return ExitCode.Ok;
|
|
8648
8788
|
}
|
|
8649
8789
|
default:
|
|
8650
|
-
throw
|
|
8651
|
-
|
|
8652
|
-
${skillsUsage}`);
|
|
8790
|
+
throw unknownVerb("skills", skillsUsage, [], verb, rest);
|
|
8653
8791
|
}
|
|
8654
8792
|
}
|
|
8655
8793
|
|
|
@@ -8829,16 +8967,12 @@ async function setup(args, io) {
|
|
|
8829
8967
|
return ExitCode.Ok;
|
|
8830
8968
|
}
|
|
8831
8969
|
default:
|
|
8832
|
-
throw
|
|
8833
|
-
|
|
8834
|
-
${agentsUsage}`);
|
|
8970
|
+
throw unknownVerb("agents", agentsUsage, ["setup"], agent, rest);
|
|
8835
8971
|
}
|
|
8836
8972
|
}
|
|
8837
8973
|
async function run(args, io) {
|
|
8838
8974
|
const [agent, ...rest] = args;
|
|
8839
|
-
if (agent !== "dsh") throw
|
|
8840
|
-
|
|
8841
|
-
${agentsUsage}`);
|
|
8975
|
+
if (agent !== "dsh") throw unknownVerb("agents", agentsUsage, ["run"], agent, rest);
|
|
8842
8976
|
const terminator = rest.indexOf("--");
|
|
8843
8977
|
const flags = terminator === -1 ? rest : rest.slice(0, terminator);
|
|
8844
8978
|
const passthrough = terminator === -1 ? [] : rest.slice(terminator + 1);
|
|
@@ -8915,18 +9049,8 @@ async function rotate(args, io) {
|
|
|
8915
9049
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
8916
9050
|
});
|
|
8917
9051
|
}
|
|
8918
|
-
function agentsVerbUsage(verb) {
|
|
8919
|
-
const lines = agentsUsage.split("\n").filter((line) => line.trimStart().startsWith(`${verb} `) || line.trimStart().startsWith(`${verb} `));
|
|
8920
|
-
return lines.length ? `diverge agents ${verb} ...
|
|
8921
|
-
|
|
8922
|
-
${lines.join("\n")}` : agentsUsage;
|
|
8923
|
-
}
|
|
8924
9052
|
async function runAgents(args, io) {
|
|
8925
9053
|
const [verb, ...rest] = args;
|
|
8926
|
-
if (verb && (rest.includes("--help") || rest.includes("-h")) && !rest.includes("--")) {
|
|
8927
|
-
io.stdout(agentsVerbUsage(verb));
|
|
8928
|
-
return ExitCode.Ok;
|
|
8929
|
-
}
|
|
8930
9054
|
switch (verb) {
|
|
8931
9055
|
case "setup":
|
|
8932
9056
|
return setup(rest, io);
|
|
@@ -8937,9 +9061,7 @@ async function runAgents(args, io) {
|
|
|
8937
9061
|
case "status":
|
|
8938
9062
|
return status(rest, io);
|
|
8939
9063
|
default:
|
|
8940
|
-
throw
|
|
8941
|
-
|
|
8942
|
-
${agentsUsage}`);
|
|
9064
|
+
throw unknownVerb("agents", agentsUsage, [], verb, rest);
|
|
8943
9065
|
}
|
|
8944
9066
|
}
|
|
8945
9067
|
|
|
@@ -8947,20 +9069,22 @@ ${agentsUsage}`);
|
|
|
8947
9069
|
import { parseArgs as parseArgs4 } from "node:util";
|
|
8948
9070
|
var orgUsage = `diverge org [use <id|name>]
|
|
8949
9071
|
|
|
8950
|
-
|
|
8951
|
-
use <id|name
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
organization
|
|
9072
|
+
(no verb) list the organizations you may act in, the default marked
|
|
9073
|
+
use <id|name> make it the default: where every command that names no organization acts,
|
|
9074
|
+
in every shell on this machine that shares the login
|
|
9075
|
+
|
|
9076
|
+
The default is a local preference: the platform is asked only for a token
|
|
9077
|
+
there, which proves you may act in it. For one command, pass
|
|
9078
|
+
--organization-id <id> (or set DIVERGENT_ORG_ID) instead. A platform actor may
|
|
9079
|
+
act in, and so sees, every organization.`;
|
|
8957
9080
|
async function runOrg(args, io) {
|
|
8958
9081
|
const { positionals } = parseArgs4({ args, options: {}, strict: true, allowPositionals: true });
|
|
9082
|
+
const verb = positionals[0];
|
|
9083
|
+
if (verb && verb !== "use") throw unknownVerb("org", orgUsage, [], verb, positionals.slice(1));
|
|
8959
9084
|
const source = tokenSource(io.env, resolveApiUrl(void 0, io.env));
|
|
8960
9085
|
const info = await fetchUserInfo(source.baseUrl, (await getUserToken(source)).access_token);
|
|
8961
9086
|
const organizations = info.organizations ?? [];
|
|
8962
9087
|
const current = requireLogin(source).organization;
|
|
8963
|
-
const verb = positionals[0];
|
|
8964
9088
|
if (!verb) {
|
|
8965
9089
|
if (organizations.length === 0) {
|
|
8966
9090
|
io.stdout("You are not a member of any organization.");
|
|
@@ -8969,9 +9093,6 @@ async function runOrg(args, io) {
|
|
|
8969
9093
|
for (const organization of organizations) io.stdout(`${organization.id === current ? "*" : " "} ${organization.name} (${organization.id})`);
|
|
8970
9094
|
return 0;
|
|
8971
9095
|
}
|
|
8972
|
-
if (verb !== "use") throw new CliError(`Unknown verb: ${verb}
|
|
8973
|
-
|
|
8974
|
-
${orgUsage}`);
|
|
8975
9096
|
const target = positionals[1];
|
|
8976
9097
|
if (!target) throw new CliError("org use needs an organization id or name");
|
|
8977
9098
|
const choice = chooseOrganization({ flag: target, organizations });
|
|
@@ -9659,7 +9780,7 @@ function formatPending(result, apiUrl, organizationId) {
|
|
|
9659
9780
|
var toolsUsage = `diverge tools <list|capabilities|describe|call|run|invocation|bridge> [--organization-id <id>] [--project-id <id>] ...
|
|
9660
9781
|
|
|
9661
9782
|
list [--filter <text>] [--capability <selector>] [--json]
|
|
9662
|
-
--filter
|
|
9783
|
+
--filter searches tool names and descriptions, ignoring case
|
|
9663
9784
|
capabilities [--json]
|
|
9664
9785
|
describe <name> [--json]
|
|
9665
9786
|
call <name> [--args-json '{...}' | --args-json - | --args-file <path>] [--wait] [--timeout <seconds>] [--json]
|
|
@@ -9718,7 +9839,7 @@ async function call(rest, io) {
|
|
|
9718
9839
|
});
|
|
9719
9840
|
} catch (error) {
|
|
9720
9841
|
if (!json) throw error;
|
|
9721
|
-
outcome = { tool, status: "failed", error: error instanceof Error ? error.message : String(error) };
|
|
9842
|
+
outcome = { tool, status: "failed", error: unknownOption(error, toolsUsage, ["call"]) ?? (error instanceof Error ? error.message : String(error)) };
|
|
9722
9843
|
}
|
|
9723
9844
|
if (json) io.stdout(JSON.stringify(outcome, null, 2));
|
|
9724
9845
|
else printOutcome(outcome, waited, io);
|
|
@@ -9742,26 +9863,8 @@ function printOutcome(outcome, waited, io) {
|
|
|
9742
9863
|
throw new CliError(outcome.invocationId ? `Approved, but execution failed: ${outcome.error}` : outcome.error || "Tool execution failed");
|
|
9743
9864
|
}
|
|
9744
9865
|
}
|
|
9745
|
-
function toolsVerbUsage(verb) {
|
|
9746
|
-
const lines = [];
|
|
9747
|
-
let inVerb = false;
|
|
9748
|
-
for (const line of toolsUsage.split("\n")) {
|
|
9749
|
-
if (/^ {2}\S/.test(line)) inVerb = line.trimStart().startsWith(`${verb} `);
|
|
9750
|
-
else if (!/^ {3,}\S/.test(line)) inVerb = false;
|
|
9751
|
-
if (inVerb) lines.push(line);
|
|
9752
|
-
}
|
|
9753
|
-
return lines.length ? `diverge tools ${verb} ...
|
|
9754
|
-
|
|
9755
|
-
${lines.join("\n")}
|
|
9756
|
-
|
|
9757
|
-
Every tools command takes --organization-id <id> (or DIVERGENT_ORG_ID, else the signed-in login's organization) and --project-id <id> (or DIVERGENT_PROJECT_ID).` : toolsUsage;
|
|
9758
|
-
}
|
|
9759
9866
|
async function runTools(args, io) {
|
|
9760
9867
|
const [verb, ...rest] = args;
|
|
9761
|
-
if (verb && (rest.includes("--help") || rest.includes("-h"))) {
|
|
9762
|
-
io.stdout(toolsVerbUsage(verb));
|
|
9763
|
-
return ExitCode.Ok;
|
|
9764
|
-
}
|
|
9765
9868
|
switch (verb) {
|
|
9766
9869
|
case "list": {
|
|
9767
9870
|
const { values } = parseArgs6({ args: rest, options: { ...SCOPE_OPTIONS, filter: { type: "string" }, capability: { type: "string" }, json: { type: "boolean", default: false } }, strict: true });
|
|
@@ -9844,9 +9947,7 @@ async function runTools(args, io) {
|
|
|
9844
9947
|
return serveBridge(new BridgeServer(tools, { tools: allow }), process.stdin, process.stdout);
|
|
9845
9948
|
}
|
|
9846
9949
|
default:
|
|
9847
|
-
throw
|
|
9848
|
-
|
|
9849
|
-
${toolsUsage}`);
|
|
9950
|
+
throw unknownVerb("tools", toolsUsage, [], verb, rest);
|
|
9850
9951
|
}
|
|
9851
9952
|
}
|
|
9852
9953
|
|
|
@@ -9900,20 +10001,8 @@ function formatPlugin(plugin) {
|
|
|
9900
10001
|
...plugin.refusals?.length ? [" NOT SERVED: the platform refuses this version; publish a fixed one:", ...plugin.refusals.map((reason) => ` - ${reason}`)] : []
|
|
9901
10002
|
];
|
|
9902
10003
|
}
|
|
9903
|
-
function pluginsVerbUsage(verb) {
|
|
9904
|
-
const lines = pluginsUsage.split("\n").filter((line) => line.trimStart().startsWith(`${verb} `));
|
|
9905
|
-
return lines.length ? `diverge plugins ${verb} ...
|
|
9906
|
-
|
|
9907
|
-
${lines.join("\n")}
|
|
9908
|
-
|
|
9909
|
-
Every plugins command takes --organization-id <id> (or DIVERGENT_ORG_ID, else the signed-in login's organization).` : pluginsUsage;
|
|
9910
|
-
}
|
|
9911
10004
|
async function runPlugins(args, io) {
|
|
9912
10005
|
const [verb, ...rest] = args;
|
|
9913
|
-
if (verb && (rest.includes("--help") || rest.includes("-h"))) {
|
|
9914
|
-
io.stdout(pluginsVerbUsage(verb));
|
|
9915
|
-
return ExitCode.Ok;
|
|
9916
|
-
}
|
|
9917
10006
|
switch (verb) {
|
|
9918
10007
|
case "validate": {
|
|
9919
10008
|
const { values, positionals } = parseArgs7({ args: rest, options: { ...SCOPE_OPTIONS2, json: { type: "boolean", default: false } }, allowPositionals: true, strict: true });
|
|
@@ -9971,9 +10060,7 @@ ${pluginsUsage}`);
|
|
|
9971
10060
|
return ExitCode.Ok;
|
|
9972
10061
|
}
|
|
9973
10062
|
default:
|
|
9974
|
-
throw
|
|
9975
|
-
|
|
9976
|
-
${pluginsUsage}`);
|
|
10063
|
+
throw unknownVerb("plugins", pluginsUsage, [], verb, rest);
|
|
9977
10064
|
}
|
|
9978
10065
|
}
|
|
9979
10066
|
|
|
@@ -10084,9 +10171,9 @@ function installLatest(version) {
|
|
|
10084
10171
|
|
|
10085
10172
|
// src/cli.ts
|
|
10086
10173
|
var COMMANDS = [
|
|
10087
|
-
{ name: "login", summary: "Sign in through the browser", usage: loginUsage, run: runLogin },
|
|
10174
|
+
{ name: "login", summary: "Sign in (authenticate) through the browser", usage: loginUsage, run: runLogin },
|
|
10088
10175
|
{ name: "logout", summary: "Revoke the login and forget it", usage: logoutUsage, run: runLogout },
|
|
10089
|
-
{ name: "status", summary: "Show the deployment and the
|
|
10176
|
+
{ name: "status", summary: "Show who you are signed in as: the deployment, the account and what the login carries", usage: statusUsage, run: runStatus },
|
|
10090
10177
|
{ name: "org", summary: "Show or switch the organization the login acts in", usage: orgUsage, run: runOrg },
|
|
10091
10178
|
{ name: "token", summary: "Print a fresh access token", usage: tokenUsage, run: runToken },
|
|
10092
10179
|
{ name: "agents", summary: "Point a coding agent at the model gateway (setup, run, status)", usage: agentsUsage, run: runAgents },
|
|
@@ -10122,15 +10209,19 @@ async function run2(argv, io) {
|
|
|
10122
10209
|
}
|
|
10123
10210
|
const command = COMMANDS.find((candidate) => candidate.name === name);
|
|
10124
10211
|
if (!command) {
|
|
10125
|
-
|
|
10212
|
+
const candidates = COMMANDS.map((known) => ({ invocation: `diverge ${known.name}`, name: known.name, summary: known.summary, lines: [known.summary] }));
|
|
10213
|
+
io.stderr(`Unknown command: ${name}.${didYouMean(closest(name, candidates, rest))}
|
|
10126
10214
|
|
|
10127
10215
|
${usage()}`);
|
|
10128
10216
|
return ExitCode.Failure;
|
|
10129
10217
|
}
|
|
10130
10218
|
const own = rest.includes("--") ? rest.slice(0, rest.indexOf("--")) : rest;
|
|
10131
|
-
if (
|
|
10132
|
-
|
|
10133
|
-
|
|
10219
|
+
if (own.includes("--help") || own.includes("-h")) {
|
|
10220
|
+
const path15 = verbPath(command.usage, own);
|
|
10221
|
+
if (path15.length > 0 || own[0].startsWith("-")) {
|
|
10222
|
+
io.stdout(verbUsage(command.name, command.usage, path15));
|
|
10223
|
+
return ExitCode.Ok;
|
|
10224
|
+
}
|
|
10134
10225
|
}
|
|
10135
10226
|
const code2 = await runCommand(command, rest, io);
|
|
10136
10227
|
updateNotice(argv, io);
|
|
@@ -10145,9 +10236,9 @@ async function runCommand(command, rest, io) {
|
|
|
10145
10236
|
return error.exitCode;
|
|
10146
10237
|
}
|
|
10147
10238
|
if (error instanceof Error && error.name === "TypeError" && /Unknown option|Option .* argument|Unexpected argument/.test(error.message)) {
|
|
10148
|
-
io.stderr(`Error: ${error.message}
|
|
10239
|
+
io.stderr(`Error: ${unknownOption(error, command.usage, rest) ?? error.message}
|
|
10149
10240
|
|
|
10150
|
-
${command.usage}`);
|
|
10241
|
+
${verbUsage(command.name, command.usage, verbPath(command.usage, rest))}`);
|
|
10151
10242
|
return ExitCode.Failure;
|
|
10152
10243
|
}
|
|
10153
10244
|
io.stderr(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
package/package.json
CHANGED