@intent-systems/nexus 2026.1.5-3 → 2026.1.5-5

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.
Files changed (144) hide show
  1. package/dist/agents/agent-id.js +41 -0
  2. package/dist/agents/auth-profiles.js +114 -25
  3. package/dist/agents/identity-state.js +79 -0
  4. package/dist/agents/model-auth.js +1 -0
  5. package/dist/agents/model-fallback.js +15 -9
  6. package/dist/agents/model-selection.js +1 -1
  7. package/dist/agents/models-config.js +17 -11
  8. package/dist/agents/pi-embedded-runner.js +101 -9
  9. package/dist/agents/sandbox.js +12 -3
  10. package/dist/agents/skill-runner.js +29 -4
  11. package/dist/agents/skill-usage.js +114 -11
  12. package/dist/agents/skills-status.js +4 -4
  13. package/dist/agents/skills.js +18 -7
  14. package/dist/agents/subagent-registry.js +25 -11
  15. package/dist/agents/system-prompt.js +16 -0
  16. package/dist/agents/tool-policy.js +19 -3
  17. package/dist/agents/tools/browser-tool.js +5 -2
  18. package/dist/agents/tools/image-tool.js +93 -8
  19. package/dist/agents/tools/sessions-announce-target.js +5 -1
  20. package/dist/agents/workspace.js +55 -46
  21. package/dist/auto-reply/command-detection.js +2 -1
  22. package/dist/auto-reply/reply/directive-handling.js +153 -28
  23. package/dist/auto-reply/reply/directives.js +17 -2
  24. package/dist/auto-reply/reply/model-selection.js +8 -3
  25. package/dist/auto-reply/reply/queue.js +2 -2
  26. package/dist/auto-reply/reply.js +1 -1
  27. package/dist/auto-reply/thinking.js +15 -0
  28. package/dist/browser/chrome.js +1 -1
  29. package/dist/browser/client.js +2 -0
  30. package/dist/browser/config.js +6 -2
  31. package/dist/browser/pw-tools-core.js +3 -0
  32. package/dist/browser/routes/agent.js +14 -0
  33. package/dist/canvas-host/server.js +1 -1
  34. package/dist/capabilities/detector.js +245 -0
  35. package/dist/capabilities/registry.js +99 -0
  36. package/dist/channels/location.js +44 -0
  37. package/dist/channels/web/index.js +2 -0
  38. package/dist/cli/cloud-cli.js +12 -7
  39. package/dist/cli/credential-cli.js +139 -17
  40. package/dist/cli/gateway-cli.js +1 -1
  41. package/dist/cli/log-cli.js +25 -0
  42. package/dist/cli/pairing-cli.js +1 -1
  43. package/dist/cli/program.js +58 -6
  44. package/dist/cli/run-main.js +1 -1
  45. package/dist/cli/skills-cli.js +144 -21
  46. package/dist/cli/skills-hub-cli.js +59 -29
  47. package/dist/cli/tool-connector-cli.js +99 -24
  48. package/dist/cli/upstream-sync-cli.js +253 -96
  49. package/dist/cli/usage-cli.js +14 -0
  50. package/dist/commands/auth-choice-options.js +6 -1
  51. package/dist/commands/auth-choice.js +157 -5
  52. package/dist/commands/bootstrap-preset.js +10 -6
  53. package/dist/commands/capabilities.js +33 -6
  54. package/dist/commands/claude-md.js +3 -2
  55. package/dist/commands/config-view.js +1 -1
  56. package/dist/commands/configure.js +4 -4
  57. package/dist/commands/credential.js +497 -36
  58. package/dist/commands/cursor-rules.js +39 -19
  59. package/dist/commands/doctor.js +5 -4
  60. package/dist/commands/identity.js +28 -31
  61. package/dist/commands/init.js +15 -18
  62. package/dist/commands/log.js +134 -0
  63. package/dist/commands/models/fallbacks.js +1 -1
  64. package/dist/commands/models/image-fallbacks.js +1 -1
  65. package/dist/commands/models/list.js +1 -1
  66. package/dist/commands/models/scan.js +1 -1
  67. package/dist/commands/onboard-auth.js +27 -2
  68. package/dist/commands/onboard-eve-identity.js +7 -8
  69. package/dist/commands/onboard-non-interactive.js +4 -2
  70. package/dist/commands/onboard-quickstart.js +18 -11
  71. package/dist/commands/quest-state.js +271 -0
  72. package/dist/commands/quest.js +53 -13
  73. package/dist/commands/reset.js +1 -1
  74. package/dist/commands/sessions-ingest.js +5 -4
  75. package/dist/commands/setup.js +4 -2
  76. package/dist/commands/skills-manifest.js +2 -2
  77. package/dist/commands/status.js +179 -61
  78. package/dist/commands/suggestions.js +1 -1
  79. package/dist/commands/usage-tracking.js +32 -0
  80. package/dist/commands/usage-upload.js +6 -1
  81. package/dist/config/defaults.js +1 -3
  82. package/dist/config/includes.js +5 -7
  83. package/dist/config/io.js +88 -16
  84. package/dist/config/legacy.js +4 -2
  85. package/dist/config/paths.js +16 -0
  86. package/dist/config/sessions.js +9 -5
  87. package/dist/config/zod-schema.js +4 -3
  88. package/dist/control-plane/broker/broker.js +1022 -0
  89. package/dist/control-plane/compaction.js +282 -0
  90. package/dist/control-plane/factory.js +31 -0
  91. package/dist/control-plane/index.js +10 -0
  92. package/dist/control-plane/odu/agents.js +192 -0
  93. package/dist/control-plane/odu/interaction-tools.js +208 -0
  94. package/dist/control-plane/odu/prompt-loader.js +95 -0
  95. package/dist/control-plane/odu/runtime.js +479 -0
  96. package/dist/control-plane/odu/types.js +6 -0
  97. package/dist/control-plane/odu-control-plane.js +316 -0
  98. package/dist/control-plane/single-agent.js +249 -0
  99. package/dist/control-plane/types.js +11 -0
  100. package/dist/credentials/store.js +449 -0
  101. package/dist/gateway/server-browser.js +5 -4
  102. package/dist/gateway/server-methods/cron.js +11 -1
  103. package/dist/gateway/server.js +14 -7
  104. package/dist/infra/bonjour.js +1 -1
  105. package/dist/infra/event-log.js +8 -2
  106. package/dist/infra/path-env.js +1 -2
  107. package/dist/infra/provider-usage.auth.js +5 -3
  108. package/dist/infra/provider-usage.fetch.claude.js +16 -6
  109. package/dist/infra/provider-usage.fetch.minimax.js +8 -3
  110. package/dist/infra/provider-usage.js +9 -5
  111. package/dist/infra/restart.js +2 -2
  112. package/dist/infra/usage-settings.js +78 -0
  113. package/dist/infra/usage-suggestions.js +17 -5
  114. package/dist/infra/usage-upload.js +38 -1
  115. package/dist/infra/voicewake.js +2 -2
  116. package/dist/logging/redact.js +109 -0
  117. package/dist/markdown/fences.js +58 -0
  118. package/dist/media/image-ops.js +3 -1
  119. package/dist/memory/embeddings.js +146 -0
  120. package/dist/memory/index.js +3 -0
  121. package/dist/memory/internal.js +163 -0
  122. package/dist/pairing/pairing-store.js +218 -0
  123. package/dist/plugins/cli.js +42 -0
  124. package/dist/plugins/discovery.js +253 -0
  125. package/dist/plugins/install.js +181 -0
  126. package/dist/plugins/loader.js +290 -0
  127. package/dist/plugins/registry.js +105 -0
  128. package/dist/plugins/status.js +29 -0
  129. package/dist/plugins/tools.js +39 -0
  130. package/dist/plugins/types.js +1 -0
  131. package/dist/providers/github-copilot-auth.js +1 -1
  132. package/dist/routing/resolve-route.js +144 -0
  133. package/dist/routing/session-key.js +65 -0
  134. package/dist/sessions/send-policy.js +5 -5
  135. package/dist/slack/monitor.js +22 -1
  136. package/dist/telegram/reaction-level.js +2 -1
  137. package/dist/utils/provider-utils.js +28 -0
  138. package/dist/utils.js +4 -3
  139. package/dist/wizard/onboarding.js +29 -7
  140. package/package.json +4 -29
  141. package/patches/@mariozechner__pi-ai.patch +215 -0
  142. package/patches/playwright-core@1.57.0.patch +13 -0
  143. package/patches/qrcode-terminal.patch +12 -0
  144. package/scripts/postinstall.js +202 -0
