nexarch 0.14.0 → 0.15.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/README.md +69 -63
- package/dist/commands/enroll.js +28 -1
- package/dist/commands/setup.js +14 -17
- package/dist/commands/skills-update.js +51 -0
- package/dist/index.js +12 -2
- package/dist/lib/skills.js +10 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,63 +1,69 @@
|
|
|
1
|
-
# nexarch
|
|
2
|
-
|
|
3
|
-
Your architecture workspace for AI delivery.
|
|
4
|
-
|
|
5
|
-
## Quick start
|
|
6
|
-
|
|
7
|
-
```sh
|
|
8
|
-
npx nexarch login
|
|
9
|
-
npx nexarch setup
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
|
22
|
-
|
|
23
|
-
| `nexarch
|
|
24
|
-
| `nexarch
|
|
25
|
-
| `nexarch
|
|
26
|
-
| `nexarch
|
|
27
|
-
| `nexarch
|
|
28
|
-
| `nexarch
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
`nexarch init-agent`
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
1
|
+
# nexarch
|
|
2
|
+
|
|
3
|
+
Your architecture workspace for AI delivery.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npx nexarch login
|
|
9
|
+
npx nexarch setup
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
For browserless agent enrollment, use `npx nexarch enroll --code <code> --client <client>`.
|
|
13
|
+
Known clients receive their MCP connection configuration and Nexarch skills as part
|
|
14
|
+
of the same enrollment.
|
|
15
|
+
|
|
16
|
+
> `setup`, `mcp-config`, and `init-agent` are registry-driven and fail closed.
|
|
17
|
+
> If the published integration registry is unavailable/invalid, these commands stop until service is restored.
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
| Command | Description |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `nexarch login [--company <id>]` | Authenticate via browser and store company-scoped credentials; prompts for company when multiple memberships exist |
|
|
24
|
+
| `nexarch logout` | Remove local credentials |
|
|
25
|
+
| `nexarch status` | Check connection, registry health/version, and architecture summary for the company selected at login |
|
|
26
|
+
| `nexarch setup` | Auto-configure detected MCP clients, write instructions, and refresh all managed skills |
|
|
27
|
+
| `nexarch skills update` | Refresh all Nexarch-managed skills for installed agent runtimes |
|
|
28
|
+
| `nexarch enroll --code <code> --client <client>` | Redeem a one-time enrollment, configure the known client, and install its Nexarch skills |
|
|
29
|
+
| `nexarch mcp-config [client]` | Print config block for manual setup (supported client codes are registry-managed) |
|
|
30
|
+
| `nexarch mcp-proxy` | stdio→HTTP bridge used internally by MCP clients |
|
|
31
|
+
| `nexarch init-agent [--json] [--strict] [--agent-id <id>] [--redact-hostname]` | Run onboarding handshake and mandatory `agent` entity registration in graph |
|
|
32
|
+
| `nexarch init-agent --bind-to-external-key <key> [--bind-relationship-type <code>]` | Optionally bind the agent node to an existing graph external key |
|
|
33
|
+
| `nexarch init-agent` (default behavior) | Also upserts technology component entities (host, OS, Node.js runtime) and links them to the agent |
|
|
34
|
+
| `nexarch agent identify ...` | Submit provider/model/client identity metadata to complete agent profile enrichment |
|
|
35
|
+
|
|
36
|
+
## Bootstrap flow after `init-agent`
|
|
37
|
+
|
|
38
|
+
`nexarch init-agent` writes a bootstrap file at:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
~/.nexarch/agent-bootstrap.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
That file contains a pre-filled `npx nexarch agent identify ...` command template.
|
|
45
|
+
The current workflow is:
|
|
46
|
+
|
|
47
|
+
1. run `npx nexarch init-agent`
|
|
48
|
+
2. open `~/.nexarch/agent-bootstrap.md`
|
|
49
|
+
3. copy the generated `npx nexarch agent identify ...` template
|
|
50
|
+
4. fill in the real provider/model/client details
|
|
51
|
+
5. run the completed command
|
|
52
|
+
|
|
53
|
+
Do not assume an `npx nexarch agent prompt` command exists unless/until it is explicitly implemented and documented.
|
|
54
|
+
|
|
55
|
+
## Company context behavior
|
|
56
|
+
|
|
57
|
+
- Company is selected during `nexarch login`.
|
|
58
|
+
- If your user has one active company, login auto-selects it.
|
|
59
|
+
- If your user has multiple active companies, login requires explicit selection.
|
|
60
|
+
- To switch company later, run `nexarch login` again and pick another company.
|
|
61
|
+
|
|
62
|
+
## Requirements
|
|
63
|
+
|
|
64
|
+
- Node.js 18 or later
|
|
65
|
+
- A Nexarch workspace account
|
|
66
|
+
|
|
67
|
+
## Documentation
|
|
68
|
+
|
|
69
|
+
[nexarch.ai/docs/cli-reference](https://nexarch.ai/docs/cli-reference)
|
package/dist/commands/enroll.js
CHANGED
|
@@ -3,6 +3,8 @@ import { mkdirSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { expandHomePath, supportsAutoWrite, writeClientConfig } from "../lib/client-config-writers.js";
|
|
6
|
+
import { fetchAgentRegistryOrThrow } from "../lib/agent-registry.js";
|
|
7
|
+
import { installSkillsForRuntime } from "../lib/skills.js";
|
|
6
8
|
// Matches www.nexarch.ai — the default production host for the web app that
|
|
7
9
|
// owns /api/agent-enrollments/exchange. Not the same service as
|
|
8
10
|
// mcp.nexarch.ai (the MCP gateway); --host exists because staging and
|
|
@@ -36,6 +38,18 @@ function parseOptionValue(args, option) {
|
|
|
36
38
|
function redactedManifest(manifest) {
|
|
37
39
|
return { ...manifest, credential: { ...manifest.credential, token: "(redacted — see saved file, or pass --print-token)" } };
|
|
38
40
|
}
|
|
41
|
+
function skillRuntimeForClient(clientCode) {
|
|
42
|
+
switch (clientCode) {
|
|
43
|
+
case "claude-code":
|
|
44
|
+
return "claude-code";
|
|
45
|
+
case "codex-cli":
|
|
46
|
+
return "codex-cli";
|
|
47
|
+
case "hermes-agent":
|
|
48
|
+
return "hermes-agent";
|
|
49
|
+
default:
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
39
53
|
/**
|
|
40
54
|
* Bootstraps a headless (browserless) MCP agent by redeeming a one-time
|
|
41
55
|
* enrollment code for a long-lived credential — the CLI equivalent of the
|
|
@@ -95,9 +109,15 @@ export async function enroll(args) {
|
|
|
95
109
|
});
|
|
96
110
|
wroteClientConfig = true;
|
|
97
111
|
}
|
|
112
|
+
let skills = [];
|
|
113
|
+
const skillRuntime = skillRuntimeForClient(clientCode);
|
|
114
|
+
if (skillRuntime) {
|
|
115
|
+
const registry = await fetchAgentRegistryOrThrow();
|
|
116
|
+
skills = installSkillsForRuntime(registry, skillRuntime);
|
|
117
|
+
}
|
|
98
118
|
if (asJson) {
|
|
99
119
|
const output = printToken ? manifest : redactedManifest(manifest);
|
|
100
|
-
process.stdout.write(`${JSON.stringify({ ...output, wroteClientConfig }, null, 2)}\n`);
|
|
120
|
+
process.stdout.write(`${JSON.stringify({ ...output, wroteClientConfig, skills }, null, 2)}\n`);
|
|
101
121
|
return;
|
|
102
122
|
}
|
|
103
123
|
console.log(`✓ Enrolled agent ${manifest.agent.ref} in workspace "${manifest.workspace.name}"`);
|
|
@@ -114,6 +134,13 @@ export async function enroll(args) {
|
|
|
114
134
|
else {
|
|
115
135
|
console.log(`\nNo known auto-write target for client "${clientCode}" — connect it manually:`);
|
|
116
136
|
}
|
|
137
|
+
if (skills.length > 0) {
|
|
138
|
+
console.log(`\n${clientCode} skills:`);
|
|
139
|
+
for (const skill of skills) {
|
|
140
|
+
const verb = skill.status === "installed" ? "installed" : skill.status === "updated" ? "updated" : "already current";
|
|
141
|
+
console.log(` ${verb.padEnd(15)} ${skill.dirName}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
117
144
|
const shownToken = printToken ? manifest.credential.token : `<see ${destination}>`;
|
|
118
145
|
if (manifest.connectInstructionsTemplate) {
|
|
119
146
|
console.log(renderInstructions(manifest.connectInstructionsTemplate, manifest, shownToken, mcpEndpoint));
|
package/dist/commands/setup.js
CHANGED
|
@@ -3,7 +3,7 @@ import { requireCredentials } from "../lib/credentials.js";
|
|
|
3
3
|
import { detectClientsFromRegistry, writeClientConfig, nexarchServerBlockFromRegistry } from "../lib/clients.js";
|
|
4
4
|
import { fetchAgentRegistryOrThrow } from "../lib/agent-registry.js";
|
|
5
5
|
import { initAgent } from "./init-agent.js";
|
|
6
|
-
import { installSkillsForRuntime } from "../lib/skills.js";
|
|
6
|
+
import { installSkillsForRuntime, installedSkillRuntimes } from "../lib/skills.js";
|
|
7
7
|
import { login } from "./login.js";
|
|
8
8
|
function argValue(args, flag) {
|
|
9
9
|
const idx = args.indexOf(flag);
|
|
@@ -168,22 +168,19 @@ export async function setup(args) {
|
|
|
168
168
|
initAgentArgs.push("--instruction-runtime-targets", instructionRuntimeTargets.join(","));
|
|
169
169
|
}
|
|
170
170
|
await initAgent(initAgentArgs);
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
for (const { clientCode, runtime, label } of skillRuntimes) {
|
|
185
|
-
if (!clients.some((client) => client.code === clientCode))
|
|
186
|
-
continue;
|
|
171
|
+
// Refresh every installed skill-capable runtime, not only MCP clients
|
|
172
|
+
// detected in this setup pass. This keeps `setup` useful for existing
|
|
173
|
+
// installations and gives it the same managed-skill behavior as
|
|
174
|
+
// `nexarch skills update`.
|
|
175
|
+
const skillRuntimes = new Set(installedSkillRuntimes());
|
|
176
|
+
for (const client of clients) {
|
|
177
|
+
if (client.code === "claude-code")
|
|
178
|
+
skillRuntimes.add("claude-code");
|
|
179
|
+
if (client.code === "codex-cli")
|
|
180
|
+
skillRuntimes.add("codex-cli");
|
|
181
|
+
}
|
|
182
|
+
for (const runtime of skillRuntimes) {
|
|
183
|
+
const label = runtime === "claude-code" ? "Claude Code" : runtime === "codex-cli" ? "Codex CLI" : "Hermes Agent";
|
|
187
184
|
try {
|
|
188
185
|
const skills = installSkillsForRuntime(registry, runtime);
|
|
189
186
|
const anyChanged = skills.some((s) => s.status !== "already_current");
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { requireCredentials } from "../lib/credentials.js";
|
|
2
|
+
import { fetchAgentRegistryOrThrow } from "../lib/agent-registry.js";
|
|
3
|
+
import { installSkillsForRuntime, installedSkillRuntimes } from "../lib/skills.js";
|
|
4
|
+
const RUNTIME_LABELS = {
|
|
5
|
+
"claude-code": "Claude Code",
|
|
6
|
+
"codex-cli": "Codex CLI",
|
|
7
|
+
"hermes-agent": "Hermes Agent",
|
|
8
|
+
};
|
|
9
|
+
function hasFlag(args, flag) {
|
|
10
|
+
return args.includes(flag);
|
|
11
|
+
}
|
|
12
|
+
export async function skillsUpdate(args) {
|
|
13
|
+
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
14
|
+
console.log(`
|
|
15
|
+
Usage:
|
|
16
|
+
nexarch skills update [--json]
|
|
17
|
+
|
|
18
|
+
Refresh all Nexarch-managed skills for installed agent runtimes.
|
|
19
|
+
`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const asJson = hasFlag(args, "--json");
|
|
23
|
+
requireCredentials();
|
|
24
|
+
const registry = await fetchAgentRegistryOrThrow();
|
|
25
|
+
const runtimes = installedSkillRuntimes();
|
|
26
|
+
const results = [];
|
|
27
|
+
for (const runtime of runtimes) {
|
|
28
|
+
results.push({
|
|
29
|
+
runtime,
|
|
30
|
+
label: RUNTIME_LABELS[runtime],
|
|
31
|
+
skills: installSkillsForRuntime(registry, runtime),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (asJson) {
|
|
35
|
+
process.stdout.write(`${JSON.stringify({ registryVersion: registry.release.version, runtimes: results }, null, 2)}\n`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
console.log(`Using integration registry release v${registry.release.version}.`);
|
|
39
|
+
if (results.length === 0) {
|
|
40
|
+
console.log("No installed Nexarch skill runtimes found.");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
for (const result of results) {
|
|
44
|
+
console.log(`\n${result.label} skills:`);
|
|
45
|
+
for (const skill of result.skills) {
|
|
46
|
+
const verb = skill.status === "installed" ? "installed" : skill.status === "updated" ? "updated" : "already current";
|
|
47
|
+
console.log(` ${verb.padEnd(15)} ${skill.dirName}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
console.log("\nNexarch-managed skills refreshed.");
|
|
51
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { enroll } from "./commands/enroll.js";
|
|
|
4
4
|
import { logout } from "./commands/logout.js";
|
|
5
5
|
import { status } from "./commands/status.js";
|
|
6
6
|
import { setup } from "./commands/setup.js";
|
|
7
|
+
import { skillsUpdate } from "./commands/skills-update.js";
|
|
7
8
|
import { mcpConfig } from "./commands/mcp-config.js";
|
|
8
9
|
import { mcpProxy } from "./commands/mcp-proxy.js";
|
|
9
10
|
import { initAgent } from "./commands/init-agent.js";
|
|
@@ -82,6 +83,13 @@ async function main() {
|
|
|
82
83
|
return;
|
|
83
84
|
}
|
|
84
85
|
}
|
|
86
|
+
if (command === "skills") {
|
|
87
|
+
const [subcommand, ...subArgs] = args;
|
|
88
|
+
if (subcommand === "update") {
|
|
89
|
+
await skillsUpdate(subArgs);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
85
93
|
if (command === "proposals") {
|
|
86
94
|
const [subcommand, ...subArgs] = args;
|
|
87
95
|
if (subcommand === "start") {
|
|
@@ -119,8 +127,8 @@ Usage:
|
|
|
119
127
|
credential to ~/.nexarch/agent-credential.json (mode 600)
|
|
120
128
|
rather than printing it. For a client with a known config
|
|
121
129
|
format (e.g. hermes-agent), also writes the connection
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
and installs its Nexarch skills; for anything else,
|
|
131
|
+
prints instructions instead.
|
|
124
132
|
Options: --code <code> (required, starts with nxe_)
|
|
125
133
|
--client <code> (required, e.g. hermes-agent)
|
|
126
134
|
--client-version <v>
|
|
@@ -141,6 +149,8 @@ Usage:
|
|
|
141
149
|
Options: --company <id|code> target a workspace directly
|
|
142
150
|
--yes accept the stored workspace without asking
|
|
143
151
|
--no-browser log in by pasting a one-time code (see login)
|
|
152
|
+
nexarch skills update
|
|
153
|
+
Refresh all Nexarch-managed skills for installed agent runtimes
|
|
144
154
|
nexarch mcp-config Print MCP server config block for manual setup
|
|
145
155
|
Client list is registry-managed (see 'nexarch mcp-config --client <code>')
|
|
146
156
|
nexarch mcp-proxy Run as stdio MCP proxy (used by MCP clients)
|
package/dist/lib/skills.js
CHANGED
|
@@ -408,7 +408,16 @@ export const SKILLS = [
|
|
|
408
408
|
const RUNTIME_SKILLS_ROOT = {
|
|
409
409
|
"claude-code": [".claude", "skills"],
|
|
410
410
|
"codex-cli": [".agents", "skills"],
|
|
411
|
+
"hermes-agent": [".hermes", "skills"],
|
|
411
412
|
};
|
|
413
|
+
export function skillRootForRuntime(runtime, homeDir = homedir()) {
|
|
414
|
+
return runtime === "hermes-agent" && process.env.HERMES_HOME
|
|
415
|
+
? join(process.env.HERMES_HOME, "skills")
|
|
416
|
+
: join(homeDir, ...RUNTIME_SKILLS_ROOT[runtime]);
|
|
417
|
+
}
|
|
418
|
+
export function installedSkillRuntimes(homeDir = homedir()) {
|
|
419
|
+
return Object.keys(RUNTIME_SKILLS_ROOT).filter((runtime) => existsSync(skillRootForRuntime(runtime, homeDir)));
|
|
420
|
+
}
|
|
412
421
|
function installSkill(spec, registry, skillsRoot) {
|
|
413
422
|
const template = registry.instructionTemplates.find((t) => t.code === spec.templateCode);
|
|
414
423
|
const body = template ? template.body.trim() + "\n" : spec.fallbackBody;
|
|
@@ -428,7 +437,6 @@ function installSkill(spec, registry, skillsRoot) {
|
|
|
428
437
|
return { dirName: spec.dirName, path: skillPath, status: "installed", source };
|
|
429
438
|
}
|
|
430
439
|
export function installSkillsForRuntime(registry, runtime, options = {}) {
|
|
431
|
-
const
|
|
432
|
-
const skillsRoot = join(homeDir, ...RUNTIME_SKILLS_ROOT[runtime]);
|
|
440
|
+
const skillsRoot = skillRootForRuntime(runtime, options.homeDir ?? homedir());
|
|
433
441
|
return SKILLS.map((spec) => installSkill(spec, registry, skillsRoot));
|
|
434
442
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexarch",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Your architecture workspace for AI delivery.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nexarch",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"prepublishOnly": "tsc",
|
|
27
27
|
"dev": "tsx src/index.ts",
|
|
28
28
|
"typecheck": "tsc --noEmit",
|
|
29
|
-
"test": "tsx scripts/test-mcp-proxy-response.ts && tsx scripts/test-trust-reattest.ts && tsx scripts/test-similar-applications.ts && tsx scripts/test-iac-tool.ts && tsx scripts/test-ansible.ts && tsx scripts/test-reference-sightings.ts && tsx scripts/test-search-icons.ts && tsx scripts/test-paste-login.ts && tsx scripts/test-credentials-resolution.ts"
|
|
29
|
+
"test": "tsx scripts/test-mcp-proxy-response.ts && tsx scripts/test-trust-reattest.ts && tsx scripts/test-similar-applications.ts && tsx scripts/test-iac-tool.ts && tsx scripts/test-ansible.ts && tsx scripts/test-reference-sightings.ts && tsx scripts/test-search-icons.ts && tsx scripts/test-paste-login.ts && tsx scripts/test-credentials-resolution.ts && tsx scripts/test-hermes-skills.ts"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^22",
|