nexarch 0.12.7 → 0.12.8
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/commands/setup.js +85 -1
- package/dist/index.js +4 -0
- package/package.json +1 -1
package/dist/commands/setup.js
CHANGED
|
@@ -1,9 +1,93 @@
|
|
|
1
|
+
import { createInterface } from "readline";
|
|
1
2
|
import { requireCredentials } from "../lib/credentials.js";
|
|
2
3
|
import { detectClientsFromRegistry, writeClientConfig, nexarchServerBlockFromRegistry } from "../lib/clients.js";
|
|
3
4
|
import { fetchAgentRegistryOrThrow } from "../lib/agent-registry.js";
|
|
4
5
|
import { initAgent } from "./init-agent.js";
|
|
5
6
|
import { installClaudeCodeSkill } from "../lib/skills.js";
|
|
6
7
|
import { login } from "./login.js";
|
|
8
|
+
function argValue(args, flag) {
|
|
9
|
+
const idx = args.indexOf(flag);
|
|
10
|
+
if (idx === -1)
|
|
11
|
+
return null;
|
|
12
|
+
const value = args[idx + 1];
|
|
13
|
+
return !value || value.startsWith("--") ? null : value;
|
|
14
|
+
}
|
|
15
|
+
/** Drops a flag and the value that belongs to it, so neither is left orphaned. */
|
|
16
|
+
function withoutFlag(args, flag) {
|
|
17
|
+
const idx = args.indexOf(flag);
|
|
18
|
+
if (idx === -1)
|
|
19
|
+
return args;
|
|
20
|
+
const takesValue = args[idx + 1] && !args[idx + 1].startsWith("--");
|
|
21
|
+
return [...args.slice(0, idx), ...args.slice(idx + (takesValue ? 2 : 1))];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Builds the argument list for a login triggered from setup.
|
|
25
|
+
*
|
|
26
|
+
* `login` speaks only `--company`, so `--workspace` is translated rather than
|
|
27
|
+
* passed through to be silently dropped by the flag it does not recognise.
|
|
28
|
+
*/
|
|
29
|
+
function loginArgs(args, company) {
|
|
30
|
+
const base = withoutFlag(withoutFlag(args, "--company"), "--workspace");
|
|
31
|
+
return company ? [...base, "--company", company] : base;
|
|
32
|
+
}
|
|
33
|
+
async function askYesNo(question) {
|
|
34
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
35
|
+
try {
|
|
36
|
+
const answer = await new Promise((resolve) => rl.question(`${question} [Y/n] `, resolve));
|
|
37
|
+
return !/^n(o)?$/i.test(answer.trim());
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
rl.close();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Settles which workspace setup is about to write to, out loud.
|
|
45
|
+
*
|
|
46
|
+
* Setup reuses a stored session when one exists, which is right — nobody wants
|
|
47
|
+
* to re-authenticate to reconfigure a client. But the workspace that session is
|
|
48
|
+
* scoped to was chosen at login, possibly weeks ago and in another repository,
|
|
49
|
+
* and setup never said which one it was. Running it in a new repo after
|
|
50
|
+
* creating a new workspace therefore succeeded loudly and wired everything to
|
|
51
|
+
* the old workspace: fourteen green ticks, not one of them naming the target.
|
|
52
|
+
*
|
|
53
|
+
* The browser consent screen already has a workspace picker for accounts with
|
|
54
|
+
* more than one membership, so switching is a matter of routing back through
|
|
55
|
+
* login rather than building a second picker here. The CLI deliberately does
|
|
56
|
+
* not enumerate workspaces itself: its token is scoped to one company, and a
|
|
57
|
+
* token for company A should not be able to list company B.
|
|
58
|
+
*/
|
|
59
|
+
async function confirmWorkspace(args, credentials) {
|
|
60
|
+
const requested = argValue(args, "--company") ?? argValue(args, "--workspace");
|
|
61
|
+
const current = credentials.company || credentials.companyCode || credentials.companyId;
|
|
62
|
+
const matchesRequest = !requested ||
|
|
63
|
+
requested === credentials.companyId ||
|
|
64
|
+
requested.toLowerCase() === (credentials.companyCode ?? "").toLowerCase() ||
|
|
65
|
+
requested.toLowerCase() === (credentials.company ?? "").toLowerCase();
|
|
66
|
+
// An explicit --company that the stored session does not satisfy must never
|
|
67
|
+
// be quietly ignored: the caller stated a target, and setup writes files.
|
|
68
|
+
if (!matchesRequest) {
|
|
69
|
+
console.log(`Stored session is for workspace "${current}", but --company ${requested} was requested.`);
|
|
70
|
+
console.log("Re-authenticating to switch workspace…\n");
|
|
71
|
+
await login(loginArgs(args, requested));
|
|
72
|
+
return requireCredentials();
|
|
73
|
+
}
|
|
74
|
+
console.log(`\nWorkspace: ${current}`);
|
|
75
|
+
const nonInteractive = args.includes("--non-interactive") || args.includes("--yes") || !process.stdin.isTTY;
|
|
76
|
+
if (nonInteractive) {
|
|
77
|
+
console.log("Everything below is registered here. Pass --company <id> to target a different workspace.\n");
|
|
78
|
+
return credentials;
|
|
79
|
+
}
|
|
80
|
+
console.log("Everything below — MCP client config, agent registration, instruction files — is registered here.");
|
|
81
|
+
if (await askYesNo("Continue with this workspace?"))
|
|
82
|
+
return credentials;
|
|
83
|
+
// No company is forwarded: the browser consent screen lists every workspace
|
|
84
|
+
// the account belongs to, which is the point of coming back here.
|
|
85
|
+
console.log("\nSwitching workspace — choose one in the browser…\n");
|
|
86
|
+
await login(loginArgs(args, null));
|
|
87
|
+
const switched = requireCredentials();
|
|
88
|
+
console.log(`\nWorkspace: ${switched.company || switched.companyId}\n`);
|
|
89
|
+
return switched;
|
|
90
|
+
}
|
|
7
91
|
function instructionRuntimeCodeForClient(code) {
|
|
8
92
|
switch (code) {
|
|
9
93
|
case "continue-dev":
|
|
@@ -27,7 +111,7 @@ export async function setup(args) {
|
|
|
27
111
|
console.log("No active Nexarch session found. Starting login flow…\n");
|
|
28
112
|
await login(args);
|
|
29
113
|
}
|
|
30
|
-
requireCredentials(); // ensure login succeeded
|
|
114
|
+
await confirmWorkspace(args, requireCredentials()); // ensure login succeeded, and name the target
|
|
31
115
|
let registry;
|
|
32
116
|
try {
|
|
33
117
|
registry = await fetchAgentRegistryOrThrow();
|
package/dist/index.js
CHANGED
|
@@ -84,6 +84,10 @@ Usage:
|
|
|
84
84
|
nexarch logout Remove stored credentials
|
|
85
85
|
nexarch status Check connection and show architecture summary
|
|
86
86
|
nexarch setup One-step onboarding: login (if needed) + MCP config + register agent
|
|
87
|
+
Names the workspace it will write to and confirms it before
|
|
88
|
+
registering anything; answer 'n' to pick a different one.
|
|
89
|
+
Options: --company <id|code> target a workspace directly
|
|
90
|
+
--yes accept the stored workspace without asking
|
|
87
91
|
nexarch mcp-config Print MCP server config block for manual setup
|
|
88
92
|
Client list is registry-managed (see 'nexarch mcp-config --client <code>')
|
|
89
93
|
nexarch mcp-proxy Run as stdio MCP proxy (used by MCP clients)
|