@@ -0,0 +1,144 @@
1
+ import { buildAgentMainSessionKey, buildAgentPeerSessionKey, DEFAULT_ACCOUNT_ID, DEFAULT_AGENT_ID, DEFAULT_MAIN_KEY, normalizeAgentId, } from "./session-key.js";
2
+ export { DEFAULT_ACCOUNT_ID, DEFAULT_AGENT_ID } from "./session-key.js";
3
+ function normalizeToken(value) {
4
+ return (value ?? "").trim().toLowerCase();
5
+ }
6
+ function normalizeId(value) {
7
+ return (value ?? "").trim();
8
+ }
9
+ function normalizeAccountId(value) {
10
+ const trimmed = (value ?? "").trim();
11
+ return trimmed ? trimmed : DEFAULT_ACCOUNT_ID;
12
+ }
13
+ function matchesAccountId(match, actual) {
14
+ const trimmed = (match ?? "").trim();
15
+ if (!trimmed)
16
+ return actual === DEFAULT_ACCOUNT_ID;
17
+ if (trimmed === "*")
18
+ return true;
19
+ return trimmed === actual;
20
+ }
21
+ export function buildAgentSessionKey(params) {
22
+ const provider = normalizeToken(params.provider) || "unknown";
23
+ const peer = params.peer;
24
+ return buildAgentPeerSessionKey({
25
+ agentId: params.agentId,
26
+ mainKey: DEFAULT_MAIN_KEY,
27
+ channel: provider,
28
+ peerKind: peer?.kind ?? "dm",
29
+ peerId: peer ? normalizeId(peer.id) || "unknown" : null,
30
+ });
31
+ }
32
+ function listBindings(cfg) {
33
+ const bindings = cfg.routing?.bindings;
34
+ return Array.isArray(bindings) ? bindings : [];
35
+ }
36
+ function listAgents(cfg) {
37
+ const agents = cfg.routing?.agents;
38
+ return agents && typeof agents === "object" ? agents : undefined;
39
+ }
40
+ function resolveDefaultAgentId(cfg) {
41
+ const explicit = cfg.routing?.defaultAgentId?.trim();
42
+ if (explicit)
43
+ return explicit;
44
+ return DEFAULT_AGENT_ID;
45
+ }
46
+ function pickFirstExistingAgentId(cfg, agentId) {
47
+ const normalized = normalizeAgentId(agentId);
48
+ const agents = listAgents(cfg);
49
+ if (!agents)
50
+ return normalized;
51
+ if (Object.hasOwn(agents, normalized))
52
+ return normalized;
53
+ return normalizeAgentId(resolveDefaultAgentId(cfg));
54
+ }
55
+ function matchesChannel(match, channel) {
56
+ const key = normalizeToken(match?.channel);
57
+ if (!key)
58
+ return false;
59
+ return key === channel;
60
+ }
61
+ function matchesPeer(match, peer) {
62
+ const m = match?.peer;
63
+ if (!m)
64
+ return false;
65
+ const kind = normalizeToken(m.kind);
66
+ const id = normalizeId(m.id);
67
+ if (!kind || !id)
68
+ return false;
69
+ return kind === peer.kind && id === peer.id;
70
+ }
71
+ function matchesGuild(match, guildId) {
72
+ const id = normalizeId(match?.guildId);
73
+ if (!id)
74
+ return false;
75
+ return id === guildId;
76
+ }
77
+ function matchesTeam(match, teamId) {
78
+ const id = normalizeId(match?.teamId);
79
+ if (!id)
80
+ return false;
81
+ return id === teamId;
82
+ }
83
+ export function resolveAgentRoute(input) {
84
+ const provider = normalizeToken(input.provider ?? input.channel);
85
+ const accountId = normalizeAccountId(input.accountId);
86
+ const peer = input.peer
87
+ ? { kind: input.peer.kind, id: normalizeId(input.peer.id) }
88
+ : null;
89
+ const guildId = normalizeId(input.guildId);
90
+ const teamId = normalizeId(input.teamId);
91
+ const bindings = listBindings(input.cfg).filter((binding) => {
92
+ if (!binding || typeof binding !== "object")
93
+ return false;
94
+ if (!matchesChannel(binding.match, provider))
95
+ return false;
96
+ return matchesAccountId(binding.match?.accountId, accountId);
97
+ });
98
+ const choose = (agentId, matchedBy) => {
99
+ const resolvedAgentId = pickFirstExistingAgentId(input.cfg, agentId);
100
+ return {
101
+ agentId: resolvedAgentId,
102
+ provider,
103
+ accountId,
104
+ sessionKey: buildAgentSessionKey({
105
+ agentId: resolvedAgentId,
106
+ provider,
107
+ peer,
108
+ }),
109
+ mainSessionKey: buildAgentMainSessionKey({
110
+ agentId: resolvedAgentId,
111
+ mainKey: DEFAULT_MAIN_KEY,
112
+ }),
113
+ matchedBy,
114
+ };
115
+ };
116
+ if (peer) {
117
+ const peerMatch = bindings.find((b) => matchesPeer(b.match, peer));
118
+ if (peerMatch)
119
+ return choose(peerMatch.agentId, "binding.peer");
120
+ }
121
+ if (guildId) {
122
+ const guildMatch = bindings.find((b) => matchesGuild(b.match, guildId));
123
+ if (guildMatch)
124
+ return choose(guildMatch.agentId, "binding.guild");
125
+ }
126
+ if (teamId) {
127
+ const teamMatch = bindings.find((b) => matchesTeam(b.match, teamId));
128
+ if (teamMatch)
129
+ return choose(teamMatch.agentId, "binding.team");
130
+ }
131
+ const accountMatch = bindings.find((b) => b.match?.accountId?.trim() !== "*" &&
132
+ !b.match?.peer &&
133
+ !b.match?.guildId &&
134
+ !b.match?.teamId);
135
+ if (accountMatch)
136
+ return choose(accountMatch.agentId, "binding.account");
137
+ const anyAccountMatch = bindings.find((b) => b.match?.accountId?.trim() === "*" &&
138
+ !b.match?.peer &&
139
+ !b.match?.guildId &&
140
+ !b.match?.teamId);
141
+ if (anyAccountMatch)
142
+ return choose(anyAccountMatch.agentId, "binding.channel");
143
+ return choose(resolveDefaultAgentId(input.cfg), "default");
144
+ }
@@ -0,0 +1,65 @@
1
+ export const DEFAULT_AGENT_ID = "default";
2
+ export const DEFAULT_MAIN_KEY = "main";
3
+ export const DEFAULT_ACCOUNT_ID = "default";
4
+ export function normalizeAgentId(value) {
5
+ const trimmed = (value ?? "").trim();
6
+ if (!trimmed)
7
+ return DEFAULT_AGENT_ID;
8
+ // Keep it path-safe + shell-friendly.
9
+ if (/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(trimmed))
10
+ return trimmed;
11
+ // Best-effort fallback: collapse invalid characters to "-"
12
+ return (trimmed
13
+ .toLowerCase()
14
+ .replace(/[^a-z0-9_-]+/g, "-")
15
+ .replace(/^-+/, "")
16
+ .replace(/-+$/, "")
17
+ .slice(0, 64) || DEFAULT_AGENT_ID);
18
+ }
19
+ export function parseAgentSessionKey(sessionKey) {
20
+ const raw = (sessionKey ?? "").trim();
21
+ if (!raw)
22
+ return null;
23
+ const parts = raw.split(":").filter(Boolean);
24
+ if (parts.length < 3)
25
+ return null;
26
+ if (parts[0] !== "agent")
27
+ return null;
28
+ const agentId = parts[1]?.trim();
29
+ const rest = parts.slice(2).join(":");
30
+ if (!agentId || !rest)
31
+ return null;
32
+ return { agentId, rest };
33
+ }
34
+ export function resolveAgentIdFromSessionKey(sessionKey) {
35
+ const parsed = parseAgentSessionKey(sessionKey);
36
+ return normalizeAgentId(parsed?.agentId ?? DEFAULT_AGENT_ID);
37
+ }
38
+ export function isSubagentSessionKey(sessionKey) {
39
+ const raw = (sessionKey ?? "").trim();
40
+ if (!raw)
41
+ return false;
42
+ if (raw.toLowerCase().startsWith("subagent:"))
43
+ return true;
44
+ const parsed = parseAgentSessionKey(raw);
45
+ return Boolean((parsed?.rest ?? "").toLowerCase().startsWith("subagent:"));
46
+ }
47
+ export function buildAgentMainSessionKey(params) {
48
+ const agentId = normalizeAgentId(params.agentId);
49
+ const mainKey = (params.mainKey ?? DEFAULT_MAIN_KEY).trim() || DEFAULT_MAIN_KEY;
50
+ return `agent:${agentId}:${mainKey}`;
51
+ }
52
+ export function buildAgentPeerSessionKey(params) {
53
+ const peerKind = params.peerKind ?? "dm";
54
+ if (peerKind === "dm") {
55
+ return buildAgentMainSessionKey({
56
+ agentId: params.agentId,
57
+ mainKey: params.mainKey,
58
+ });
59
+ }
60
+ const provider = (params.channel ?? params.provider ?? "")
61
+ .trim()
62
+ .toLowerCase() || "unknown";
63
+ const peerId = (params.peerId ?? "").trim() || "unknown";
64
+ return `agent:${normalizeAgentId(params.agentId)}:${provider}:${peerKind}:${peerId}`;
65
+ }
@@ -10,7 +10,7 @@ function normalizeMatchValue(raw) {
10
10
  const value = raw?.trim().toLowerCase();
11
11
  return value ? value : undefined;
12
12
  }
13
- function deriveProviderFromKey(key) {
13
+ function deriveChannelFromKey(key) {
14
14
  if (!key)
15
15
  return undefined;
16
16
  const parts = key.split(":").filter(Boolean);
@@ -35,10 +35,10 @@ export function resolveSendPolicy(params) {
35
35
  const policy = params.cfg.session?.sendPolicy;
36
36
  if (!policy)
37
37
  return "allow";
38
- const provider = normalizeMatchValue(params.provider) ??
38
+ const channel = normalizeMatchValue(params.provider) ??
39
39
  normalizeMatchValue(params.entry?.provider) ??
40
40
  normalizeMatchValue(params.entry?.lastProvider) ??
41
- deriveProviderFromKey(params.sessionKey);
41
+ deriveChannelFromKey(params.sessionKey);
42
42
  const chatType = normalizeMatchValue(params.chatType ?? params.entry?.chatType) ??
43
43
  normalizeMatchValue(deriveChatTypeFromKey(params.sessionKey));
44
44
  const sessionKey = params.sessionKey ?? "";
@@ -48,10 +48,10 @@ export function resolveSendPolicy(params) {
48
48
  continue;
49
49
  const action = normalizeSendPolicy(rule.action) ?? "allow";
50
50
  const match = rule.match ?? {};
51
- const matchProvider = normalizeMatchValue(match.provider);
51
+ const matchChannel = normalizeMatchValue(match.channel);
52
52
  const matchChatType = normalizeMatchValue(match.chatType);
53
53
  const matchPrefix = normalizeMatchValue(match.keyPrefix);
54
- if (matchProvider && matchProvider !== provider)
54
+ if (matchChannel && matchChannel !== channel)
55
55
  continue;
56
56
  if (matchChatType && matchChatType !== chatType)
57
57
  continue;
@@ -27,6 +27,9 @@ function normalizeSlackSlug(raw) {
27
27
  const cleaned = dashed.replace(/[^a-z0-9#@._+-]+/g, "-");
28
28
  return cleaned.replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, "");
29
29
  }
30
+ function escapeRegExp(value) {
31
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
32
+ }
30
33
  function normalizeSlackSlashCommandName(raw) {
31
34
  const trimmed = raw?.trim().toLowerCase() ?? "";
32
35
  if (!trimmed)
@@ -34,6 +37,24 @@ function normalizeSlackSlashCommandName(raw) {
34
37
  const stripped = trimmed.startsWith("/") ? trimmed.slice(1) : trimmed;
35
38
  return normalizeSlackSlug(stripped);
36
39
  }
40
+ export function buildSlackSlashCommandMatcher(rawName) {
41
+ const normalized = normalizeSlackSlashCommandName(rawName);
42
+ const name = normalized || "nexus";
43
+ return new RegExp(`^/?${escapeRegExp(name)}$`, "i");
44
+ }
45
+ export function resolveSlackThreadTs(params) {
46
+ if (params.incomingThreadTs)
47
+ return params.incomingThreadTs;
48
+ if (params.replyToMode === "off")
49
+ return undefined;
50
+ if (!params.messageTs)
51
+ return undefined;
52
+ if (params.replyToMode === "all")
53
+ return params.messageTs;
54
+ if (!params.hasReplied)
55
+ return params.messageTs;
56
+ return undefined;
57
+ }
37
58
  function normalizeAllowList(list) {
38
59
  return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean);
39
60
  }
@@ -62,7 +83,7 @@ function allowListMatches(params) {
62
83
  function resolveSlackSlashCommandConfig(raw) {
63
84
  const rawName = raw?.name?.trim() || "nexus";
64
85
  const normalizedName = normalizeSlackSlashCommandName(rawName);
65
- const name = normalizedName || "nexus";
86
+ const _name = normalizedName || "nexus";
66
87
  return {
67
88
  enabled: raw?.enabled === true,
68
89
  name: raw?.name?.trim() || "clawd",
@@ -5,7 +5,8 @@ export function resolveTelegramReactionLevel(params) {
5
5
  const channelConfig = "channels" in params.cfg
6
6
  ? params.cfg.channels?.telegram
7
7
  : undefined;
8
- const telegramCfg = channelConfig ?? params.cfg.telegram;
8
+ const telegramCfg = channelConfig ??
9
+ params.cfg.telegram;
9
10
  const level = (telegramCfg?.reactionLevel ?? "ack");
10
11
  switch (level) {
11
12
  case "off":
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Utility functions for provider-specific logic and capabilities.
3
+ */
4
+ /**
5
+ * Returns true if the provider requires reasoning to be wrapped in tags
6
+ * (e.g. <think> and <final>) in the text stream, rather than using native
7
+ * API fields for reasoning/thinking.
8
+ */
9
+ export function isReasoningTagProvider(provider) {
10
+ if (!provider)
11
+ return false;
12
+ const normalized = provider.trim().toLowerCase();
13
+ // Check for exact matches or known prefixes/substrings for reasoning providers
14
+ if (normalized === "ollama" ||
15
+ normalized === "google-gemini-cli" ||
16
+ normalized === "google-generative-ai") {
17
+ return true;
18
+ }
19
+ // Handle google-antigravity and its model variations (e.g. google-antigravity/gemini-3)
20
+ if (normalized.includes("google-antigravity")) {
21
+ return true;
22
+ }
23
+ // Handle Minimax (M2.1 is chatty/reasoning-like)
24
+ if (normalized.includes("minimax")) {
25
+ return true;
26
+ }
27
+ return false;
28
+ }
package/dist/utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
+ import { resolveStateDir } from "./config/paths.js";
4
5
  import { logVerbose, shouldLogVerbose } from "./globals.js";
5
6
  export async function ensureDir(dir) {
6
7
  await fs.promises.mkdir(dir, { recursive: true });
@@ -147,7 +148,7 @@ export function resolveNexusRoot(env = process.env, homedir = os.homedir) {
147
148
  return resolveUserPath(override);
148
149
  return path.join(homedir(), "nexus");
149
150
  }
150
- // Nexus root directory containing home/, skills/, state/
151
+ // Nexus root directory containing home/ and state/
151
152
  export const NEXUS_ROOT = resolveNexusRoot();
152
- // Managed skills directory (for NexusHub installs, etc.)
153
- export const MANAGED_SKILLS_DIR = path.join(NEXUS_ROOT, "skills");
153
+ // Managed skills directory lives under state/
154
+ export const MANAGED_SKILLS_DIR = path.join(resolveStateDir(), "skills");
@@ -10,12 +10,12 @@ import { applyAuthChoice } from "../commands/auth-choice.js";
10
10
  import { buildAuthChoiceOptions } from "../commands/auth-choice-options.js";
11
11
  import { healthCommand } from "../commands/health.js";
12
12
  import { applyAuthProfileConfig, applyMinimaxConfig, setAnthropicApiKey, writeOAuthCredentials, } from "../commands/onboard-auth.js";
13
- import { applyWizardMetadata, DEFAULT_WORKSPACE, detectBrowserOpenSupport, ensureWorkspaceAndSessions, formatControlUiSshHint, handleReset, openUrl, printWizardHeader, probeGatewayReachable, randomToken, resolveControlUiLinks, summarizeExistingConfig, } from "../commands/onboard-helpers.js";
13
+ import { maybeSetupIdentityFromEve } from "../commands/onboard-eve-identity.js";
14
14
  import { setupGitHubSync } from "../commands/onboard-github.js";
15
+ import { applyWizardMetadata, DEFAULT_WORKSPACE, detectBrowserOpenSupport, ensureWorkspaceAndSessions, formatControlUiSshHint, handleReset, openUrl, printWizardHeader, probeGatewayReachable, randomToken, resolveControlUiLinks, summarizeExistingConfig, } from "../commands/onboard-helpers.js";
15
16
  import { setupProviders } from "../commands/onboard-providers.js";
16
17
  import { promptRemoteGatewayConfig } from "../commands/onboard-remote.js";
17
18
  import { setupSkills } from "../commands/onboard-skills.js";
18
- import { maybeSetupIdentityFromEve } from "../commands/onboard-eve-identity.js";
19
19
  import { applyOpenAICodexModelDefault, OPENAI_CODEX_DEFAULT_MODEL, } from "../commands/openai-codex-model-default.js";
20
20
  import { ensureSystemdUserLingerInteractive } from "../commands/systemd-linger.js";
21
21
  import { CONFIG_PATH_NEXUS, readConfigFileSnapshot, resolveGatewayPort, writeConfigFile, } from "../config/config.js";
@@ -24,6 +24,7 @@ import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
24
24
  import { resolveGatewayService } from "../daemon/service.js";
25
25
  import { ensureControlUiAssetsBuilt } from "../infra/control-ui-assets.js";
26
26
  import { defaultRuntime } from "../runtime.js";
27
+ import { runTui } from "../tui/tui.js";
27
28
  import { resolveUserPath, sleep } from "../utils.js";
28
29
  async function warnIfModelConfigLooksOff(config, prompter) {
29
30
  const ref = resolveConfiguredModelRef({
@@ -61,6 +62,17 @@ export async function runOnboardingWizard(opts, runtime = defaultRuntime, prompt
61
62
  await prompter.intro("Nexus onboarding");
62
63
  const snapshot = await readConfigFileSnapshot();
63
64
  let baseConfig = snapshot.valid ? snapshot.config : {};
65
+ if (snapshot.exists && !snapshot.valid) {
66
+ await prompter.note(summarizeExistingConfig(baseConfig), "Invalid config");
67
+ if (snapshot.issues.length > 0) {
68
+ await prompter.note(snapshot.issues
69
+ .map((iss) => `- ${iss.path}: ${iss.message}`)
70
+ .join("\n"), "Config issues");
71
+ }
72
+ await prompter.outro("Fix config issues and rerun onboarding.");
73
+ runtime.exit(1);
74
+ return;
75
+ }
64
76
  if (snapshot.exists) {
65
77
  const title = snapshot.valid
66
78
  ? "Existing config detected"
@@ -104,15 +116,16 @@ export async function runOnboardingWizard(opts, runtime = defaultRuntime, prompt
104
116
  }
105
117
  const localPort = resolveGatewayPort(baseConfig);
106
118
  const localUrl = `ws://127.0.0.1:${localPort}`;
107
- const localToken = process.env.NEXUS_GATEWAY_TOKEN ?? process.env.NEXUS_GATEWAY_TOKEN;
119
+ const _localToken = process.env.NEXUS_GATEWAY_TOKEN ?? process.env.NEXUS_GATEWAY_TOKEN;
108
120
  const configPassword = baseConfig.gateway?.auth?.password;
109
121
  const envPassword = process.env.NEXUS_GATEWAY_PASSWORD ?? process.env.NEXUS_GATEWAY_PASSWORD;
110
- const primaryPassword = configPassword ?? envPassword;
111
- let localProbe = await probeGatewayReachable({
122
+ const _primaryPassword = configPassword ?? envPassword;
123
+ const localProbe = await probeGatewayReachable({
112
124
  url: localUrl,
113
125
  token: process.env.NEXUS_GATEWAY_TOKEN ?? process.env.CLAWDBOT_GATEWAY_TOKEN,
114
126
  password: baseConfig.gateway?.auth?.password ??
115
- process.env.NEXUS_GATEWAY_PASSWORD ?? process.env.CLAWDBOT_GATEWAY_PASSWORD,
127
+ process.env.NEXUS_GATEWAY_PASSWORD ??
128
+ process.env.CLAWDBOT_GATEWAY_PASSWORD,
116
129
  });
117
130
  const remoteUrl = baseConfig.gateway?.remote?.url?.trim() ?? "";
118
131
  const remoteProbe = remoteUrl
@@ -534,7 +547,9 @@ export async function runOnboardingWizard(opts, runtime = defaultRuntime, prompt
534
547
  const environment = {
535
548
  PATH: process.env.PATH,
536
549
  NEXUS_GATEWAY_TOKEN: gatewayToken,
537
- NEXUS_LAUNCHD_LABEL: process.platform === "darwin" ? GATEWAY_LAUNCH_AGENT_LABEL : undefined,
550
+ NEXUS_LAUNCHD_LABEL: process.platform === "darwin"
551
+ ? GATEWAY_LAUNCH_AGENT_LABEL
552
+ : undefined,
538
553
  };
539
554
  await service.install({
540
555
  env: process.env,
@@ -616,5 +631,12 @@ export async function runOnboardingWizard(opts, runtime = defaultRuntime, prompt
616
631
  await maybeSetupIdentityFromEve({ workspaceDir, prompter, runtime });
617
632
  // Set up GitHub sync for workspace portability
618
633
  await setupGitHubSync(workspaceDir, prompter, runtime);
634
+ const hatch = await prompter.confirm({
635
+ message: "Do you want to hatch your bot now?",
636
+ initialValue: false,
637
+ });
638
+ if (hatch) {
639
+ await runTui({ deliver: false, message: "Wake up, my friend!" });
640
+ }
619
641
  await prompter.outro("Onboarding complete.");
620
642
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intent-systems/nexus",
3
- "version": "2026.1.5-3",
3
+ "version": "2026.1.5-5",
4
4
  "description": "WhatsApp gateway CLI (Baileys web) with Pi RPC agent",
5
5
  "homepage": "https://github.com/Napageneral/nexus",
6
6
  "repository": {
@@ -13,36 +13,11 @@
13
13
  "nexus": "dist/entry.js"
14
14
  },
15
15
  "files": [
16
- "dist/agents/**",
17
- "dist/auto-reply/**",
18
- "dist/browser/**",
19
- "dist/canvas-host/**",
20
- "dist/cli/**",
21
- "dist/commands/**",
22
- "dist/config/**",
23
- "dist/control-ui/**",
24
- "dist/cron/**",
25
- "dist/daemon/**",
26
- "dist/discord/**",
27
- "dist/gateway/**",
28
- "dist/hooks/**",
29
- "dist/imessage/**",
30
- "dist/infra/**",
31
- "dist/macos/**",
32
- "dist/media/**",
33
- "dist/process/**",
34
- "dist/sessions/**",
35
- "dist/providers/**",
36
- "dist/signal/**",
37
- "dist/slack/**",
38
- "dist/telegram/**",
39
- "dist/tui/**",
40
- "dist/web/**",
41
- "dist/wizard/**",
42
- "dist/*.js",
43
- "dist/*.json",
16
+ "dist/**",
44
17
  "docs/**",
45
18
  "skills/**",
19
+ "patches/**",
20
+ "scripts/postinstall.js",
46
21
  "README.md",
47
22
  "README-header.png",
48
23
  "CHANGELOG.md",